feat:网元信息平滑自动更新,修复新增和删除问题

This commit is contained in:
zhongzm
2025-09-12 16:32:23 +08:00
parent 6b45194c65
commit 33dc7cb7dc
2 changed files with 217 additions and 108 deletions

View File

@@ -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) {

View File

@@ -93,6 +93,7 @@ let tableState: TabeStateType = reactive({
selectedRowKeys: [],
});
/**自动刷新相关 */
let autoRefreshTimer: number | null = null;
@@ -248,7 +249,7 @@ function fnModalVisibleByEdit(row?: Record<string, any>) {
* 进行表达规则校验
*/
function fnModalEditOk(from: Record<string, any>) {
// 新增时刷新列表
// 新增时重新获取数据,确保数据结构一致性
if (!from.id) {
fnGetList();
return;
@@ -276,47 +277,19 @@ function fnModalEditOk(from: Record<string, any>) {
// // 检查网元类型是否发生变化
// const oldNeType = foundItem.neType;
// const newNeType = from.neType;
if (foundItem) {
// 检查网元类型是否发生变化
const oldNeType = foundItem.neType;
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 {
// 网元类型没有变化,也需要重新获取数据以确保数据同步
// 使用静默模式重新获取数据避免loading效果
fnGetList(undefined, true);
}
useNeInfoStore().fnRefreshNelist();
}
/**
@@ -367,11 +340,15 @@ function fnRecordDelete(id: string) {
}
});
tableState.data = tableState.data.filter(item => {
// 重新组织数据结构,确保一致性
const remainingData: Record<string, any>[] = [];
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<string, any>[]) {
} 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<string, any>[]) {
return result;
}
/**平滑更新表格数据,避免闪烁 */
function updateTableDataSmoothly(newData: Record<string, any>[]) {
// 参考仪表盘概览的实现方式直接更新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;
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;
}
})
.finally(() => {
// 刷新缓存的网元信息
@@ -602,9 +699,8 @@ function startAutoRefresh() {
clearInterval(autoRefreshTimer);
}
autoRefreshTimer = window.setInterval(() => {
if (!tableState.loading) {
fnGetList();
}
// 使用静默模式刷新不显示loading
fnGetList(undefined, true);
}, 10000); // 每10秒刷新一次
}