From 8d531b34a36f2032b08b0bec3449b39b039e433e Mon Sep 17 00:00:00 2001 From: 12451 <12451@example.com> Date: Thu, 2 Jul 2026 19:26:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AE=BE=E5=A4=87=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=A1=B5=E6=94=B9=E4=B8=BA=E5=B7=A6=E5=8F=B3=E4=B8=A4=E5=88=97?= =?UTF-8?q?=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- software/web/src/pages/devices/index.tsx | 79 +++++++++++++++++++----- 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/software/web/src/pages/devices/index.tsx b/software/web/src/pages/devices/index.tsx index bcdc18f..cd930f5 100644 --- a/software/web/src/pages/devices/index.tsx +++ b/software/web/src/pages/devices/index.tsx @@ -8,7 +8,6 @@ import { useEffect, useState, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { - Layout, Typography, Modal, Button, @@ -17,11 +16,14 @@ import { Dropdown, Menu, Message, + Spin, + Tree, } from '@arco-design/web-react'; import { IconPlus, IconDelete, IconEdit, + IconRefresh, } from '@arco-design/web-react/icon'; import { treeApi, @@ -33,7 +35,7 @@ import { type Organization, } from '@/api/devices'; -import OrganizationTree, { +import { buildTreeData, collectCabinets, findOrgInTree, @@ -43,8 +45,6 @@ import OrganizationTree, { import CabinetGrid from './CabinetGrid'; import AddCabinetModal from './AddCabinetModal'; -const Content = Layout.Content; - export default function Devices() { const navigate = useNavigate(); const [treeData, setTreeData] = useState([]); @@ -285,18 +285,63 @@ export default function Devices() { ); - return ( - - + // -------- 树渲染 -------- + const renderNodeTitle = useCallback( + (nodeType: NodeType, nodeId: number, title: string) => ( + handleRightClick(e, nodeType, nodeId)} + > + {title} + + ), + [handleRightClick], + ); - + const injectTitleRender = useCallback( + (nodes: TreeInternalNode[]): unknown[] => + nodes.map((n) => ({ + ...n, + title: renderNodeTitle(n._type, n._id, n.title), + children: n.children ? injectTitleRender(n.children) : undefined, + })), + [renderNodeTitle], + ); + + const renderedTreeData = [ + { + key: 'all', + title: renderNodeTitle('all', 0, '全部'), + children: injectTitleRender(treeData) as TreeInternalNode[], + }, + ]; + + return ( +
+ {/* 左列:组织架构树 */} +
+
+ 组织架构 +
+ + {treeData.length > 0 ? ( + + ) : ( + !loading && 暂无数据 + )} + +
+ + {/* 右列:柜子列表 */} +
设备列表 ({cabinets.length}) @@ -306,7 +351,7 @@ export default function Devices() {
- +
{/* 右键菜单 */} setCabinetModalVisible(false)} onSuccess={async () => { setCabinetModalVisible(false); await loadTree(); }} /> - +
); }