opt:树形

This commit is contained in:
2026-01-20 16:41:49 +08:00
parent 4a0ef377bb
commit 3b84113d26

View File

@@ -95,9 +95,10 @@
<a-tree-select <a-tree-select
v-model:value="formData.parentDetailId" v-model:value="formData.parentDetailId"
:tree-data="parentTreeData" :tree-data="parentTreeData"
:load-data="handleLoadData"
placeholder="请选择上级类目" placeholder="请选择上级类目"
allow-clear allow-clear
tree-default-expand-all tree-line
/> />
</a-form-item> </a-form-item>
</a-col> </a-col>
@@ -128,7 +129,6 @@
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import { required } from '@/utils/formRules' import { required } from '@/utils/formRules'
import projectApi from '@/api/pmm/projectApi'
import stageDetailApi from '@/api/pmm/stageDetailApi' import stageDetailApi from '@/api/pmm/stageDetailApi'
const open = ref(false) const open = ref(false)
@@ -183,39 +183,44 @@
] ]
} }
const buildTree = (nodes) => { const toTreeNode = (item = {}) => {
const list = Array.isArray(nodes) ? nodes : [] const id = item.detailId
const byId = new Map() const titleParts = []
const roots = [] if (item.modelName) titleParts.push(item.modelName)
list.forEach((item) => { if (item.modelDetail) titleParts.push(item.modelDetail)
const id = item?.detailId const title = titleParts.length ? titleParts.join(' - ') : String(id || '')
if (!id) return return {
const titleParts = [] title,
if (item.modelName) titleParts.push(item.modelName) value: id,
if (item.modelDetail) titleParts.push(item.modelDetail) key: id,
const title = titleParts.length ? titleParts.join(' - ') : String(id) isLeaf: item.isLeaf === true,
byId.set(id, { title, value: id, key: id, children: [], raw: item }) children: Array.isArray(item.children) ? item.children.map(toTreeNode) : []
}) }
byId.forEach((node) => {
const parentId = node.raw?.parentDetailId
if (parentId && byId.has(parentId)) {
byId.get(parentId).children.push(node)
} else {
roots.push(node)
}
})
return roots
} }
const loadParentTree = async (projectId) => { const loadRootTree = async () => {
if (!projectId) { if (!formData.value.stageId) return
parentTreeData.value = [] const data = await stageDetailApi.loadClass({
return stageId: formData.value.stageId,
} parentDetailId: 0
const data = await projectApi.requestDetail({ projectId }) })
const stages = Array.isArray(data) ? data : [] parentTreeData.value = (Array.isArray(data) ? data : []).map(toTreeNode)
const flat = stages.flatMap((s) => (Array.isArray(s?.descriptions) ? s.descriptions : [])) }
parentTreeData.value = buildTree(flat)
const loadSuperiorTree = async (parentDetailId) => {
if (!formData.value.stageId || !parentDetailId) return
const data = await stageDetailApi.superior({
stageId: formData.value.stageId,
parentDetailId
})
parentTreeData.value = (Array.isArray(data) ? data : []).map(toTreeNode)
}
const handleLoadData = async (node) => {
// 展开时走 superior后端会返回包含父链的树结构
const parentId = node?.value
if (!parentId) return
await loadSuperiorTree(parentId)
} }
const recomputeEndTime = () => { const recomputeEndTime = () => {
@@ -234,9 +239,13 @@
} }
) )
const onTopChange = () => { const onTopChange = async () => {
if (formData.value.isTop === true) { if (formData.value.isTop === true) {
formData.value.parentDetailId = 0 formData.value.parentDetailId = 0
parentTreeData.value = []
} else {
// 顶级新增同级parentId = 0加载根节点
await loadRootTree()
} }
} }
@@ -250,7 +259,11 @@
if (formData.value.isTop) { if (formData.value.isTop) {
formData.value.parentDetailId = 0 formData.value.parentDetailId = 0
} }
await loadParentTree(formData.value.projectId) if (formData.value.isTop === false) {
await loadRootTree()
} else {
parentTreeData.value = []
}
recomputeEndTime() recomputeEndTime()
} }