From 9b9e63bb526ec60dda3f33855759874a39a45cb4 Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期五, 03 一月 2025 10:24:03 +0800 Subject: [PATCH] 多行表单,大模型嵌套表格 --- src/views/project/yw/systemManage/agentGraph/AgentGraph.vue | 341 +++++++++++--------------------------------------------- 1 files changed, 66 insertions(+), 275 deletions(-) diff --git a/src/views/project/yw/systemManage/agentGraph/AgentGraph.vue b/src/views/project/yw/systemManage/agentGraph/AgentGraph.vue index f521df7..b313478 100644 --- a/src/views/project/yw/systemManage/agentGraph/AgentGraph.vue +++ b/src/views/project/yw/systemManage/agentGraph/AgentGraph.vue @@ -1,170 +1,35 @@ <template> - <div v-loading="firstLoading" class="h-full w-full bg-white relative"> - <!-- <div class="absolute right-4 top-4 z-10"> - - - <span class="ywifont ywicon-zishiying cursor-pointer" title="鑷�傚簲" @click="selfAdaptClick"></span> - </div> --> - <div class="h-full w-full" ref="graphRef"></div> - - <div - class="absolute left-4 top-4 z-10 w-16 divide-y-[1.5px] divide-solid divide-gray-100 rounded-lg" - style="box-shadow: 0 0 15px #dbdee6" - > - <div - class="flex-column content-center items-center border-x-0 py-2 hover:bg-gray-200 active:bg-gray-300 cursor-pointer" - @click="toolBarItemClick(item)" - v-for="item in toolBarFunList" - > - <span class="ywifont !text-[20px] mb-1 p-1.5" :class="[`ywicon-${item.icon}`]"></span> - <span>{{ item.label }}</span> - </div> - </div> - <div class="absolute right-2 top-4 py-7 px-5 rounded-lg w-96" style="box-shadow: 0 0 15px #dbdee6" v-if="searchIsShow"> - <span - class="absolute ywifont ywicon-guanbi right-4 top-4 cursor-pointer hover:bg-gray-200 active:bg-gray-300" - @click="closeSearch" - ></span> - <div class="flex-column"> - <span class="mb-5">鏌ユ壘</span> - <el-input v-model="searchValue" @input="debounceSearch" placeholder="杈撳叆鏌ユ壘鍐呭" v-elInputFocus></el-input> - </div> - </div> + <div class="h-full" v-loading="firstLoading"> + <TreeGraph v-if="graphData" :data="graphData" class="h-full" :maxCount="maxCount" /> </div> </template> <script setup lang="ts"> -import { DagreLayout } from '@antv/layout'; -import { Graph } from '@antv/x6'; import { onMounted, ref } from 'vue'; -import { routeMap } from './routeMap'; -import { circleShape, edgeShape, ellipseShape, rectShape } from './shape'; -import { getMetricAgentListByPost, getMetricNameListByPost } from '/@/api/metrics'; +import TreeGraph from '/@/components/graph/treeGraph/TreeGraph.vue'; import router from '/@/router'; -import { travelTree } from '/@/utils/util'; -const graphRef = ref<HTMLDivElement>(null); - -let graph: Graph; -const firstLoading = ref(false); +import { getMetricAgentListByPost, getMetricNameListByPost } from '/@/api/metrics'; +import { OrgTreeItem } from './types'; const agentId = router.currentRoute.value.query.id as string; - -const initGraph = () => { - // 鍒濆鍖栫敾甯� - graph = new Graph({ - container: graphRef.value, - async: true, - interacting: false, - connecting: { - anchor: 'orth', - connector: 'rounded', - connectionPoint: 'boundary', - router: { - name: 'er', - args: { - offset: 24, - direction: 'H', - }, - }, - }, - mousewheel: { - enabled: true, - }, - panning: { - enabled: true, - }, - }); -}; - -const getLeaf = (item) => { - if (item.Children && item.Children.length > 0) { - const first = item.Children[0]; - return getLeaf(first); - } else { - return item; - } -}; - -const initEvent = () => { - graph.on('node:click', ({ cell, e, node, view }) => { - return; - const target = e.target; - const targetParent = target.parentElement; - if (!targetParent.className?.baseVal?.includes('name')) return; - - const data = node.getData(); - const leafData = getLeaf(data); - const routeName = routeMap.get(leafData.Code); - router.push({ - name: routeName, - }); - }); -}; - -const loadData = (treeData: any[]) => { - const data: any = { - nodes: [], - edges: [], +const maxCount = ref(null); +const graphData = ref(null); +const firstLoading = ref(false); +const convertOrgTreeToTreeNode = (orgTreeData: OrgTreeItem) => { + const treeData = { + id: orgTreeData.treeId, + label: orgTreeData.label, + data: orgTreeData, + children: orgTreeData.children?.length > 0 ? orgTreeData.children.map((item) => convertOrgTreeToTreeNode(item)) : [], }; - travelTree( - treeData, - (item) => { - let shapeAttrs = null; - switch (item.type) { - case 'agent': - shapeAttrs = rectShape(item.treeId, item.label); - break; - case 'metrics': - shapeAttrs = ellipseShape(item.treeId, item.label); - break; - case 'dimension': - shapeAttrs = circleShape(item.treeId, item.label); - break; - default: - break; - } - data.nodes.push({ - id: item.treeId, - - ...shapeAttrs, - children: item.children?.map((item) => item.treeId), - data: item, - }); - if (item.children) { - for (const child of item?.children) { - const sourceId = `${item.treeId}-b`; - const targetId = `${child.treeId}-t`; - - data.edges.push({ - source: { cell: item.treeId, port: sourceId }, - target: { cell: child.treeId, port: targetId }, - ...edgeShape, - }); - } - } - }, - undefined, - undefined, - 'children' - ); - const dagreLayout = new DagreLayout({ - type: 'dagre', - rankdir: 'TB', - // align: 'UL', - // ranksep: 30, - nodesep: 30, - - controlPoints: false, - }); - let newData = dagreLayout.layout(data); - - graph.fromJSON(newData); - selfAdapt(); + return treeData; }; - const getFirstOrgTreeList = async () => { // const res = await GetSMCenterFirstOrgTreeList(); - + /** @description 缁村害鏁伴噺 */ + let dimensionCount = 0; + /** @description 鎸囨爣鏁伴噺 */ + let metricsCount = 0; const allAgentRes = getMetricAgentListByPost(); const metricsRes = getMetricNameListByPost({ agent_id: agentId, @@ -174,139 +39,65 @@ const allAgentList = allAgentResult?.values ?? []; const metricsList = metricsResult?.values ?? []; // const foundAgent = allAgentList.find(item=>item.) - + metricsCount = metricsList.length; const foundAgent = allAgentList.find((item) => item.id === agentId); if (!foundAgent) return []; const agentTreeId = `agent-${foundAgent.id}`; - let logicTree = [ - { - treeId: agentTreeId, - logicId: foundAgent.id, - model: foundAgent, - type: 'agent', - get label() { - return this.model.title; - }, - children: metricsList.map((curVal) => { - const metricsTreeId = `${agentTreeId}-metrics-${curVal.id}`; - const metrics = { - treeId: metricsTreeId, - logicId: curVal.id, - type: 'metrics', - - model: curVal, - get label() { - return this.model.title; - }, - children: (curVal.dimensions ?? []).map((item) => { - const dimensionTreeId = `${metricsTreeId}-dimension-${item.id}`; - return { - treeId: dimensionTreeId, - logicId: item.id, - type: 'dimension', - model: item, - get label() { - return this.model.title; - }, - }; - }), - }; - return metrics; - }, []), + let logicTree: OrgTreeItem = { + treeId: agentTreeId, + logicId: foundAgent.id, + model: foundAgent, + type: 'agent', + get label() { + return this.model.title; }, - ]; + level: 0, + children: metricsList.map((curVal) => { + const metricsTreeId = `${agentTreeId}-metrics-${curVal.id}`; + const dimensionList = curVal.dimensions ?? []; + const metrics: OrgTreeItem = { + treeId: metricsTreeId, + logicId: curVal.id, + type: 'metrics', + + model: curVal, + get label() { + return this.model.title; + }, + level: 1, + children: dimensionList.map((item) => { + const dimensionTreeId = `${metricsTreeId}-dimension-${item.id}`; + return { + treeId: dimensionTreeId, + logicId: item.id, + type: 'dimension', + model: item, + get label() { + return this.model.title; + }, + level: 2, + }; + }), + }; + dimensionCount += metrics.children.length; + + return metrics; + }, []), + }; const resData = logicTree; - return resData; + const maxCount = Math.max(dimensionCount, metricsCount); + return [resData, maxCount]; }; -const selfAdapt = () => { - setTimeout(() => { - graph.zoomToFit(); - }, 100); -}; - -//#region ====================== 宸ュ叿鏍� ====================== -const enum ToolBarType { - Search, - ZoomIn, - ZoomOut, - Reset, -} -type ToolBarItem = { - icon: string; - label: string; - type: ToolBarType; -}; -const toolBarFunList: ToolBarItem[] = [ - { - icon: 'sousuo', - label: '鎼滅储', - type: ToolBarType.Search, - }, - { - icon: 'fangda', - label: '鏀惧ぇ', - type: ToolBarType.ZoomIn, - }, - { - icon: 'suoxiao', - label: '缂╁皬', - type: ToolBarType.ZoomOut, - }, - { - icon: 'zishiying', - label: '閲嶇疆', - type: ToolBarType.Reset, - }, -]; - -const searchIsShow = ref(false); -const searchValue = ref(''); -const ZOOM_OFFSET = 0.05; -const toolBarItemClick = (item: ToolBarItem) => { - switch (item.type) { - case ToolBarType.Search: - searchIsShow.value = true; - break; - case ToolBarType.ZoomIn: - graph.zoom(ZOOM_OFFSET); - break; - - case ToolBarType.ZoomOut: - graph.zoom(-ZOOM_OFFSET); - - break; - - case ToolBarType.Reset: - selfAdapt(); - default: - break; - } -}; - -const debounceSearch = () => {}; -const closeSearch = () => { - searchIsShow.value = false; -}; -//#endregion onMounted(async () => { if (!agentId) return; firstLoading.value = true; - const orgTreeList = await getFirstOrgTreeList().catch(() => { + const [orgTreeData, maxLevelNodeCount] = await (getFirstOrgTreeList() as any).finally(() => { firstLoading.value = false; }); - setTimeout(() => { - initGraph(); - initEvent(); - loadData(orgTreeList as any); - firstLoading.value = false; - }, 100); + maxCount.value = maxLevelNodeCount; + graphData.value = convertOrgTreeToTreeNode(orgTreeData); }); </script> -<style scoped lang="scss"> -:deep(g[data-shape='rect'].x6-node > text:hover) { - // text-decoration: underline; - cursor: pointer; -} -</style> +<style scoped lang="scss"></style> -- Gitblit v1.9.3