Merge branch 'multi-tenant' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 into multi-tenant

This commit is contained in:
TsMask
2025-06-27 16:58:32 +08:00

View File

@@ -447,17 +447,13 @@ function fnGetListTitle() {
// 获取表头文字,只传递纯网元类型 // 获取表头文字,只传递纯网元类型
getKPITitle(state.neType) getKPITitle(state.neType)
.then(res => { .then(res => {
//处理getKPITitle返回的结果
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
//检查值
tableColumns.value = []; //设为空数组 tableColumns.value = []; //设为空数组
const columns: any[] = []; //初始化,构建新表头 const columns: any[] = [];
for (const item of res.data) { for (const item of res.data) {
//遍历res.data const kpiDisplay = item[`${language}Title`];
const kpiDisplay = item[`${language}Title`]; //提取标题kpiDisplay和ID标识kpiValue
const kpiValue = item[`kpiId`]; const kpiValue = item[`kpiId`];
columns.push({ columns.push({
//
title: kpiDisplay, title: kpiDisplay,
dataIndex: kpiValue, dataIndex: kpiValue,
align: 'left', align: 'left',
@@ -486,6 +482,9 @@ function fnGetListTitle() {
}); });
nextTick(() => { nextTick(() => {
tableColumns.value = columns; tableColumns.value = columns;
nextTick(() => {
fnGetList();
});
}); });
return true; return true;
} else { } else {
@@ -495,10 +494,6 @@ function fnGetListTitle() {
}); });
return false; return false;
} }
})
.then(result => {
//result是前一个.then返回的值(true or false)
result && fnGetList();
}); });
} }
@@ -508,7 +503,10 @@ async function fnGetList() {
tableState.loading = true; tableState.loading = true;
try { try {
// 获取所有网元数据 // 第一步:根据指标信息和网元数量,创建完整的默认数据结构
fnCreateDefaultDataStructure();
// 第二步:获取所有网元数据
let allNeData: any[] = []; let allNeData: any[] = [];
// 每个选中的网元ID发送一个请求 // 每个选中的网元ID发送一个请求
@@ -541,55 +539,8 @@ async function fnGetList() {
tablePagination.total = allNeData.length; tablePagination.total = allNeData.length;
tableState.data = allNeData; tableState.data = allNeData;
// 调用图表渲染函数 // 第三步:用真实数据更新默认值
fnRanderChartData(); fnUpdateDataWithRealValues(allNeData);
// 封装legend表格数据
kpiStats.value = [];
// 为每个指标和每个网元创建统计数据
for (const columns of tableColumns.value) {
if (
columns.key === 'neName' ||
columns.key === 'startIndex' ||
columns.key === 'timeGroup'
) {
continue;
}
// 处理每个网元
for (const neId of state.neIds) {
// 过滤该网元的数据
const neData = tableState.data.filter(item => item._neId === neId);
if (neData.length === 0) continue;
const values = neData.map((item: any) => {
return item[columns.key] ? Number(item[columns.key]) : 0;
});
// 计算总值
const total = Number(
values.reduce((sum, val) => sum + val, 0).toFixed(2)
);
// 计算平均值
const avg =
values.length > 0 ? Number((total / values.length).toFixed(2)) : 0;
kpiStats.value.push({
kpiId: `${columns.key}_${neId}`, // 使用组合ID来唯一标识指标-网元对
title: `${columns.title}(${neId})`, // 在标题中显示网元ID
rawKpiId: columns.key,
rawKpiTitle: columns.title,
neId: neId,
max: values.length > 0 ? Math.max(...values) : 0,
min: values.length > 0 ? Math.min(...values) : 0,
avg: avg,
total: total,
});
}
}
return true; return true;
} catch (error) { } catch (error) {
@@ -604,6 +555,260 @@ async function fnGetList() {
} }
} }
/**创建默认数据结构 */
function fnCreateDefaultDataStructure() {
// 重置
chartLegendSelected = {};
chartDataXAxisData = [];
chartDataYSeriesData = [];
kpiStats.value = [];
// 创建默认的时间点(当前时间)
const defaultTimePoint = Date.now();
chartDataXAxisData = [parseDateToStr(defaultTimePoint)];
// 为每个网元的每个指标创建默认数据结构
for (const columns of tableColumns.value) {
if (
columns.key === 'neName' ||
columns.key === 'startIndex' ||
columns.key === 'timeGroup'
) {
continue;
}
for (const neId of state.neIds) {
const kpiId = `${columns.key}_${neId}`;
const seriesName = `${columns.title}(${neId})`;
// 获取或生成颜色
const color = kpiColors.get(kpiId) || generateColorRGBA();
kpiColors.set(kpiId, color);
// 创建图表系列,包含默认数据点
const seriesData = {
name: seriesName,
key: kpiId,
type: 'line',
symbol: 'none',
symbolSize: 6,
smooth: 0.6,
showSymbol: true,
sampling: 'lttb',
itemStyle: {
color: color,
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: color.replace(')', ',0.8)'),
},
{
offset: 1,
color: color.replace(')', ',0.3)'),
},
]),
},
data: [0], // 默认值为0确保tooltip能显示指标信息
};
chartDataYSeriesData.push(seriesData);
chartLegendSelected[seriesName] = true;
// 创建统计表格项默认值为0
kpiStats.value.push({
kpiId: `${columns.key}_${neId}`,
title: `${columns.title}(${neId})`,
rawKpiId: columns.key,
rawKpiTitle: columns.title,
neId: neId,
max: 0,
min: 0,
avg: 0,
total: 0,
});
}
}
// 创建默认的原始数据(用于表格显示)
const defaultTableData: any[] = [];
for (const neId of state.neIds) {
const defaultRow: any = {
_neId: neId,
neName: `${state.neType}-${neId}`,
timeGroup: defaultTimePoint,
};
// 为每个指标添加默认值0
for (const columns of tableColumns.value) {
if (
columns.key === 'neName' ||
columns.key === 'startIndex' ||
columns.key === 'timeGroup'
) {
continue;
}
defaultRow[columns.key] = 0;
}
defaultTableData.push(defaultRow);
}
tableState.data = defaultTableData;
tablePagination.total = defaultTableData.length;
// 渲染默认的图表和表格
if (kpiChart.value && kpiChartDom.value) {
kpiChart.value.setOption(
{
legend: {
selected: chartLegendSelected,
},
xAxis: {
type: 'category',
boundaryGap: false,
axisLabel: {
color:
document.documentElement.getAttribute('data-theme') === 'dark'
? '#CACADA'
: '#333',
},
splitLine: {
show: true,
lineStyle: {
color: getSplitLineColor(),
},
},
data: chartDataXAxisData,
},
series: chartDataYSeriesData,
},
{
replaceMerge: ['xAxis', 'series'],
}
);
}
}
/**用真实数据更新默认值 */
function fnUpdateDataWithRealValues(allNeData: any[]) {
if (allNeData.length === 0) {
// 如果没有真实数据,保持默认值
return;
}
// 更新原始数据表格
tableState.data = allNeData;
tablePagination.total = allNeData.length;
// 获取所有时间点并格式化
const timePoints = [
...new Set(allNeData.map(item => item.timeGroup)),
].sort();
chartDataXAxisData = timePoints.map(time => parseDateToStr(+time));
// 更新图表数据
for (const series of chartDataYSeriesData) {
const [kpiKey, neId] = series.key.split('_');
const neData = allNeData.filter(item => item._neId === neId);
// 为每个时间点填充数据
series.data = timePoints.map(time => {
const dataPoint = neData.find(item => item.timeGroup === time);
return dataPoint ? +dataPoint[kpiKey] : null;
});
}
// 更新统计数据
for (const columns of tableColumns.value) {
if (
columns.key === 'neName' ||
columns.key === 'startIndex' ||
columns.key === 'timeGroup'
) {
continue;
}
// 处理每个网元
for (const neId of state.neIds) {
// 过滤该网元的数据
const neData = allNeData.filter(item => item._neId === neId);
// 找到对应的统计项并更新
const statsItem = kpiStats.value.find(
(item: KPIStats) => item.kpiId === `${columns.key}_${neId}`
);
if (statsItem) {
if (neData.length === 0) {
// 没有数据时保持默认值0
statsItem.max = 0;
statsItem.min = 0;
statsItem.avg = 0;
statsItem.total = 0;
} else {
// 有数据时计算统计值
const values = neData.map((item: any) => {
return item[columns.key] ? Number(item[columns.key]) : 0;
});
const total = Number(
values.reduce((sum, val) => sum + val, 0).toFixed(2)
);
const avg =
values.length > 0 ? Number((total / values.length).toFixed(2)) : 0;
statsItem.max = values.length > 0 ? Math.max(...values) : 0;
statsItem.min = values.length > 0 ? Math.min(...values) : 0;
statsItem.avg = avg;
statsItem.total = total;
}
}
}
}
// 更新图表
if (kpiChart.value && kpiChartDom.value) {
// 如果有选中的行,只显示选中的指标
if (selectedRows.value.length > 0) {
Object.keys(chartLegendSelected).forEach(key => {
chartLegendSelected[key] = false;
});
kpiStats.value.forEach((item: KPIStats) => {
if (selectedRows.value.includes(item.kpiId)) {
chartLegendSelected[item.title] = true;
}
});
}
kpiChart.value.setOption(
{
legend: {
selected: chartLegendSelected,
},
xAxis: {
type: 'category',
boundaryGap: false,
axisLabel: {
color:
document.documentElement.getAttribute('data-theme') === 'dark'
? '#CACADA'
: '#333',
},
splitLine: {
show: true,
lineStyle: {
color: getSplitLineColor(),
},
},
data: chartDataXAxisData,
},
series: chartDataYSeriesData,
},
{
replaceMerge: ['xAxis', 'series'],
}
);
}
}
/**切换显示类型 图或表格 */ /**切换显示类型 图或表格 */
function fnChangShowType() { function fnChangShowType() {
tableState.showTable = !tableState.showTable; tableState.showTable = !tableState.showTable;
@@ -700,11 +905,13 @@ function fnRanderChart() {
}, },
series: [], // 数据y轴 series: [], // 数据y轴
}; };
kpiChart.value.setOption(option); //设置图表配置项应用到kpiChart实例上 if (kpiChart.value && kpiChartDom.value) {
kpiChart.value.setOption(option); //设置图表配置项应用到kpiChart实例上
}
// 创建 ResizeObserver 实例 监听图表容器大小变化,并在变化时调整图表大小 // 创建 ResizeObserver 实例 监听图表容器大小变化,并在变化时调整图表大小
var observer = new ResizeObserver(entries => { var observer = new ResizeObserver(entries => {
if (kpiChart.value) { if (kpiChart.value && kpiChartDom.value) {
kpiChart.value.resize(); kpiChart.value.resize();
} }
}); });
@@ -721,125 +928,10 @@ let chartDataYSeriesData: Record<string, any>[] = [];
/**图表数据渲染 */ /**图表数据渲染 */
function fnRanderChartData() { function fnRanderChartData() {
if (kpiChart.value == null || tableState.data.length <= 0) { if (!kpiChart.value || !kpiChartDom.value || tableState.data.length <= 0) {
return; return;
} }
fnUpdateDataWithRealValues(tableState.data);
// 重置
chartLegendSelected = {};
chartDataXAxisData = [];
chartDataYSeriesData = [];
// 为每个网元的每个指标创建一条线
for (const neId of state.neIds) {
for (const columns of tableColumns.value) {
if (
columns.key === 'neName' ||
columns.key === 'startIndex' ||
columns.key === 'timeGroup'
) {
continue;
}
const kpiId = `${columns.key}_${neId}`;
const seriesName = `${columns.title}(${neId})`;
// 获取或生成颜色
const color = kpiColors.get(kpiId) || generateColorRGBA();
kpiColors.set(kpiId, color);
const seriesData = {
name: seriesName,
key: kpiId,
type: 'line',
symbol: 'none',
symbolSize: 6,
smooth: 0.6,
showSymbol: true,
sampling: 'lttb',
itemStyle: {
color: color,
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: color.replace(')', ',0.8)'),
},
{
offset: 1,
color: color.replace(')', ',0.3)'),
},
]),
},
data: [] as (number | null)[],
};
chartDataYSeriesData.push(seriesData);
// 默认所有指标都显示
chartLegendSelected[seriesName] = true;
}
}
// 获取所有时间点并格式化
const timePoints = [
...new Set(tableState.data.map(item => item.timeGroup)),
].sort();
chartDataXAxisData = timePoints.map(time => parseDateToStr(+time));
// 填充数据
for (const series of chartDataYSeriesData) {
const [kpiKey, neId] = series.key.split('_');
const neData = tableState.data.filter(item => item._neId === neId);
series.data = timePoints.map(time => {
const dataPoint = neData.find(item => item.timeGroup === time);
return dataPoint ? +dataPoint[kpiKey] : null;
});
}
// 如果有选中的行,只显示选中的指标
if (selectedRows.value.length > 0) {
Object.keys(chartLegendSelected).forEach(key => {
chartLegendSelected[key] = false;
});
kpiStats.value.forEach((item: KPIStats) => {
if (selectedRows.value.includes(item.kpiId)) {
chartLegendSelected[item.title] = true;
}
});
}
// 更新图表
kpiChart.value.setOption(
{
legend: {
selected: chartLegendSelected,
},
xAxis: {
type: 'category',
boundaryGap: false,
axisLabel: {
color:
document.documentElement.getAttribute('data-theme') === 'dark'
? '#CACADA'
: '#333',
},
splitLine: {
show: true,
lineStyle: {
color: getSplitLineColor(),
},
},
data: chartDataXAxisData,
},
series: chartDataYSeriesData,
},
{
replaceMerge: ['xAxis', 'series'],
}
);
} }
/**图表折线显示全部 */ /**图表折线显示全部 */
@@ -869,89 +961,8 @@ function fnRealTimeSwitch(bool: any) {
chartDataXAxisData = []; chartDataXAxisData = [];
chartDataYSeriesData = []; chartDataYSeriesData = [];
// 重新初始化图表配置 // 先创建默认数据结构
const option = { fnCreateDefaultDataStructure();
tooltip: {
trigger: 'axis',
position: function (pt: any) {
return [pt[0], '10%'];
},
confine: true,
backgroundColor:
document.documentElement.getAttribute('data-theme') === 'dark'
? 'rgba(48, 48, 48, 0.8)'
: 'rgba(255, 255, 255, 0.9)',
borderColor:
document.documentElement.getAttribute('data-theme') === 'dark'
? '#555'
: '#ddd',
textStyle: {
color:
document.documentElement.getAttribute('data-theme') === 'dark'
? '#CACADA'
: '#333',
},
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [],
axisLabel: {
color:
document.documentElement.getAttribute('data-theme') === 'dark'
? '#CACADA'
: '#333',
},
splitLine: {
show: true,
lineStyle: {
color: getSplitLineColor(),
},
},
},
yAxis: {
type: 'value',
boundaryGap: [0, '100%'],
axisLabel: {
formatter: '{value}',
color:
document.documentElement.getAttribute('data-theme') === 'dark'
? '#CACADA'
: '#333',
},
splitNumber: 5,
scale: true,
splitLine: {
show: true,
lineStyle: {
color: getSplitLineColor(),
},
},
},
legend: {
show: false,
type: 'scroll',
orient: 'vertical',
top: 40,
right: 20,
itemWidth: 20,
itemGap: 25,
textStyle: {
color: '#646A73',
},
icon: 'circle',
selected: {},
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
series: [],
};
kpiChart.value.setOption(option);
// 建立链接 // 建立链接
const options: OptionsType = { const options: OptionsType = {
@@ -1051,7 +1062,7 @@ function wsMessage(res: Record<string, any>) {
// 使用 requestAnimationFrame 更新图表 // 使用 requestAnimationFrame 更新图表
requestAnimationFrame(() => { requestAnimationFrame(() => {
if (!kpiChart.value) return; if (!kpiChart.value || !kpiChartDom.value) return;
// 重新生成 series 数据 // 重新生成 series 数据
const series = []; const series = [];
@@ -1139,6 +1150,7 @@ function wsMessage(res: Record<string, any>) {
// 添加更新统计数据的函数 // 添加更新统计数据的函数
function updateKpiStats() { function updateKpiStats() {
// 清空现有统计数据
kpiStats.value = []; kpiStats.value = [];
// 为每个指标和每个网元创建统计数据 // 为每个指标和每个网元创建统计数据
@@ -1156,32 +1168,41 @@ function updateKpiStats() {
// 过滤该网元的数据 // 过滤该网元的数据
const neData = tableState.data.filter(item => item._neId === neId); const neData = tableState.data.filter(item => item._neId === neId);
if (neData.length === 0) continue; // 创建统计项(即使没有数据也创建)
const statsItem = {
const values = neData.map((item: any) => {
return item[columns.key] ? Number(item[columns.key]) : 0;
});
// 计算总值
const total = Number(
values.reduce((sum, val) => sum + val, 0).toFixed(2)
);
// 计算平均值
const avg =
values.length > 0 ? Number((total / values.length).toFixed(2)) : 0;
kpiStats.value.push({
kpiId: `${columns.key}_${neId}`, kpiId: `${columns.key}_${neId}`,
title: `${columns.title}(${neId})`, title: `${columns.title}(${neId})`,
rawKpiId: columns.key, rawKpiId: columns.key,
rawKpiTitle: columns.title, rawKpiTitle: columns.title,
neId: neId, neId: neId,
max: values.length > 0 ? Math.max(...values) : 0, max: 0,
min: values.length > 0 ? Math.min(...values) : 0, min: 0,
avg: avg, avg: 0,
total: total, total: 0,
}); };
if (neData.length > 0) {
// 有数据时计算统计值
const values = neData.map((item: any) => {
return item[columns.key] ? Number(item[columns.key]) : 0;
});
// 计算总值
const total = Number(
values.reduce((sum, val) => sum + val, 0).toFixed(2)
);
// 计算平均值
const avg =
values.length > 0 ? Number((total / values.length).toFixed(2)) : 0;
statsItem.max = values.length > 0 ? Math.max(...values) : 0;
statsItem.min = values.length > 0 ? Math.min(...values) : 0;
statsItem.avg = avg;
statsItem.total = total;
}
kpiStats.value.push(statsItem);
} }
} }
} }
@@ -1414,6 +1435,10 @@ onMounted(() => {
onBeforeUnmount(() => { onBeforeUnmount(() => {
ws.close(); ws.close();
if (kpiChart.value) {
kpiChart.value.dispose();
kpiChart.value = null;
}
}); });
</script> </script>