diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index aad058da..a6041d57 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -1072,7 +1072,19 @@ export default { element:'Element', granularity:'Granularity', unit:'Unit', - } + }, + kpiKeyTarget:{ + "fullWidthLayout":"Full Width", + "twoColumnLayout":"Two Column", + "saveLayout": "Save Layout", + "restoreSaved": "Restore Layout", + "saveSuccess": " '{name}' saved successfully", + "restoreSavedSuccess": " '{name}' restored successfully", + "noSavedLayout": "No saved layout found for '{name}'", + "layout1": "Layout 1", + "layout2": "Layout 2", + "layout3": "Layout 3" + }, }, traceManage: { analysis: { @@ -1288,7 +1300,7 @@ export default { }, exportFile:{ fileName:'File Source', - downTip: "Confirm the download file name is [{fileName}] File?", + downTip: "Confirm the download file name is [{fileName}] File?", downTipErr: "Failed to get file", deleteTip: "Confirm the delete file name is [{fileName}] File?", deleteTipErr: "Failed to delete file", diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 3f878c47..4fa0e506 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -1072,7 +1072,19 @@ export default { element:'元素', granularity:'颗粒度', unit:'单位', - } + }, + kpiKeyTarget:{ + "fullWidthLayout":"全宽布局", + "twoColumnLayout":"两列布局", + "saveLayout": "保存布局", + "restoreSaved": "恢复布局", + "saveSuccess": " {name} 保存成功", + "restoreSavedSuccess": " {name} 恢复成功", + "noSavedLayout": "没有找到保存的布局 {name}", + "layout1": "布局1", + "layout2": "布局2", + "layout3": "布局3" + }, }, traceManage: { analysis: { @@ -1127,7 +1139,7 @@ export default { stopNotRun: "{title} 任务未运行", }, task: { - traceId: '跟踪编号', + traceId: '跟踪编号', trackType: '跟踪类型', trackTypePlease: '请选择跟踪类型', creater: '创建人', @@ -1288,7 +1300,7 @@ export default { }, exportFile:{ fileName:'文件来源', - downTip: "确认下载文件名为 【{fileName}】 文件?", + downTip: "确认下载文件名为 【{fileName}】 文件?", downTipErr: "文件获取失败", deleteTip: "确认删除文件名为 【{fileName}】 文件?", deleteTipErr: "文件删除失败", @@ -2110,7 +2122,7 @@ export default { hostSelectMore: "加载更多 {num}", hostSelectHeader: "主机列表", }, - ps:{ + ps:{ realTimeHigh:"高", realTimeLow:"低", realTimeRegular:"常规", diff --git a/src/views/perfManage/kpiKeyTarget/index.vue b/src/views/perfManage/kpiKeyTarget/index.vue index 1e6ed330..47559efd 100644 --- a/src/views/perfManage/kpiKeyTarget/index.vue +++ b/src/views/perfManage/kpiKeyTarget/index.vue @@ -1,5 +1,4 @@ +const isSaving = ref(false); +const isRestoring = ref(false); +//保存布局按钮 +const handleSaveLayout = async (info: MenuInfo) => { + if (typeof info.key === 'string' && !isSaving.value) { + isSaving.value = true; + isRestoring.value = true; + try { + await saveCurrentLayout(info.key); + } finally { + setTimeout(()=>{ + isSaving.value = false; + isRestoring.value = false; + },700) + } + } else { + console.error('Invalid layout key or operation in progress'); + } +}; +//恢复布局按钮 +const handleRestoreLayout = async (info: MenuInfo) => { + if (typeof info.key === 'string' && !isRestoring.value) { + isRestoring.value = true; + isSaving.value = true; + try { + await restoreSavedLayout(info.key); + } finally { + setTimeout(()=>{ + isSaving.value = false; + isRestoring.value = false; + },700) + } + } else { + console.error('Invalid layout key or operation in progress'); + } +}; + +// 保存当前布局 +const saveCurrentLayout = async (layoutName: string) => { + const savedLayouts = JSON.parse(localStorage.getItem('savedLayouts') || '{}'); + savedLayouts[layoutName] = { + layout: chartOrder.value, + selectedTypes: selectedNeTypes.value + }; + localStorage.setItem('savedLayouts', JSON.stringify(savedLayouts)); + message.success(t('layout.saveSuccess', { name: t(`layout.${layoutName}`) })); +}; +//恢复已保存的布局 +const restoreSavedLayout = async (layoutName: string) => { + const savedLayouts = JSON.parse(localStorage.getItem('savedLayouts') || '{}'); + const savedLayout = savedLayouts[layoutName]; + if (savedLayout && Array.isArray(savedLayout.selectedTypes) && Array.isArray(savedLayout.layout)) { + selectedNeTypes.value = savedLayout.selectedTypes; + networkElementTypes.value = savedLayout.selectedTypes; + + // 更新布局 + chartOrder.value = savedLayout.layout.filter((item: LayoutItem) => + savedLayout.selectedTypes.includes(item.i) + ); + + // 如果有当前选中的网元类型不在保存的布局中,添加它们 + const missingTypes = savedLayout.selectedTypes.filter((type: AllChartType) => + !chartOrder.value.some(item => item.i === type) + ); + missingTypes.forEach((type: AllChartType) => { + chartOrder.value.push({ + x: (chartOrder.value.length % 2) * 6, + y: Math.floor(chartOrder.value.length / 2) * 4, + w: 6, + h: 4, + i: type, + }); + }); + + localStorage.setItem('chartOrder', JSON.stringify(chartOrder.value)); + localStorage.setItem('selectedNeTypes', JSON.stringify(selectedNeTypes.value)); + + await nextTick(); + await initCharts(); + + message.success(t('layout.restoreSavedSuccess', { name: t(`layout.${layoutName}`) })); + } else { + message.warning(t('layout.noSavedLayout', { name: t(`layout.${layoutName}`) })); + } +}; + +// 应用全宽布局 +const applyFullWidthLayout = () => { + isManuallyUpdating.value = true; + const newLayout = selectedNeTypes.value.map((type, index) => ({ + x: 0, + y: index * 8, + w: 12, + h: 8, + i: type, + })); + + nextTick(() => { + Object.assign(chartOrder.value, newLayout) + // chartOrder.value = newLayout; + localStorage.setItem('chartOrder', JSON.stringify(newLayout)); + initCharts(); + // 直接更新图表,不调用 handleLayoutUpdated + chartOrder.value.forEach((item) => { + const state = chartStates[item.i]; + if (state?.chart.value) { + state.chart.value.resize(); + renderChart(item.i); + } + }); + isManuallyUpdating.value = false; + }); +}; + +// 应用两列布局 +const applyTwoColumnLayout = () => { + isManuallyUpdating.value = true; + const newLayout = selectedNeTypes.value.map((type, index) => ({ + x: (index % 2) * 6, + y: Math.floor(index / 2) * 4, + w: 6, + h: 4, + i: type, + })); + nextTick(() => { + // chartOrder.value = newLayout; + Object.assign(chartOrder.value, newLayout) + localStorage.setItem('chartOrder', JSON.stringify(newLayout)); + initCharts(); + // 直接更新图表,不调用 handleLayoutUpdated + chartOrder.value.forEach((item) => { + const state = chartStates[item.i]; + if (state?.chart.value) { + state.chart.value.resize(); + renderChart(item.i); + } + }); + isManuallyUpdating.value = false; + }); +}; +