feat:kpi自定义仪表盘需求更改

This commit is contained in:
zhongzm
2025-08-14 19:30:53 +08:00
parent 7b7907616f
commit bcd7599676
3 changed files with 217 additions and 145 deletions

View File

@@ -1032,6 +1032,11 @@ export default {
expressionErrorTip:'Please check the expression, the wrong indicator is {kpiId}',
expressionNoIdTip:'Please check the expression, no valid indicator is found',
unitSelect:'To better display the image, the same unit needs to be selected. The current unit is:',
avg:'(average)',
total:'(total)',
ago1:'Past 1 day value',
ago7:'Past 7 days value',
ago30:'Past 30 days value',
},
kpiKeyTarget:{
"time":"Time",
@@ -1734,8 +1739,8 @@ export default {
baseDnPlease: 'Please enter the LDAP base DN correctly',
ldapUserFilter: "User Filter",
userFilterPlease: 'Please enter the LDAP user filter correctly',
ldapBindDN: "Bind DN",
ldapBindPassword: "Bind Password",
ldapBindDN: "Bind DN",
ldapBindPassword: "Bind Password",
smtpHost: 'Server Address',
smtpHostPlease: 'Please enter the SMTP server address correctly',
smtpPort: 'Port Number',
@@ -1762,7 +1767,7 @@ export default {
uploadFileErr: 'Authentication source icon upload failed',
viewInfoErr: "Failed to get authentication source information",
addInfo: "Add Authentication Source",
editInfo: "Modify Authentication Source",
editInfo: "Modify Authentication Source",
delTip: "Confirm deleting the authentication source number [{num}] data item?",
delOk: "Deleted Successfully",
},

View File

@@ -1032,6 +1032,11 @@ export default {
expressionErrorTip:'请检查表达式,错误的指标为{kpiId}',
expressionNoIdTip:'请检查表达式,没有找到任何有效的指标',
unitSelect:'为更好展示图需选择相同单位,当前单位为:',
avg:'(平均)',
total:'(累计)',
ago1:'近1天值',
ago7:'近7天值',
ago30:'近30天值',
},
kpiKeyTarget:{
"time":"时间",
@@ -1734,8 +1739,8 @@ export default {
baseDnPlease: '请正确输入LDAP 基础DN',
ldapUserFilter: "用户过滤",
userFilterPlease: '请正确输入LDAP 用户过滤',
ldapBindDN: "绑定DN",
ldapBindPassword: "绑定密码",
ldapBindDN: "绑定DN",
ldapBindPassword: "绑定密码",
smtpHost: '服务器地址',
smtpHostPlease: '请正确输入SMTP 服务器地址',
smtpPort: '端口号',
@@ -1762,7 +1767,7 @@ export default {
uploadFileErr: '认证源图标上传失败',
viewInfoErr: "获取认证源信息失败",
addInfo: "添加认证源",
editInfo: "修改认证源",
editInfo: "修改认证源",
delTip: "确认删除认证源编号为 【{num}】 的数据项?",
delOk: "删除成功",
},

View File

@@ -269,33 +269,65 @@ const statsColumns: TableColumnType<any>[] = [
dataIndex: 'title',
key: 'title',
},
// {
// title: t('views.perfManage.kpiOverView.totalValue'),
// dataIndex: 'total',
// key: 'total',
// width: '12%',
// sortDirections: ['ascend', 'descend'],
// },
// {
// title: t('views.perfManage.kpiOverView.avgValue'),
// dataIndex: 'avg',
// key: 'avg',
// width: '24%',
// sortDirections: ['ascend', 'descend'],
// },
{
title: t('views.perfManage.kpiOverView.maxValue'),
dataIndex: 'max',
key: 'max',
width: '200px',
title: t('views.perfManage.customTarget.ago1'),
dataIndex: 'last1Day',
key: 'last1Day',
width: '150px',
sortDirections: ['ascend', 'descend'],
customRender: ({ record }: { record: any }) => {
const unit = record.unit || '';
const value = record.last1Day;
// 如果是默认值,直接显示
if (value === '-') {
return value;
}
if (unit.includes('%') || unit.toLowerCase().includes('mbps') || unit.toLowerCase().includes('bps')) {
return `${value} ${t('views.perfManage.customTarget.avg')}`;
} else {
return `${value} ${t('views.perfManage.customTarget.total')}`;
}
},
},
{
title: t('views.perfManage.kpiOverView.minValue'),
dataIndex: 'min',
key: 'min',
width: '200px',
title: t('views.perfManage.customTarget.ago7'),
dataIndex: 'last7Days',
key: 'last7Days',
width: '150px',
sortDirections: ['ascend', 'descend'],
customRender: ({ record }: { record: any }) => {
const unit = record.unit || '';
const value = record.last7Days;
// 如果是默认值,直接显示
if (value === '-') {
return value;
}
if (unit.includes('%') || unit.toLowerCase().includes('mbps') || unit.toLowerCase().includes('bps')) {
return `${value} ${t('views.perfManage.customTarget.avg')}`;
} else {
return `${value} ${t('views.perfManage.customTarget.total')}`;
}
},
},
{
title: t('views.perfManage.customTarget.ago30'),
dataIndex: 'last30Days',
key: 'last30Days',
width: '150px',
sortDirections: ['ascend', 'descend'],
customRender: ({ record }: { record: any }) => {
const unit = record.unit || '';
const value = record.last30Days;
// 如果是默认值,直接显示
if (value === '-') {
return value;
}
if (unit.includes('%') || unit.toLowerCase().includes('mbps') || unit.toLowerCase().includes('bps')) {
return `${value} ${t('views.perfManage.customTarget.avg')}`;
} else {
return `${value} ${t('views.perfManage.customTarget.total')}`;
}
},
},
];
@@ -358,6 +390,133 @@ function fnRecordExport() {
});
}
/**初始化统计表格数据 */
function fnInitStatsData() {
// 先初始化表格,显示指标列表和默认值
kpiStats.value = [];
for (const columns of tableColumns.value) {
if (
columns.key === 'neName' ||
columns.key === 'startIndex' ||
columns.key === 'timeGroup'
) {
continue;
}
kpiStats.value.push({
kpiId: columns.key,
title: columns.title,
unit: columns.unit,
last1Day: '-', // 默认值,显示加载中状态
last7Days: '-',
last30Days: '-',
});
}
}
/**获取近期统计数据 */
async function fnGetStatsData() {
if (!state.neType[0]) return;
const now = new Date();
const stats: Record<string, any> = {};
// 获取近1天、7天、30天的数据
const periods = [
{ key: 'last1Day', days: 1 },
{ key: 'last7Days', days: 7 },
{ key: 'last30Days', days: 30 }
];
// 获取所有统计数据,等全部计算完成后统一更新
for (const period of periods) {
const startTime = new Date(now);
startTime.setDate(now.getDate() - period.days);
startTime.setHours(0, 0, 0, 0);
const endTime = new Date(now);
endTime.setHours(23, 59, 59, 999);
const params = {
neType: state.neType[0],
neId: state.neType[1],
startTime: startTime.getTime().toString(),
endTime: endTime.getTime().toString(),
sortField: 'created_at',
sortOrder: 'desc',
};
try {
const res = await listCustomData(params);
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
// 为每个指标计算统计值暂存到stats对象中
for (const columns of tableColumns.value) {
if (
columns.key === 'neName' ||
columns.key === 'startIndex' ||
columns.key === 'timeGroup'
) {
continue;
}
const values = res.data.map((item: any) => {
return item[columns.key] ? Number(item[columns.key]) : 0;
});
let calculatedValue = 0;
if (values.length > 0) {
const unit = columns.unit || '';
// 智能单位判断:百分比值%和速率值Mbps计算平均值普通值计算累加值
if (unit.includes('%') || unit.toLowerCase().includes('mbps') || unit.toLowerCase().includes('bps')) {
// 百分比和速率值使用平均值
calculatedValue = Number((values.reduce((sum, val) => sum + val, 0) / values.length).toFixed(2));
} else {
// 普通值使用累加值
calculatedValue = Number(values.reduce((sum, val) => sum + val, 0).toFixed(2));
}
}
if (!stats[columns.key]) {
stats[columns.key] = {};
}
stats[columns.key][period.key] = calculatedValue;
}
}
} catch (error) {
console.error(`获取${period.key}数据失败:`, error);
// 如果获取失败设置默认值为0
for (const columns of tableColumns.value) {
if (
columns.key === 'neName' ||
columns.key === 'startIndex' ||
columns.key === 'timeGroup'
) {
continue;
}
if (!stats[columns.key]) {
stats[columns.key] = {};
}
stats[columns.key][period.key] = 0;
}
}
}
// 所有统计数据计算完成后,统一更新显示
for (const statsItem of kpiStats.value) {
const kpiId = statsItem.kpiId;
if (stats[kpiId]) {
statsItem.last1Day = stats[kpiId].last1Day || 0;
statsItem.last7Days = stats[kpiId].last7Days || 0;
statsItem.last30Days = stats[kpiId].last30Days || 0;
} else {
// 如果没有统计数据,保持默认值
statsItem.last1Day = '-';
statsItem.last7Days = '-';
statsItem.last30Days = '-';
}
}
}
/**查询数据列表表头 */
function fnGetListTitle() {
// 当前语言
@@ -378,7 +537,7 @@ function fnGetListTitle() {
tableState.data = [];
tableColumns.value = [];
tableColumnsDnd.value = [];
kpiStats.value = []; //清空数据
kpiStats.value = []; //清空数据,因为没有可用指标
fnRanderChartData();
return false;
}
@@ -420,6 +579,8 @@ function fnGetListTitle() {
nextTick(() => {
tableColumns.value = columns;
// 立即初始化统计表格,显示指标列表和默认值
fnInitStatsData();
});
return true;
} else {
@@ -431,7 +592,11 @@ function fnGetListTitle() {
}
})
.then(result => {
result && fnGetList();
if (result) {
fnGetList();
// 获取近期统计数据
fnGetStatsData();
}
});
}
@@ -457,7 +622,10 @@ function fnGetList() {
tableState.data = [];
// tableColumns.value = [];
// tableColumnsDnd.value = [];
kpiStats.value = []; //清空数据
// 即使没有图表数据,也要确保联动表格显示指标和默认值
if (kpiStats.value.length === 0) {
fnInitStatsData();
}
fnRanderChartData();
return false;
}
@@ -468,58 +636,8 @@ function fnGetList() {
.then(result => {
if (result) {
fnRanderChartData();
//封装legend表格数据
kpiStats.value = [];
for (const columns of tableColumns.value) {
if (
columns.key === 'neName' ||
columns.key === 'startIndex' ||
columns.key === 'timeGroup'
) {
continue;
}
const values = tableState.data.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,
title: columns.title,
unit: columns.unit,
max: values.length > 0 ? Math.max(...values) : 0,
min: values.length > 0 ? Math.min(...values) : 0,
avg,
total: total,
});
}
} else {
kpiStats.value = [];
for (const columns of tableColumns.value) {
if (
columns.key === 'neName' ||
columns.key === 'startIndex' ||
columns.key === 'timeGroup'
) {
continue;
}
kpiStats.value.push({
kpiId: columns.key,
title: columns.title,
unit: columns.unit,
max: 0,
min: 0,
avg: 0,
total: 0,
});
}
// 图表数据获取成功后,开始获取统计数据(此时统计表格已经显示默认值)
fnGetStatsData();
}
});
}
@@ -730,6 +848,11 @@ function fnRanderChartData() {
function fnRealTimeSwitch(bool: any) {
if (bool) {
tableState.seached = false;
// 确保统计数据已获取(如果表格为空则先初始化再获取数据)
if (kpiStats.value.length === 0) {
fnInitStatsData();
fnGetStatsData();
}
// 建立链接
const options: OptionsType = {
url: '/ws',
@@ -1190,68 +1313,7 @@ onBeforeUnmount(() => {
})
"
>
<template #headerCell="{ column }">
<template v-if="column.key === 'total'">
<span>
{{ t('views.perfManage.kpiOverView.totalValue') }}
<a-tooltip placement="bottom">
<template #title>
<span>
{{ t('views.perfManage.kpiOverView.totalValueTip') }}
</span>
</template>
<InfoCircleOutlined />
</a-tooltip>
</span>
</template>
<template v-if="column.key === 'avg'">
<span>
{{ t('views.perfManage.kpiOverView.avgValue') }}
<a-tooltip placement="bottom">
<template #title>
<span>
{{ t('views.perfManage.kpiOverView.avgValueTip') }}
</span>
</template>
<InfoCircleOutlined />
</a-tooltip>
</span>
</template>
<template v-if="column.key === 'max'">
<span>
{{ t('views.perfManage.kpiOverView.maxValue') }}
<a-tooltip placement="bottom">
<template #title>
<span>
{{ t('views.perfManage.kpiOverView.maxValueTip') }}
</span>
</template>
<InfoCircleOutlined />
</a-tooltip>
</span>
</template>
<template v-if="column.key === 'min'">
<span>
{{ t('views.perfManage.kpiOverView.minValue') }}
<a-tooltip placement="bottom">
<template #title>
<span>
{{ t('views.perfManage.kpiOverView.minValueTip') }}
</span>
</template>
<InfoCircleOutlined />
</a-tooltip>
</span>
</template>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'avg'">
<span v-if="record.unit !== '%'">-</span>
</template>
<template v-if="column.key === 'total'">
<span v-if="record.unit == '%'">-</span>
</template>
</template>
</a-table>
</div>
</div>