feat:网元信息平滑自动更新,修复新增和删除问题
This commit is contained in:
@@ -49,21 +49,34 @@ let dict: {
|
|||||||
function generateNextNeId(neType: string): string {
|
function generateNextNeId(neType: string): string {
|
||||||
const neListData = props.neListData as any[];
|
const neListData = props.neListData as any[];
|
||||||
|
|
||||||
// 找到对应网元类型的分组
|
// 收集所有该类型的网元ID
|
||||||
const targetGroup = neListData.find(group => group.neType === neType);
|
const existingIds: number[] = [];
|
||||||
|
|
||||||
if (!targetGroup || !targetGroup.childrenData) {
|
neListData.forEach(item => {
|
||||||
return '001'; // 如果没有找到该类型的网元,返回001
|
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
|
// 排序并找到下一个可用ID
|
||||||
const existingIds = targetGroup.childrenData
|
existingIds.sort((a, b) => a - b);
|
||||||
.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
|
|
||||||
let nextId = 1;
|
let nextId = 1;
|
||||||
for (const id of existingIds) {
|
for (const id of existingIds) {
|
||||||
if (id === nextId) {
|
if (id === nextId) {
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ let tableState: TabeStateType = reactive({
|
|||||||
selectedRowKeys: [],
|
selectedRowKeys: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**自动刷新相关 */
|
/**自动刷新相关 */
|
||||||
let autoRefreshTimer: number | null = null;
|
let autoRefreshTimer: number | null = null;
|
||||||
|
|
||||||
@@ -248,7 +249,7 @@ function fnModalVisibleByEdit(row?: Record<string, any>) {
|
|||||||
* 进行表达规则校验
|
* 进行表达规则校验
|
||||||
*/
|
*/
|
||||||
function fnModalEditOk(from: Record<string, any>) {
|
function fnModalEditOk(from: Record<string, any>) {
|
||||||
// 新增时刷新列表
|
// 新增时重新获取数据,确保数据结构一致性
|
||||||
if (!from.id) {
|
if (!from.id) {
|
||||||
fnGetList();
|
fnGetList();
|
||||||
return;
|
return;
|
||||||
@@ -276,47 +277,19 @@ function fnModalEditOk(from: Record<string, any>) {
|
|||||||
// // 检查网元类型是否发生变化
|
// // 检查网元类型是否发生变化
|
||||||
// const oldNeType = foundItem.neType;
|
// const oldNeType = foundItem.neType;
|
||||||
// const newNeType = from.neType;
|
// const newNeType = from.neType;
|
||||||
if (foundItem) {
|
|
||||||
// 检查网元类型是否发生变化
|
// 检查网元类型是否发生变化
|
||||||
const oldNeType = foundItem.neType;
|
const oldNeType = foundItem?.neType;
|
||||||
const newNeType = from.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) {
|
if (oldNeType !== newNeType) {
|
||||||
fnGetList(); // 重新获取数据以重新组织表格结构
|
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 (item.children && item.children.length > 0) {
|
||||||
// 如果分组行被删除,移除整个分组
|
// 分组行处理
|
||||||
if (idsToDelete.has(item.id)) {
|
if (idsToDelete.has(item.id)) {
|
||||||
return false;
|
// 如果分组行被删除,跳过整个分组
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 过滤分组中的子节点
|
// 过滤分组中的子节点
|
||||||
@@ -380,25 +357,46 @@ function fnRecordDelete(id: string) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (filteredChildren.length === 0) {
|
if (filteredChildren.length === 0) {
|
||||||
return false; // 移除整个分组
|
// 移除整个分组
|
||||||
|
return;
|
||||||
} else if (filteredChildren.length === 1) {
|
} else if (filteredChildren.length === 1) {
|
||||||
// 如果只剩一个,转换为单行显示
|
// 如果只剩一个,转换为单行显示
|
||||||
const singleItem = filteredChildren[0];
|
const singleItem = filteredChildren[0];
|
||||||
Object.assign(item, singleItem);
|
remainingData.push({
|
||||||
item.children = undefined;
|
...singleItem,
|
||||||
|
children: undefined
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// 更新分组
|
// 保持分组
|
||||||
item.children = filteredChildren;
|
remainingData.push({
|
||||||
|
...item,
|
||||||
|
children: filteredChildren
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} 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 = [];
|
tableState.selectedRowKeys = [];
|
||||||
|
|
||||||
|
|
||||||
// 刷新缓存
|
// 刷新缓存
|
||||||
useNeInfoStore().fnRefreshNelist();
|
useNeInfoStore().fnRefreshNelist();
|
||||||
} else {
|
} else {
|
||||||
@@ -485,7 +483,7 @@ function transformToTreeTableData(flatData: Record<string, any>[]) {
|
|||||||
} else {
|
} else {
|
||||||
// 多个网元,创建分组行,使用children字段
|
// 多个网元,创建分组行,使用children字段
|
||||||
const groupRow = {
|
const groupRow = {
|
||||||
id: `group_${neType}_${Math.random().toString(36).substr(2, 9)}`,
|
id: `group_${neType}_${sortedItems.map((item: any) => item.id).join('_')}`,
|
||||||
neType: neType,
|
neType: neType,
|
||||||
neId: '', // 空白显示
|
neId: '', // 空白显示
|
||||||
rmUid: '', // 空白显示
|
rmUid: '', // 空白显示
|
||||||
@@ -502,10 +500,117 @@ function transformToTreeTableData(flatData: Record<string, any>[]) {
|
|||||||
return result;
|
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初始页数 */
|
/**查询列表, pageNum初始页数 */
|
||||||
function fnGetList(pageNum?: number) {
|
function fnGetList(pageNum?: number, silent = false) {
|
||||||
if (tableState.loading) return;
|
if (tableState.loading && !silent) return;
|
||||||
|
|
||||||
|
// 只有在非静默模式下才显示loading
|
||||||
|
if (!silent) {
|
||||||
tableState.loading = true;
|
tableState.loading = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (pageNum) {
|
if (pageNum) {
|
||||||
queryParams.pageNum = pageNum;
|
queryParams.pageNum = pageNum;
|
||||||
}
|
}
|
||||||
@@ -517,29 +622,21 @@ function fnGetList(pageNum?: number) {
|
|||||||
tableState.selectedRowKeys = [];
|
tableState.selectedRowKeys = [];
|
||||||
}
|
}
|
||||||
tablePagination.total = res.total;
|
tablePagination.total = res.total;
|
||||||
// // 遍历处理资源情况数值
|
|
||||||
// const processedData = res.rows.map(item => {
|
// 转换为树状表格结构
|
||||||
// let resouresUsage = {
|
const newData = transformToTreeTableData(res.rows);
|
||||||
// sysDiskUsage: 0,
|
|
||||||
// sysMemUsage: 0,
|
// 如果是静默刷新,使用平滑更新;否则直接替换数据
|
||||||
// sysCpuUsage: 0,
|
if (silent) {
|
||||||
// nfCpuUsage: 0,
|
updateTableDataSmoothly(newData);
|
||||||
// };
|
} else {
|
||||||
// const neState = item.serverState;
|
tableState.data = newData;
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!silent) {
|
||||||
tableState.loading = false;
|
tableState.loading = false;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
// 刷新缓存的网元信息
|
// 刷新缓存的网元信息
|
||||||
@@ -602,9 +699,8 @@ function startAutoRefresh() {
|
|||||||
clearInterval(autoRefreshTimer);
|
clearInterval(autoRefreshTimer);
|
||||||
}
|
}
|
||||||
autoRefreshTimer = window.setInterval(() => {
|
autoRefreshTimer = window.setInterval(() => {
|
||||||
if (!tableState.loading) {
|
// 使用静默模式刷新,不显示loading
|
||||||
fnGetList();
|
fnGetList(undefined, true);
|
||||||
}
|
|
||||||
}, 10000); // 每10秒刷新一次
|
}, 10000); // 每10秒刷新一次
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user