feat:网元信息平滑自动更新,修复新增和删除问题
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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秒刷新一次
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user