mirror of
https://gitee.com/xiaonuobase/snowy.git
synced 2026-03-22 02:37:16 +08:00
【更新】机构大数据优化(待完善)
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
<a-tree
|
||||
v-if="treeData"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:tree-data="treeData"
|
||||
:field-names="treeFieldNames"
|
||||
:load-data="onLoadData"
|
||||
@@ -57,11 +58,7 @@
|
||||
placeholder="请选择上级组织"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
selectable="false"
|
||||
tree-line
|
||||
/>
|
||||
@@ -243,6 +240,7 @@
|
||||
const slots = useSlots()
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 获取机构树数据
|
||||
const treeData = ref()
|
||||
// 默认展开二级树的节点id
|
||||
|
||||
@@ -27,11 +27,7 @@ XnPageSelect 分页下拉选择器
|
||||
tree-default-expand-all
|
||||
:tree-data="treeData"
|
||||
:tree-default-expanded-keys="treeDefaultExpandedKeys"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
@change="selePositionData(formData.orgId, 0)"
|
||||
></a-tree-select>
|
||||
</a-form-item>
|
||||
@@ -56,6 +52,7 @@ import bizUserApi from '@/api/biz/bizUserApi'
|
||||
// 表单数据
|
||||
const formData = ref({})
|
||||
const xnPositionPageSelectRef = ref()
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
|
||||
// 机构选择后查询对应的职位
|
||||
const selePositionData = (orgId, type) => {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
v-if="props.showSearch"
|
||||
v-model:value="modelValue"
|
||||
:options="options"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
:field-names="selectFieldNames"
|
||||
class="xn-wd"
|
||||
:placeholder="props.placeholder"
|
||||
:allow-clear="props.allowClear"
|
||||
@@ -20,7 +20,7 @@
|
||||
v-else
|
||||
v-model:value="modelValue"
|
||||
:options="options"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
:field-names="selectFieldNames"
|
||||
class="xn-wd"
|
||||
:placeholder="props.placeholder"
|
||||
:allow-clear="props.allowClear"
|
||||
@@ -40,6 +40,7 @@
|
||||
const initParams = ref({})
|
||||
const options = ref([])
|
||||
const spinning = ref(false)
|
||||
const selectFieldNames = { label: 'name', value: 'id' }
|
||||
const emit = defineEmits({ change: null, 'update:value': null, search: null })
|
||||
const props = defineProps({
|
||||
value: {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
<a-tree
|
||||
v-if="treeData"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:tree-data="treeData"
|
||||
:field-names="treeFieldNames"
|
||||
:load-data="onLoadData"
|
||||
@@ -57,11 +58,7 @@
|
||||
placeholder="请选择组织"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
selectable="false"
|
||||
tree-line
|
||||
/>
|
||||
@@ -239,6 +236,7 @@
|
||||
const slots = useSlots()
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 获取职位树数据
|
||||
const treeData = ref()
|
||||
// 默认展开二级树的节点id
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
<a-tree
|
||||
v-if="treeData"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:tree-data="treeData"
|
||||
:field-names="treeFieldNames"
|
||||
:load-data="onLoadData"
|
||||
@@ -57,11 +58,7 @@
|
||||
placeholder="请选择组织"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
selectable="false"
|
||||
tree-line
|
||||
@change="onCategoryOrOrgIdSelect"
|
||||
@@ -246,6 +243,7 @@
|
||||
const slots = useSlots()
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 获取机构树数据
|
||||
const treeData = ref()
|
||||
// 默认展开二级树的节点id
|
||||
@@ -323,7 +321,7 @@
|
||||
}
|
||||
}
|
||||
const openModal = () => {
|
||||
if (typeof props.orgTreeApi !== 'function' || typeof props.rolePageApi !== 'function') {
|
||||
if ((typeof props.orgTreeApi !== 'function' && typeof props.orgTreeLazyApi !== 'function') || typeof props.rolePageApi !== 'function') {
|
||||
message.warning('未配置角色选择器API')
|
||||
return
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<a-tree
|
||||
v-if="treeData"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:tree-data="treeData"
|
||||
:field-names="treeFieldNames"
|
||||
:load-data="onLoadData"
|
||||
@@ -64,11 +65,7 @@
|
||||
placeholder="请选择组织"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
selectable="false"
|
||||
tree-line
|
||||
/>
|
||||
@@ -253,6 +250,7 @@
|
||||
const selectedTableListLoading = ref(false)
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 获取机构树数据
|
||||
const treeData = ref()
|
||||
// 默认展开二级树的节点id
|
||||
|
||||
@@ -11,11 +11,7 @@
|
||||
placeholder="请选择上级字典"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
selectable="false"
|
||||
treeLine
|
||||
/>
|
||||
@@ -52,7 +48,7 @@
|
||||
const treeData = ref([])
|
||||
// 默认展开的节点(顶级)
|
||||
const defaultExpandedKeys = ref([0])
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 打开抽屉
|
||||
const onOpen = (record, parentId) => {
|
||||
visible.value = true
|
||||
|
||||
@@ -22,11 +22,7 @@
|
||||
placeholder="请选择上级字典"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
selectable="false"
|
||||
tree-line
|
||||
/>
|
||||
@@ -119,6 +115,7 @@
|
||||
const treeData = ref([])
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'dictLabel', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
|
||||
|
||||
// 表格查询 返回 Promise 对象
|
||||
|
||||
@@ -10,11 +10,7 @@
|
||||
allow-clear
|
||||
tree-default-expand-all
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
selectable="false"
|
||||
tree-line
|
||||
/>
|
||||
@@ -48,6 +44,7 @@
|
||||
// 定义机构元素
|
||||
const treeData = ref([])
|
||||
const submitLoading = ref(false)
|
||||
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 选中的ID列表
|
||||
const ids = ref([])
|
||||
|
||||
|
||||
@@ -15,11 +15,7 @@
|
||||
placeholder="请选择上级机构"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
/>
|
||||
@@ -71,7 +67,7 @@
|
||||
// 定义机构元素
|
||||
const treeData = ref([])
|
||||
const submitLoading = ref(false)
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
|
||||
// 在树中递归查找节点
|
||||
const findNodeInTree = (nodes, id) => {
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
/>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<xn-tree-skeleton v-if="treeLoading && treeData.length === 0" />
|
||||
<a-spin v-else-if="treeData.length > 0" :spinning="treeLoading">
|
||||
<a-tree
|
||||
v-else-if="treeData.length > 0"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:tree-data="treeData"
|
||||
@@ -22,6 +22,7 @@
|
||||
:height="treeHeight"
|
||||
@select="treeSelect"
|
||||
/>
|
||||
</a-spin>
|
||||
<a-empty v-else :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,11 +39,7 @@
|
||||
placeholder="请选择上级机构"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
/>
|
||||
@@ -184,6 +181,7 @@
|
||||
const treeData = ref([])
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 树容器高度自适应
|
||||
const treeContainerRef = ref(null)
|
||||
const treeHeight = ref(0)
|
||||
|
||||
@@ -15,11 +15,7 @@
|
||||
placeholder="请选择组织"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
></a-tree-select>
|
||||
@@ -63,7 +59,7 @@
|
||||
// 定义机构元素
|
||||
const treeData = ref([])
|
||||
const submitLoading = ref(false)
|
||||
|
||||
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 在树中递归查找节点
|
||||
const findNodeInTree = (nodes, id) => {
|
||||
if (!nodes) return false
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
/>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<xn-tree-skeleton v-if="treeLoading && treeData.length === 0" />
|
||||
<a-spin v-else-if="treeData.length > 0" :spinning="treeLoading">
|
||||
<a-tree
|
||||
v-else-if="treeData.length > 0"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:tree-data="treeData"
|
||||
@@ -22,6 +22,7 @@
|
||||
:height="treeHeight"
|
||||
@select="treeSelect"
|
||||
/>
|
||||
</a-spin>
|
||||
<a-empty v-else :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,11 +39,7 @@
|
||||
placeholder="请选择机构"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
/>
|
||||
@@ -175,6 +172,7 @@
|
||||
const treeData = ref([])
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 树容器高度自适应
|
||||
const treeContainerRef = ref(null)
|
||||
const treeHeight = ref(0)
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<a-row :gutter="16">
|
||||
<a-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
|
||||
<a-form-item label="选择机构:" name="orgId">
|
||||
<a-spin :spinning="treeLoading">
|
||||
<a-tree-select
|
||||
v-model:value="formData.orgId"
|
||||
class="xn-wd"
|
||||
@@ -53,15 +54,17 @@
|
||||
allow-clear
|
||||
tree-line
|
||||
:tree-data="treeData"
|
||||
:tree-default-expanded-keys="treeDefaultExpandedKeys"
|
||||
v-model:treeExpandedKeys="treeDefaultExpandedKeys"
|
||||
:field-names="treeFieldNames"
|
||||
:load-data="onLoadData"
|
||||
:load-data="isEditMode ? undefined : onLoadData"
|
||||
@change="selePositionData(formData.orgId, 0)"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
|
||||
<a-form-item label="选择岗位:" name="positionId">
|
||||
<a-spin :spinning="treeLoading">
|
||||
<xn-page-select
|
||||
ref="xnPositionPageSelectRef"
|
||||
v-model:value="formData.positionId"
|
||||
@@ -70,10 +73,12 @@
|
||||
:page-function="selectApiFunction.positionSelector"
|
||||
:echo-function="selectApiFunction.echoPosition"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
|
||||
<a-form-item label="选择主管:" name="directorId">
|
||||
<a-spin :spinning="treeLoading">
|
||||
<xn-page-select
|
||||
ref="xnUserPageSelectRef"
|
||||
v-model:value="formData.directorId"
|
||||
@@ -82,6 +87,7 @@
|
||||
:page-function="selectApiFunction.userSelector"
|
||||
:echo-function="selectApiFunction.echoUser"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
@@ -122,6 +128,7 @@
|
||||
:name="['positionJson', index, 'orgId']"
|
||||
:rules="{ required: true, message: '请选择机构' }"
|
||||
>
|
||||
<a-spin :spinning="treeLoading">
|
||||
<a-tree-select
|
||||
v-model:value="positionInfo.orgId"
|
||||
class="xn-wd"
|
||||
@@ -130,11 +137,12 @@
|
||||
allow-clear
|
||||
tree-line
|
||||
:tree-data="treeData"
|
||||
:tree-default-expanded-keys="treeDefaultExpandedKeys"
|
||||
v-model:treeExpandedKeys="childTreeExpandedKeys[index]"
|
||||
:field-names="treeFieldNames"
|
||||
:load-data="onLoadData"
|
||||
:load-data="isEditMode ? undefined : onLoadData"
|
||||
@change="childOrgSelect(positionInfo, 0, index)"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7">
|
||||
@@ -142,6 +150,7 @@
|
||||
:name="['positionJson', index, 'positionId']"
|
||||
:rules="{ required: true, message: '请选择岗位' }"
|
||||
>
|
||||
<a-spin :spinning="treeLoading">
|
||||
<xn-page-select
|
||||
ref="xnChildPositionPageSelectRef"
|
||||
v-model:value="positionInfo.positionId"
|
||||
@@ -150,10 +159,12 @@
|
||||
:page-function="selectApiFunction.childPositionSelector"
|
||||
:echo-function="selectApiFunction.echoPosition"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7">
|
||||
<a-form-item :name="['positionJson', index, 'directorId']">
|
||||
<a-spin :spinning="treeLoading">
|
||||
<xn-page-select
|
||||
ref="xnChildUserPageSelectRef"
|
||||
v-model:value="positionInfo.directorId"
|
||||
@@ -162,6 +173,7 @@
|
||||
:page-function="selectApiFunction.childUserSelector"
|
||||
:echo-function="selectApiFunction.echoUser"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="3" :lg="3" :xl="3">
|
||||
@@ -308,8 +320,10 @@
|
||||
const activeTabsKey = ref('1')
|
||||
const emit = defineEmits({ successful: null })
|
||||
const formLoading = ref(false)
|
||||
const treeLoading = ref(false)
|
||||
const treeData = ref([])
|
||||
const treeDefaultExpandedKeys = ref([])
|
||||
const childTreeExpandedKeys = ref([])
|
||||
// 分页select组件dom定义
|
||||
const xnPositionPageSelectRef = ref()
|
||||
const xnUserPageSelectRef = ref()
|
||||
@@ -319,33 +333,12 @@
|
||||
const formData = ref({})
|
||||
const treeFieldNames = { children: 'children', label: 'name', key: 'id', value: 'id' }
|
||||
|
||||
// 在树中递归查找节点
|
||||
const findNodeInTree = (nodes, id) => {
|
||||
if (!nodes) return false
|
||||
for (const node of nodes) {
|
||||
if (node.id === id) return true
|
||||
if (node.children && findNodeInTree(node.children, id)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
// 确保选中的机构节点在树中可回显名称
|
||||
const ensureOrgsInTree = (orgIds) => {
|
||||
const missingIds = orgIds.filter((id) => id && !findNodeInTree(treeData.value, id))
|
||||
if (missingIds.length === 0) return
|
||||
userCenterApi.userCenterGetOrgListByIdList({ idList: missingIds }).then((data) => {
|
||||
if (data && data.length > 0) {
|
||||
data.forEach((org) => {
|
||||
treeData.value.push({ ...org, isLeaf: true })
|
||||
})
|
||||
treeData.value = [...treeData.value]
|
||||
}
|
||||
})
|
||||
}
|
||||
// 树加载Promise,用于协调回显时序
|
||||
let treeLoadPromise = null
|
||||
// 是否为编辑模式(编辑时加载全量树,新增时懒加载)
|
||||
const isEditMode = ref(false)
|
||||
// 打开抽屉
|
||||
const onOpen = (record, orgId) => {
|
||||
visible.value = true
|
||||
isEditMode.value = !!record
|
||||
formData.value = {
|
||||
gender: '男',
|
||||
positionJson: []
|
||||
@@ -357,12 +350,28 @@
|
||||
selePositionData(orgId)
|
||||
})
|
||||
}
|
||||
if (record) {
|
||||
convertFormData(record)
|
||||
}
|
||||
nextTick(() => {
|
||||
// 机构选择器数据
|
||||
treeLoadPromise = bizUserApi.userOrgTreeLazySelector().then((res) => {
|
||||
if (isEditMode.value) {
|
||||
// 编辑模式:加载全量树 + 详情,等都完成后展开到选中节点
|
||||
treeLoading.value = true
|
||||
const treePromise = bizUserApi.userOrgTreeLazySelector({ searchKey: '' }).then((res) => {
|
||||
if (res !== null) {
|
||||
treeData.value = res
|
||||
// 只有一个根节点时才自动展开
|
||||
if (treeData.value.length === 1) {
|
||||
treeDefaultExpandedKeys.value.push(treeData.value[0].id)
|
||||
}
|
||||
}
|
||||
})
|
||||
const detailPromise = convertFormData(record)
|
||||
Promise.all([treePromise, detailPromise]).then(() => {
|
||||
expandToSelectedOrgs()
|
||||
}).finally(() => {
|
||||
treeLoading.value = false
|
||||
})
|
||||
} else {
|
||||
// 新增模式:懒加载树
|
||||
bizUserApi.userOrgTreeLazySelector().then((res) => {
|
||||
if (res !== null) {
|
||||
treeData.value = res.map((item) => {
|
||||
return {
|
||||
@@ -376,6 +385,7 @@
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 懒加载子节点
|
||||
@@ -405,15 +415,51 @@
|
||||
const onClose = () => {
|
||||
treeData.value = []
|
||||
treeDefaultExpandedKeys.value = []
|
||||
childTreeExpandedKeys.value = []
|
||||
visible.value = 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 = () => {
|
||||
// 主选择机构:只展开主orgId的祖先
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 任职信息:每行独立展开
|
||||
if (formData.value.positionJson) {
|
||||
formData.value.positionJson.forEach((item, index) => {
|
||||
if (item.orgId) {
|
||||
const ancestors = collectAncestorKeys(treeData.value, item.orgId)
|
||||
childTreeExpandedKeys.value[index] = ancestors ? [...ancestors] : []
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 回显数据
|
||||
const convertFormData = (record) => {
|
||||
const param = {
|
||||
id: record.id
|
||||
}
|
||||
// 查询详情
|
||||
const detailPromise = bizUserApi.userDetail(param).then((data) => {
|
||||
return bizUserApi.userDetail(param).then((data) => {
|
||||
if (data.positionJson) {
|
||||
// 替换表单中的格式与后端查到的
|
||||
data.positionJson = JSON.parse(data.positionJson)
|
||||
@@ -428,24 +474,6 @@
|
||||
})
|
||||
}
|
||||
selePositionData(formData.value.orgId)
|
||||
return data
|
||||
})
|
||||
// 等待树和详情都加载完成后,确保机构节点可回显
|
||||
nextTick(() => {
|
||||
if (treeLoadPromise) {
|
||||
Promise.all([treeLoadPromise, detailPromise]).then(([_, detail]) => {
|
||||
const orgIds = [detail.orgId]
|
||||
if (detail.positionJson) {
|
||||
const positions = typeof detail.positionJson === 'string'
|
||||
? JSON.parse(detail.positionJson)
|
||||
: detail.positionJson
|
||||
positions.forEach((item) => {
|
||||
if (item.orgId) orgIds.push(item.orgId)
|
||||
})
|
||||
}
|
||||
ensureOrgsInTree(orgIds)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 默认要校验的
|
||||
@@ -518,10 +546,12 @@
|
||||
positionId: undefined,
|
||||
directorId: undefined
|
||||
})
|
||||
childTreeExpandedKeys.value.push([])
|
||||
}
|
||||
// 删减行
|
||||
const delDomains = (index) => {
|
||||
formData.value.positionJson.splice(index, 1)
|
||||
childTreeExpandedKeys.value.splice(index, 1)
|
||||
}
|
||||
// 子表行内选择机构
|
||||
const childOrgSelect = async (data, type, index) => {
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
/>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<xn-tree-skeleton v-if="treeLoading && treeData.length === 0" />
|
||||
<a-spin v-else-if="treeData.length > 0" :spinning="treeLoading">
|
||||
<a-tree
|
||||
v-else-if="treeData.length > 0"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:tree-data="treeData"
|
||||
@@ -22,6 +22,7 @@
|
||||
:height="treeHeight"
|
||||
@select="treeSelect"
|
||||
/>
|
||||
</a-spin>
|
||||
<a-empty v-else :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,11 +39,7 @@
|
||||
placeholder="请选择所属机构"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
/>
|
||||
@@ -173,7 +170,6 @@
|
||||
<Form ref="formRef" @successful="tableRef.refresh()" />
|
||||
<xn-role-selector
|
||||
ref="RoleSelectorPlusRef"
|
||||
:org-tree-api="selectorApiFunction.orgTreeApi"
|
||||
:org-tree-lazy-api="selectorApiFunction.orgTreeLazyApi"
|
||||
:role-page-api="selectorApiFunction.rolePageApi"
|
||||
:add-show="false"
|
||||
@@ -247,6 +243,7 @@
|
||||
const treeData = ref([])
|
||||
const selectedRowKeys = ref([])
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
const formRef = ref(null)
|
||||
const RoleSelectorPlusRef = ref()
|
||||
const selectedRecord = ref({})
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
placeholder="请选择上级字典"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
selectable="false"
|
||||
treeLine
|
||||
/>
|
||||
@@ -69,6 +65,7 @@
|
||||
const treeData = ref([])
|
||||
// 默认展开的节点(顶级)
|
||||
const defaultExpandedKeys = ref([0])
|
||||
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 定义字典颜色
|
||||
const dictColorList = [
|
||||
'default',
|
||||
|
||||
@@ -66,11 +66,7 @@
|
||||
allow-clear
|
||||
tree-default-expand-all
|
||||
:tree-data="menuTreeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'title',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
selectable="false"
|
||||
tree-line
|
||||
/>
|
||||
@@ -192,6 +188,7 @@
|
||||
const tableList = ref([])
|
||||
const tableColumns = ref([])
|
||||
const menuTreeData = ref([])
|
||||
const treeFieldNames = { children: 'children', label: 'title', value: 'id' }
|
||||
const submitLoading = ref(false)
|
||||
const moduleOptions = ref()
|
||||
const generateTypeOptions = ref([
|
||||
|
||||
@@ -19,11 +19,7 @@
|
||||
allow-clear
|
||||
tree-default-expand-all
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'title',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
selectable="false"
|
||||
tree-line
|
||||
@change="parentChange(formData.parentId)"
|
||||
@@ -111,6 +107,7 @@
|
||||
// 默认展开的节点(顶级)
|
||||
const defaultExpandedKeys = ref([0])
|
||||
const treeData = ref([])
|
||||
const treeFieldNames = { children: 'children', label: 'title', value: 'id' }
|
||||
const formData = ref({})
|
||||
// 类别
|
||||
const moduleId = ref('')
|
||||
|
||||
@@ -10,11 +10,7 @@
|
||||
allow-clear
|
||||
tree-default-expand-all
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
selectable="false"
|
||||
tree-line
|
||||
/>
|
||||
@@ -48,6 +44,7 @@
|
||||
// 定义机构元素
|
||||
const treeData = ref([])
|
||||
const submitLoading = ref(false)
|
||||
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 选中的ID列表
|
||||
const ids = ref([])
|
||||
|
||||
|
||||
@@ -15,11 +15,7 @@
|
||||
placeholder="请选择上级组织"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
/>
|
||||
@@ -71,7 +67,7 @@
|
||||
// 定义机构元素
|
||||
const treeData = ref([])
|
||||
const submitLoading = ref(false)
|
||||
|
||||
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 在树中递归查找节点
|
||||
const findNodeInTree = (nodes, id) => {
|
||||
if (!nodes) return false
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
/>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<xn-tree-skeleton v-if="treeLoading && treeData.length === 0" />
|
||||
<a-spin v-else-if="treeData.length > 0" :spinning="treeLoading">
|
||||
<a-tree
|
||||
v-else-if="treeData.length > 0"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:tree-data="treeData"
|
||||
@@ -22,6 +22,7 @@
|
||||
:height="treeHeight"
|
||||
@select="treeSelect"
|
||||
/>
|
||||
</a-spin>
|
||||
<a-empty v-else :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,11 +39,7 @@
|
||||
placeholder="请选择上级组织"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
/>
|
||||
@@ -181,6 +178,7 @@
|
||||
const treeData = ref([])
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 树容器高度自适应
|
||||
const treeContainerRef = ref(null)
|
||||
const treeHeight = ref(0)
|
||||
|
||||
@@ -15,11 +15,7 @@
|
||||
placeholder="请选择组织"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
></a-tree-select>
|
||||
@@ -62,7 +58,7 @@
|
||||
// 定义机构元素
|
||||
const treeData = ref([])
|
||||
const submitLoading = ref(false)
|
||||
|
||||
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 在树中递归查找节点
|
||||
const findNodeInTree = (nodes, id) => {
|
||||
if (!nodes) return false
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
/>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<xn-tree-skeleton v-if="treeLoading && treeData.length === 0" />
|
||||
<a-spin v-else-if="treeData.length > 0" :spinning="treeLoading">
|
||||
<a-tree
|
||||
v-else-if="treeData.length > 0"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:tree-data="treeData"
|
||||
@@ -22,6 +22,7 @@
|
||||
:height="treeHeight"
|
||||
@select="treeSelect"
|
||||
/>
|
||||
</a-spin>
|
||||
<a-empty v-else :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,11 +39,7 @@
|
||||
placeholder="请选择组织"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
/>
|
||||
@@ -172,6 +169,7 @@
|
||||
const treeData = ref([])
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 树容器高度自适应
|
||||
const treeContainerRef = ref(null)
|
||||
const treeHeight = ref(0)
|
||||
|
||||
@@ -30,11 +30,7 @@
|
||||
allow-clear
|
||||
tree-default-expand-all
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeFieldNames"
|
||||
selectable="false"
|
||||
tree-line
|
||||
/>
|
||||
@@ -65,7 +61,7 @@
|
||||
// 定义机构元素
|
||||
const treeData = ref([])
|
||||
const submitLoading = ref(false)
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 打开抽屉
|
||||
const onOpen = (record, category, orgId) => {
|
||||
visible.value = true
|
||||
|
||||
@@ -38,11 +38,7 @@
|
||||
placeholder="请选择组织"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
@change="onCategoryOrOrgIdSelect"
|
||||
@@ -216,6 +212,7 @@
|
||||
const treeData = ref([])
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
// 记录数据
|
||||
const recordCacheData = ref({})
|
||||
// 树容器高度自适应
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<a-row :gutter="16">
|
||||
<a-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
|
||||
<a-form-item label="选择组织:" name="orgId">
|
||||
<a-spin :spinning="treeLoading">
|
||||
<a-tree-select
|
||||
v-model:value="formData.orgId"
|
||||
class="xn-wd"
|
||||
@@ -53,15 +54,17 @@
|
||||
allow-clear
|
||||
tree-line
|
||||
:tree-data="treeData"
|
||||
:tree-default-expanded-keys="treeDefaultExpandedKeys"
|
||||
v-model:treeExpandedKeys="treeDefaultExpandedKeys"
|
||||
:field-names="treeFieldNames"
|
||||
:load-data="onLoadData"
|
||||
:load-data="isEditMode ? undefined : onLoadData"
|
||||
@change="selePositionData(formData.orgId, 0)"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
|
||||
<a-form-item label="选择职位:" name="positionId">
|
||||
<a-spin :spinning="treeLoading">
|
||||
<xn-page-select
|
||||
ref="xnPositionPageSelectRef"
|
||||
v-model:value="formData.positionId"
|
||||
@@ -70,10 +73,12 @@
|
||||
:page-function="selectApiFunction.positionSelector"
|
||||
:echo-function="selectApiFunction.echoPosition"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
|
||||
<a-form-item label="选择主管:" name="directorId">
|
||||
<a-spin :spinning="treeLoading">
|
||||
<xn-page-select
|
||||
ref="xnUserPageSelectRef"
|
||||
v-model:value="formData.directorId"
|
||||
@@ -82,6 +87,7 @@
|
||||
:page-function="selectApiFunction.userSelector"
|
||||
:echo-function="selectApiFunction.echoUser"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
@@ -122,6 +128,7 @@
|
||||
:name="['positionJson', index, 'orgId']"
|
||||
:rules="{ required: true, message: '请选择组织' }"
|
||||
>
|
||||
<a-spin :spinning="treeLoading">
|
||||
<a-tree-select
|
||||
v-model:value="positionInfo.orgId"
|
||||
class="xn-wd"
|
||||
@@ -130,11 +137,12 @@
|
||||
allow-clear
|
||||
tree-line
|
||||
:tree-data="treeData"
|
||||
:tree-default-expanded-keys="treeDefaultExpandedKeys"
|
||||
v-model:treeExpandedKeys="childTreeExpandedKeys[index]"
|
||||
:field-names="treeFieldNames"
|
||||
:load-data="onLoadData"
|
||||
:load-data="isEditMode ? undefined : onLoadData"
|
||||
@change="childOrgSelect(positionInfo, 0, index)"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7">
|
||||
@@ -142,6 +150,7 @@
|
||||
:name="['positionJson', index, 'positionId']"
|
||||
:rules="{ required: true, message: '请选择职位' }"
|
||||
>
|
||||
<a-spin :spinning="treeLoading">
|
||||
<xn-page-select
|
||||
ref="xnChildPositionPageSelectRef"
|
||||
v-model:value="positionInfo.positionId"
|
||||
@@ -150,10 +159,12 @@
|
||||
:page-function="selectApiFunction.childPositionSelector"
|
||||
:echo-function="selectApiFunction.echoPosition"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7">
|
||||
<a-form-item :name="['positionJson', index, 'directorId']">
|
||||
<a-spin :spinning="treeLoading">
|
||||
<xn-page-select
|
||||
ref="xnChildUserPageSelectRef"
|
||||
v-model:value="positionInfo.directorId"
|
||||
@@ -162,6 +173,7 @@
|
||||
:page-function="selectApiFunction.childUserSelector"
|
||||
:echo-function="selectApiFunction.echoUser"
|
||||
/>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="3" :lg="3" :xl="3">
|
||||
@@ -308,8 +320,10 @@
|
||||
const activeTabsKey = ref('1')
|
||||
const emit = defineEmits({ successful: null })
|
||||
const formLoading = ref(false)
|
||||
const treeLoading = ref(false)
|
||||
const treeData = ref([])
|
||||
const treeDefaultExpandedKeys = ref([])
|
||||
const childTreeExpandedKeys = ref([])
|
||||
// 分页select组件dom定义
|
||||
const xnPositionPageSelectRef = ref()
|
||||
const xnUserPageSelectRef = ref()
|
||||
@@ -319,33 +333,12 @@
|
||||
const formData = ref({})
|
||||
const treeFieldNames = { children: 'children', label: 'name', key: 'id', value: 'id' }
|
||||
|
||||
// 在树中递归查找节点
|
||||
const findNodeInTree = (nodes, id) => {
|
||||
if (!nodes) return false
|
||||
for (const node of nodes) {
|
||||
if (node.id === id) return true
|
||||
if (node.children && findNodeInTree(node.children, id)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
// 确保选中的机构节点在树中可回显名称
|
||||
const ensureOrgsInTree = (orgIds) => {
|
||||
const missingIds = orgIds.filter((id) => id && !findNodeInTree(treeData.value, id))
|
||||
if (missingIds.length === 0) return
|
||||
userCenterApi.userCenterGetOrgListByIdList({ idList: missingIds }).then((data) => {
|
||||
if (data && data.length > 0) {
|
||||
data.forEach((org) => {
|
||||
treeData.value.push({ ...org, isLeaf: true })
|
||||
})
|
||||
treeData.value = [...treeData.value]
|
||||
}
|
||||
})
|
||||
}
|
||||
// 树加载Promise,用于协调回显时序
|
||||
let treeLoadPromise = null
|
||||
// 是否为编辑模式(编辑时加载全量树,新增时懒加载)
|
||||
const isEditMode = ref(false)
|
||||
// 打开抽屉
|
||||
const onOpen = (record, orgId) => {
|
||||
visible.value = true
|
||||
isEditMode.value = !!record
|
||||
formData.value = {
|
||||
gender: '男',
|
||||
positionJson: []
|
||||
@@ -357,12 +350,28 @@
|
||||
selePositionData(orgId)
|
||||
})
|
||||
}
|
||||
if (record) {
|
||||
convertFormData(record)
|
||||
}
|
||||
nextTick(() => {
|
||||
// 机构选择器数据
|
||||
treeLoadPromise = userApi.userOrgTreeLazySelector().then((res) => {
|
||||
if (isEditMode.value) {
|
||||
// 编辑模式:加载全量树 + 详情,等都完成后展开到选中节点
|
||||
treeLoading.value = true
|
||||
const treePromise = userApi.userOrgTreeLazySelector({ searchKey: '' }).then((res) => {
|
||||
if (res !== null) {
|
||||
treeData.value = res
|
||||
// 只有一个根节点时才自动展开
|
||||
if (treeData.value.length === 1) {
|
||||
treeDefaultExpandedKeys.value.push(treeData.value[0].id)
|
||||
}
|
||||
}
|
||||
})
|
||||
const detailPromise = convertFormData(record)
|
||||
Promise.all([treePromise, detailPromise]).then(() => {
|
||||
expandToSelectedOrgs()
|
||||
}).finally(() => {
|
||||
treeLoading.value = false
|
||||
})
|
||||
} else {
|
||||
// 新增模式:懒加载树
|
||||
userApi.userOrgTreeLazySelector().then((res) => {
|
||||
if (res !== null) {
|
||||
treeData.value = res.map((item) => {
|
||||
return {
|
||||
@@ -376,6 +385,7 @@
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 懒加载子节点
|
||||
@@ -405,15 +415,51 @@
|
||||
const onClose = () => {
|
||||
treeData.value = []
|
||||
treeDefaultExpandedKeys.value = []
|
||||
childTreeExpandedKeys.value = []
|
||||
visible.value = 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 = () => {
|
||||
// 主选择组织:只展开主orgId的祖先
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 任职信息:每行独立展开
|
||||
if (formData.value.positionJson) {
|
||||
formData.value.positionJson.forEach((item, index) => {
|
||||
if (item.orgId) {
|
||||
const ancestors = collectAncestorKeys(treeData.value, item.orgId)
|
||||
childTreeExpandedKeys.value[index] = ancestors ? [...ancestors] : []
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 回显数据
|
||||
const convertFormData = (record) => {
|
||||
const param = {
|
||||
id: record.id
|
||||
}
|
||||
// 查询详情
|
||||
const detailPromise = userApi.userDetail(param).then((data) => {
|
||||
return userApi.userDetail(param).then((data) => {
|
||||
if (data.positionJson) {
|
||||
// 替换表单中的格式与后端查到的
|
||||
data.positionJson = JSON.parse(data.positionJson)
|
||||
@@ -428,24 +474,6 @@
|
||||
})
|
||||
}
|
||||
selePositionData(formData.value.orgId)
|
||||
return data
|
||||
})
|
||||
// 等待树和详情都加载完成后,确保机构节点可回显
|
||||
nextTick(() => {
|
||||
if (treeLoadPromise) {
|
||||
Promise.all([treeLoadPromise, detailPromise]).then(([_, detail]) => {
|
||||
const orgIds = [detail.orgId]
|
||||
if (detail.positionJson) {
|
||||
const positions = typeof detail.positionJson === 'string'
|
||||
? JSON.parse(detail.positionJson)
|
||||
: detail.positionJson
|
||||
positions.forEach((item) => {
|
||||
if (item.orgId) orgIds.push(item.orgId)
|
||||
})
|
||||
}
|
||||
ensureOrgsInTree(orgIds)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -519,10 +547,12 @@
|
||||
positionId: undefined,
|
||||
directorId: undefined
|
||||
})
|
||||
childTreeExpandedKeys.value.push([])
|
||||
}
|
||||
// 删减行
|
||||
const delDomains = (index) => {
|
||||
formData.value.positionJson.splice(index, 1)
|
||||
childTreeExpandedKeys.value.splice(index, 1)
|
||||
}
|
||||
|
||||
// 子表行内选择机构
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
/>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<xn-tree-skeleton v-if="treeLoading && treeData.length === 0" />
|
||||
<a-spin v-else-if="treeData.length > 0" :spinning="treeLoading">
|
||||
<a-tree
|
||||
v-else-if="treeData.length > 0"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:tree-data="treeData"
|
||||
@@ -22,6 +22,7 @@
|
||||
:height="treeHeight"
|
||||
@select="treeSelect"
|
||||
/>
|
||||
</a-spin>
|
||||
<a-empty v-else :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,11 +39,7 @@
|
||||
:placeholder="$t('user.placeholderUserOrg')"
|
||||
allow-clear
|
||||
:tree-data="treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}"
|
||||
:field-names="treeSelectFieldNames"
|
||||
tree-line
|
||||
:load-data="onLoadData"
|
||||
/>
|
||||
@@ -187,7 +184,7 @@
|
||||
<Form ref="formRef" @successful="tableRef.refresh()" />
|
||||
<xn-role-selector
|
||||
ref="RoleSelectorPlusRef"
|
||||
:org-tree-api="selectorApiFunction.orgTreeApi"
|
||||
:org-tree-lazy-api="selectorApiFunction.orgTreeLazyApi"
|
||||
:role-page-api="selectorApiFunction.rolePageApi"
|
||||
:add-show="false"
|
||||
:show="false"
|
||||
@@ -265,6 +262,7 @@
|
||||
const treeData = ref([])
|
||||
const selectedRowKeys = ref([])
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
const treeSelectFieldNames = { children: 'children', label: 'name', value: 'id' }
|
||||
const formRef = ref(null)
|
||||
const RoleSelectorPlusRef = ref()
|
||||
const selectedRecord = ref({})
|
||||
|
||||
Reference in New Issue
Block a user