From 33dc7cb7dc459350fb8fb311bd28c369a5d72a51 Mon Sep 17 00:00:00 2001 From: zhongzm Date: Fri, 12 Sep 2025 16:32:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E7=BD=91=E5=85=83=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=B9=B3=E6=BB=91=E8=87=AA=E5=8A=A8=E6=9B=B4=E6=96=B0=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=B0=E5=A2=9E=E5=92=8C=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/ne/neInfo/components/EditModal.vue | 37 ++- src/views/ne/neInfo/index.vue | 288 ++++++++++++------- 2 files changed, 217 insertions(+), 108 deletions(-) diff --git a/src/views/ne/neInfo/components/EditModal.vue b/src/views/ne/neInfo/components/EditModal.vue index 9d031c7d..6b642b17 100644 --- a/src/views/ne/neInfo/components/EditModal.vue +++ b/src/views/ne/neInfo/components/EditModal.vue @@ -49,21 +49,34 @@ let dict: { function generateNextNeId(neType: string): string { const neListData = props.neListData as any[]; - // 找到对应网元类型的分组 - const targetGroup = neListData.find(group => group.neType === neType); + // 收集所有该类型的网元ID + const existingIds: number[] = []; - if (!targetGroup || !targetGroup.childrenData) { - return '001'; // 如果没有找到该类型的网元,返回001 + neListData.forEach(item => { + if (item.children && item.children.length > 0) { + // 分组行,检查子项 + if (item.neType === neType) { + item.children.forEach((child: any) => { + if (child.neId && /^\d+$/.test(child.neId)) { + existingIds.push(parseInt(child.neId, 10)); + } + }); + } + } else { + // 单行,直接检查 + if (item.neType === neType && item.neId && /^\d+$/.test(item.neId)) { + existingIds.push(parseInt(item.neId, 10)); + } + } + }); + + // 如果没有找到该类型的网元,返回001 + if (existingIds.length === 0) { + return '001'; } - // 获取该类型下所有网元的ID - const existingIds = targetGroup.childrenData - .map((item: any) => item.neId) - .filter((id: string) => /^\d+$/.test(id)) // 只保留纯数字ID - .map((id: string) => parseInt(id, 10)) - .sort((a: number, b: number) => a - b); - - // 找到下一个可用ID + // 排序并找到下一个可用ID + existingIds.sort((a, b) => a - b); let nextId = 1; for (const id of existingIds) { if (id === nextId) { diff --git a/src/views/ne/neInfo/index.vue b/src/views/ne/neInfo/index.vue index 0f79d904..00f5b916 100644 --- a/src/views/ne/neInfo/index.vue +++ b/src/views/ne/neInfo/index.vue @@ -93,6 +93,7 @@ let tableState: TabeStateType = reactive({ selectedRowKeys: [], }); + /**自动刷新相关 */ let autoRefreshTimer: number | null = null; @@ -248,7 +249,7 @@ function fnModalVisibleByEdit(row?: Record) { * 进行表达规则校验 */ function fnModalEditOk(from: Record) { - // 新增时刷新列表 + // 新增时重新获取数据,确保数据结构一致性 if (!from.id) { fnGetList(); return; @@ -256,67 +257,39 @@ function fnModalEditOk(from: Record) { // 编辑时局部更新信息 // stateNeInfo(from.neType, from.neId) // .then(res => { - // 在树状表格结构中找到编辑更新的网元 - let foundItem = null; + // 在树状表格结构中找到编辑更新的网元 + let foundItem = null; - for (const item of tableState.data) { - if (item.children && item.children.length > 0) { - const child = item.children.find((c: any) => c.id === from.id); - if (child) { - foundItem = child; - break; - } - } else if (item.id === from.id) { - foundItem = item; - break; - } + for (const item of tableState.data) { + if (item.children && item.children.length > 0) { + const child = item.children.find((c: any) => c.id === from.id); + if (child) { + foundItem = child; + break; } - - // if (foundItem && res.code === RESULT_CODE_SUCCESS) { - // // 检查网元类型是否发生变化 - // const oldNeType = foundItem.neType; - // const newNeType = from.neType; - if (foundItem) { - // 检查网元类型是否发生变化 - const oldNeType = foundItem.neType; - const newNeType = from.neType; - - // 更新网元信息 - foundItem.neType = from.neType; - foundItem.neId = from.neId; - foundItem.rmUid = from.rmUid; - foundItem.neName = from.neName; - foundItem.ip = from.ip; - foundItem.port = from.port; - - // if (res.data.online) { - // foundItem.status = '1'; - // if (res.data.standby) { - // foundItem.status = '3'; - // } - // } else { - // foundItem.status = '0'; - // } - // Object.assign(foundItem.serverState, res.data); - // const resouresUsage = parseResouresUsage(foundItem.serverState); - // Reflect.set(foundItem, 'resoures', resouresUsage); - // - // // 如果网元类型发生变化,需要重新组织数据结构 - // if (oldNeType !== newNeType) { - // fnGetList(); // 重新获取数据以重新组织表格结构 - // } - // } - // }) - // .finally(() => { - // useNeInfoStore().fnRefreshNelist(); - // }); - // 如果网元类型发生变化,需要重新组织数据结构 - if (oldNeType !== newNeType) { - fnGetList(); // 重新获取数据以重新组织表格结构 + } else if (item.id === from.id) { + foundItem = item; + break; } } - useNeInfoStore().fnRefreshNelist(); + // if (foundItem && res.code === RESULT_CODE_SUCCESS) { + // // 检查网元类型是否发生变化 + // const oldNeType = foundItem.neType; + // const newNeType = from.neType; + // 检查网元类型是否发生变化 + const oldNeType = foundItem?.neType; + const newNeType = from.neType; + + // 如果网元类型发生变化,需要重新组织数据结构 + if (oldNeType !== newNeType) { + fnGetList(); // 重新获取数据以重新组织表格结构 + } else { + // 网元类型没有变化,也需要重新获取数据以确保数据同步 + // 使用静默模式重新获取数据,避免loading效果 + fnGetList(undefined, true); + } + } /** @@ -367,11 +340,15 @@ function fnRecordDelete(id: string) { } }); - tableState.data = tableState.data.filter(item => { + // 重新组织数据结构,确保一致性 + const remainingData: Record[] = []; + + tableState.data.forEach(item => { if (item.children && item.children.length > 0) { - // 如果分组行被删除,移除整个分组 + // 分组行处理 if (idsToDelete.has(item.id)) { - return false; + // 如果分组行被删除,跳过整个分组 + return; } // 过滤分组中的子节点 @@ -380,25 +357,46 @@ function fnRecordDelete(id: string) { ); if (filteredChildren.length === 0) { - return false; // 移除整个分组 + // 移除整个分组 + return; } else if (filteredChildren.length === 1) { // 如果只剩一个,转换为单行显示 const singleItem = filteredChildren[0]; - Object.assign(item, singleItem); - item.children = undefined; + remainingData.push({ + ...singleItem, + children: undefined + }); } else { - // 更新分组 - item.children = filteredChildren; + // 保持分组 + remainingData.push({ + ...item, + children: filteredChildren + }); } } else { // 单行项目,检查是否在删除列表中 - return !idsToDelete.has(item.id); + if (!idsToDelete.has(item.id)) { + remainingData.push(item); + } } - return true; }); + // 重新组织为树状结构 + const flatData = remainingData.map(item => { + // 如果是单行,直接返回 + if (!item.children) { + return item; + } + // 如果是分组,返回所有子项 + return item.children; + }).flat(); + + tableState.data = transformToTreeTableData(flatData); + // 清空选择 tableState.selectedRowKeys = []; + + // 刷新缓存 useNeInfoStore().fnRefreshNelist(); } else { @@ -485,7 +483,7 @@ function transformToTreeTableData(flatData: Record[]) { } else { // 多个网元,创建分组行,使用children字段 const groupRow = { - id: `group_${neType}_${Math.random().toString(36).substr(2, 9)}`, + id: `group_${neType}_${sortedItems.map((item: any) => item.id).join('_')}`, neType: neType, neId: '', // 空白显示 rmUid: '', // 空白显示 @@ -502,10 +500,117 @@ function transformToTreeTableData(flatData: Record[]) { return result; } +/**平滑更新表格数据,避免闪烁 */ +function updateTableDataSmoothly(newData: Record[]) { + // 参考仪表盘概览的实现方式:直接更新reactive对象的属性 + // 这样可以保持Vue的响应式特性,同时避免组件重新渲染 + + // 如果当前没有数据,直接设置新数据 + if (!tableState.data || tableState.data.length === 0) { + tableState.data = newData; + return; + } + + // 创建新数据的映射,便于快速查找 + const newDataMap = new Map(); + newData.forEach(item => { + if (item.children && item.children.length > 0) { + // 分组行 + newDataMap.set(item.id, item); + item.children.forEach((child: any) => { + newDataMap.set(child.id, child); + }); + } else { + // 单行 + newDataMap.set(item.id, item); + } + }); + + // 直接更新现有数据的属性,保持对象引用不变 + tableState.data.forEach((existingItem, index) => { + if (existingItem.children && existingItem.children.length > 0) { + // 处理分组行 + const newGroupItem = newDataMap.get(existingItem.id); + if (newGroupItem) { + // 直接更新分组行的属性,但保留用户可能正在编辑的状态 + Object.assign(existingItem, { + neType: newGroupItem.neType, + neId: newGroupItem.neId, + rmUid: newGroupItem.rmUid, + neName: newGroupItem.neName, + ip: newGroupItem.ip, + port: newGroupItem.port, + status: newGroupItem.status, + }); + + // 更新子项 + if (newGroupItem.children) { + newGroupItem.children.forEach((newChild: any) => { + const existingChild = existingItem.children.find((c: any) => c.id === newChild.id); + if (existingChild) { + // 直接更新子项属性 + Object.assign(existingChild, { + neType: newChild.neType, + neId: newChild.neId, + rmUid: newChild.rmUid, + neName: newChild.neName, + ip: newChild.ip, + port: newChild.port, + status: newChild.status, + serverState: newChild.serverState, + }); + } + }); + } + } + } else { + // 处理单行 + const newItem = newDataMap.get(existingItem.id); + if (newItem) { + // 直接更新单行属性 + Object.assign(existingItem, { + neType: newItem.neType, + neId: newItem.neId, + rmUid: newItem.rmUid, + neName: newItem.neName, + ip: newItem.ip, + port: newItem.port, + status: newItem.status, + serverState: newItem.serverState, + }); + } + } + }); + + // 处理新增的项目 + const existingIds = new Set(); + tableState.data.forEach(item => { + if (item.children && item.children.length > 0) { + existingIds.add(item.id); + item.children.forEach((child: any) => { + existingIds.add(child.id); + }); + } else { + existingIds.add(item.id); + } + }); + + const newItems = newData.filter(item => !existingIds.has(item.id)); + if (newItems.length > 0) { + // 直接添加到现有数组 + tableState.data.push(...newItems); + } +} + /**查询列表, pageNum初始页数 */ -function fnGetList(pageNum?: number) { - if (tableState.loading) return; - tableState.loading = true; +function fnGetList(pageNum?: number, silent = false) { + if (tableState.loading && !silent) return; + + // 只有在非静默模式下才显示loading + if (!silent) { + tableState.loading = true; + } + if (pageNum) { queryParams.pageNum = pageNum; } @@ -517,29 +622,21 @@ function fnGetList(pageNum?: number) { tableState.selectedRowKeys = []; } tablePagination.total = res.total; - // // 遍历处理资源情况数值 - // const processedData = res.rows.map(item => { - // let resouresUsage = { - // sysDiskUsage: 0, - // sysMemUsage: 0, - // sysCpuUsage: 0, - // nfCpuUsage: 0, - // }; - // const neState = item.serverState; - // if (neState) { - // resouresUsage = parseResouresUsage(neState); - // } else { - // item.serverState = { online: false }; - // } - // Reflect.set(item, 'resoures', resouresUsage); - // return item; - // }); - // - // // 转换为树状表格结构 - // tableState.data = transformToTreeTableData(processedData); - tableState.data = transformToTreeTableData(res.rows); + + // 转换为树状表格结构 + const newData = transformToTreeTableData(res.rows); + + // 如果是静默刷新,使用平滑更新;否则直接替换数据 + if (silent) { + updateTableDataSmoothly(newData); + } else { + tableState.data = newData; + } + } + + if (!silent) { + tableState.loading = false; } - tableState.loading = false; }) .finally(() => { // 刷新缓存的网元信息 @@ -602,9 +699,8 @@ function startAutoRefresh() { clearInterval(autoRefreshTimer); } autoRefreshTimer = window.setInterval(() => { - if (!tableState.loading) { - fnGetList(); - } + // 使用静默模式刷新,不显示loading + fnGetList(undefined, true); }, 10000); // 每10秒刷新一次 }