---黄金指标初版

This commit is contained in:
lai
2023-12-06 18:13:21 +08:00
parent be6e91390e
commit 36ac9d0a5f
6 changed files with 257 additions and 125 deletions

View File

@@ -28,10 +28,10 @@ export async function listgoldData(query: Record<string, any>) {
let sortSql = ' order by ';
if (query.sortField) {
sortSql += ` ${query.sortField} `;
}else{
} else {
sortSql += ` start_time `;
}
if (query.sortOrder === 'asc') {
sortSql += ' asc ';
} else {
@@ -76,12 +76,6 @@ export async function listgoldData(query: Record<string, any>) {
return result;
}
/**
* 查询黄金指标数据
* @param query 查询参数
@@ -92,11 +86,11 @@ export async function goldData(query: Record<string, any>) {
url: `/ne/kpi/data`,
method: 'get',
params: {
neType:query.neType[0],
neId:query.neType[1],
startTime:query.beginTime,
endTime:query.endTime,
interval:query.particle
neType: query.neType[0],
neId: query.neType[1],
startTime: query.beginTime,
endTime: query.endTime,
interval: query.particle,
},
timeout: 60_000,
});
@@ -114,9 +108,8 @@ export async function getGoldTitleByNE(neType: string) {
const result = await request({
url: `/ne/kpi/title`,
method: 'get',
params:{neType}
params: { neType },
});
// 解析数据
return result;
}

View File

@@ -633,6 +633,8 @@ export default {
nullTip:'There are no statistical data within this time range',
kpiTitle:'KPI Statistics Chart',
allData:'Complete Data',
makeLine:'Statistical Chart',
time:'Time',
}
},
traceManage: {

View File

@@ -633,6 +633,8 @@ export default {
nullTip:'此时间范围内没有统计数据',
kpiTitle:'KPI统计图表',
allData:'完整统计数据',
makeLine:'统计图',
time:'时间',
}
},
traceManage: {

View File

@@ -118,7 +118,7 @@ let tablePagination = {
showSizeChanger: true,
/**数据总数 */
total: 0,
showTotal: (total: number) => `总共 ${total}`,
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
onChange: (page: number, pageSize: number) => {
tablePagination.current = page;
tablePagination.pageSize = pageSize;

View File

@@ -2,12 +2,15 @@
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { message, Form } from 'ant-design-vue/lib';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import ChartLine from '@/components/ChartLine/index.vue';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeInfoStore from '@/store/modules/neinfo';
import useI18n from '@/hooks/useI18n';
import { getGoldTitleByNE, goldData } from '@/api/perfManage/goldTarget';
import dayjs from 'dayjs';
import { parseDateToStr } from '@/utils/date-utils';
const { t, currentLocale } = useI18n();
@@ -18,10 +21,69 @@ let neCascaderOptions = ref<Record<string, any>[]>([]);
/**记录开始结束时间 */
let queryRangePicker = ref<[string, string]>(['', '']);
/**表格字段列排序 */
let tableColumnsDnd = ref<ColumnsType>([]);
/**表格状态类型 */
type TabeStateType = {
/**表格列 */
tableColumns: object[];
/**加载等待 */
loading: boolean;
/**紧凑型 */
size: SizeType;
/**搜索栏 */
seached: boolean;
/**记录数据 */
data: object[];
};
/**表格状态 */
let tableState: TabeStateType = reactive({
tableColumns: [],
loading: false,
size: 'middle',
seached: true,
data: [],
});
/**表格分页器参数 */
let tablePagination = reactive({
/**当前页数 */
current: 1,
/**每页条数 */
pageSize: 20,
/**默认的每页条数 */
defaultPageSize: 20,
/**指定每页可以显示多少条 */
pageSizeOptions: ['10', '20', '50', '100'],
/**只有一页时是否隐藏分页器 */
hideOnSinglePage: false,
/**是否可以快速跳转至某页 */
showQuickJumper: true,
/**是否可以改变 pageSize */
showSizeChanger: true,
/**数据总数 */
total: 0,
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
onChange: (page: number, pageSize: number) => {
tablePagination.current = page;
tablePagination.pageSize = pageSize;
queryParams.pageNum = page;
queryParams.pageSize = pageSize;
fnGetList();
},
});
/**表格紧凑型变更操作 */
function fnTableSize({ key }: MenuInfo) {
tableState.size = key as SizeType;
}
/**查询参数 */
let queryParams: any = reactive({
/**已勾选指标 */
goldArr: [],
/**卡片切换Flag */
cardFlag: 0, //0-显示统计图 1-显示统计表
/**告警设备类型 */
neType: '',
/**告警网元标识 */
@@ -46,8 +108,6 @@ type StateType = {
designNeType: string;
/**黄金指标集 tree */
designTreeData: any[];
/**指标勾选集*/
goldArr: any[];
/**表单数据 */
from: Record<string, any>;
};
@@ -57,7 +117,6 @@ let state: StateType = reactive({
neType: [],
designNeType: '',
designTreeData: [],
goldArr: [],
from: {
uploadLoading: false,
sendLoading: false,
@@ -69,15 +128,7 @@ function fnNeChange(keys: any, _: any) {
// 不是同类型时需要重新加载
if (state.designNeType !== keys[0]) {
state.designTreeData = [];
queryRangePicker.value = ['', ''];
queryParams = Object.assign(queryParams, {
/**已勾选指标 */
goldArr: [],
/**颗粒度 */
particle: '',
beginTime: '',
endTime: '',
});
queryParams.cardFlag = 0;
fnGetList();
}
}
@@ -109,6 +160,7 @@ function fnGetList() {
});
}
});
fnDesign();
}
/**根据 key 查找对应的 title */
@@ -117,8 +169,33 @@ function findTitleByKey(key: string): string | undefined {
return item ? item.title : undefined;
}
/**筛选条件进行制图 */
function fnMakeTable(flag: any) {
queryParams.cardFlag = flag;
fnDesign();
}
/**筛选条件进行制图 */
function fnDesign() {
//当前界面是表格界面
const columnsArr = state.designTreeData.map(item => {
return {
title: item.title,
dataIndex: item.key,
align: 'center',
};
});
tableState.tableColumns = columnsArr;
tableState.tableColumns.unshift({
title: t('views.perfManage.perfData.neName'),
dataIndex: 'neName',
align: 'center',
});
tableState.tableColumns.push({
title: t('views.perfManage.goldTarget.time'),
dataIndex: 'timeGroup',
align: 'center',
});
if (!queryRangePicker.value) {
queryRangePicker.value = ['', ''];
}
@@ -127,26 +204,26 @@ function fnDesign() {
const neType = queryParams.neType[0];
let goldXDate: any = [];
let goldYData: any = [];
let hideAllArr: any = [];
goldData(queryParams).then(res => {
console.log(res.data)
if (res.code === RESULT_CODE_SUCCESS) {
if (res.data.length > 0) {
goldXDate = res.data.map((item:any) => item.timeInterval);
tableState.data = res.data;
tablePagination.total = res.data.length;
goldXDate = res.data.map((item: any) => item.timeGroup);
goldYData = Object.keys(res.data[0])
.filter(key => key !== 'timeInterval')
.filter(key => !['timeGroup', 'neName', 'startIndex'].includes(key))
.map(key => {
if (!queryParams.goldArr.includes(key)) hideAllArr[key] = false;
const title = findTitleByKey(key);
if (queryParams.goldArr.includes(key))
return {
name: title,
data: res.data.map((item: any) => parseInt(item[key])),
};
const title: any = findTitleByKey(key);
return {
name: title,
data: res.data.map((item: any) => parseInt(item[key])),
};
});
} else {
tableState.data = [];
tablePagination.total = 0;
state.designTreeData.forEach((item: any) => {
goldYData.push({name:item.title,data:[]});
goldYData.push({ name: item.title, data: [] });
});
message.warning({
content: t('views.perfManage.goldTarget.nullTip'),
@@ -175,7 +252,6 @@ function fnDesign() {
color: '#646A73',
},
icon: 'circle',
selected: hideAllArr,
},
grid: {
left: '10%',
@@ -194,8 +270,9 @@ function fnDesign() {
},
],
};
chartsOption.perfChart = option;
//处理表格数据
} else {
message.warning({
content: t('common.getInfoFail'),
@@ -205,11 +282,6 @@ function fnDesign() {
});
}
/**勾选指标的变动 */
function fnTreeCheck(value: any, _: any) {
queryParams.goldArr = value;
}
onMounted(() => {
// 获取网元网元列表
useNeInfoStore()
@@ -256,11 +328,15 @@ onMounted(() => {
<template>
<PageContainer>
<a-row :gutter="16">
<a-col :span="8">
<!-- 命令导航 -->
<a-card size="small" :bordered="false">
<a-form name="queryParamsFrom" layout="horizontal">
<a-card
v-show="tableState.seached"
:bordered="false"
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
>
<!-- 表格搜索栏 -->
<a-form :model="queryParams" name="queryParamsFrom" layout="horizontal">
<a-row :gutter="16">
<a-col :lg="6" :md="12" :xs="24">
<a-form-item
name="neType"
:label="t('views.traceManage.task.neType')"
@@ -273,7 +349,8 @@ onMounted(() => {
:placeholder="t('common.selectPlease')"
/>
</a-form-item>
</a-col>
<a-col :lg="10" :md="12" :xs="24">
<a-form-item
:label="t('views.perfManage.goldTarget.timeFrame')"
name="eventTime"
@@ -286,65 +363,135 @@ onMounted(() => {
show-time
/>
</a-form-item>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.perfManage.goldTarget.particle')"
name="particle"
>
<a-select
v-model:value="queryParams.particle"
:placeholder="t('common.selectPlease')"
:options="[
{ label: '15M', value: '15' },
{ label: '30M', value: '30' },
{ label: '60M', value: '60' },
]"
/>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item>
<a-space :size="8">
<a-button type="primary" @click.prevent="fnDesign()">
<template #icon><SearchOutlined /></template>
{{ t('common.search') }}
</a-button>
</a-space>
</a-form-item>
</a-col>
</a-row>
</a-form>
<a-form layout="vertical" autocomplete="off">
<a-form-item name="goldTree" v-if="state.designTreeData.length > 0">
<a-directory-tree
:tree-data="state.designTreeData"
checkable
default-expand-all
@check="fnTreeCheck"
></a-directory-tree>
</a-col>
<a-col :lg="4" :md="12" :xs="24">
<a-form-item
:label="t('views.perfManage.goldTarget.particle')"
name="particle"
>
<a-select
v-model:value="queryParams.particle"
:placeholder="t('common.selectPlease')"
:options="[
{ label: '15M', value: '15' },
{ label: '30M', value: '30' },
{ label: '60M', value: '60' },
]"
/>
</a-form-item>
</a-form>
</a-card>
</a-col>
<a-col :span="16">
<a-card :bordered="false" :body-style="{ marginBottom: '24px' }">
<!-- 插槽-卡片左侧侧 -->
<template #title>{{
t('views.perfManage.goldTarget.kpiTitle')
}}</template>
</a-col>
<a-col :lg="2" :md="12" :xs="24">
<a-form-item>
<a-space :size="8">
<a-button type="primary" @click.prevent="fnDesign()">
<template #icon><SearchOutlined /></template>
{{ t('common.search') }}
</a-button>
</a-space>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-card>
<div class="chart">
<ChartLine
:option="chartsOption.perfChart"
:dataZoom="true"
height="400px"
></ChartLine>
</div>
</a-card>
</a-col>
</a-row>
<template v-if="queryParams.cardFlag">
<a-card :bordered="false" :body-style="{ padding: '0px' }">
<!-- 插槽-卡片左侧侧 -->
<template #title>
<a-button type="primary" @click.prevent="fnMakeTable(0)">
<template #icon> <area-chart-outlined /> </template>
{{ t('views.perfManage.goldTarget.kpiTitle') }}
</a-button>
</template>
<!-- 插槽-卡片右侧 -->
<template #extra>
<a-space :size="8" align="center">
<a-tooltip>
<template #title>{{ t('common.searchBarText') }}</template>
<a-switch
v-model:checked="tableState.seached"
:checked-children="t('common.switch.show')"
:un-checked-children="t('common.switch.hide')"
size="small"
/>
</a-tooltip>
<a-tooltip>
<template #title>{{ t('common.reloadText') }}</template>
<a-button type="text" @click.prevent="fnGetList()">
<template #icon><ReloadOutlined /></template>
</a-button>
</a-tooltip>
<TableColumnsDnd
:columns="tableState.tableColumns"
v-model:columns-dnd="tableColumnsDnd"
></TableColumnsDnd>
<a-tooltip>
<template #title>{{ t('common.sizeText') }}</template>
<a-dropdown trigger="click" placement="bottomRight">
<a-button type="text">
<template #icon><ColumnHeightOutlined /></template>
</a-button>
<template #overlay>
<a-menu
:selected-keys="[tableState.size as string]"
@click="fnTableSize"
>
<a-menu-item key="default">
{{ t('common.size.default') }}
</a-menu-item>
<a-menu-item key="middle">
{{ t('common.size.middle') }}
</a-menu-item>
<a-menu-item key="small">
{{ t('common.size.small') }}
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-tooltip>
</a-space>
</template>
<!-- 表格列表 -->
<a-table
class="table"
row-key="id"
:columns="tableColumnsDnd"
:loading="tableState.loading"
:data-source="tableState.data"
:size="tableState.size"
:pagination="tablePagination"
:scroll="{ x: true }"
>
</a-table>
</a-card>
</template>
<a-card :bordered="false" :body-style="{ marginBottom: '24px' }" v-else>
<!-- 插槽-卡片左侧侧 -->
<template #title>{{
t('views.perfManage.goldTarget.kpiTitle')
}}</template>
<!-- 插槽-卡片右侧 -->
<template #extra>
<a-space :size="8" align="center">
<a-button type="default" size="small" @click.prevent="fnMakeTable(1)">
<template #icon>
<ClearOutlined />
</template>
{{ t('views.perfManage.goldTarget.allData') }}
</a-button>
</a-space>
</template>
<div class="chart">
<ChartLine
:option="chartsOption.perfChart"
:dataZoom="true"
height="400px"
></ChartLine>
</div>
</a-card>
</PageContainer>
</template>

View File

@@ -352,14 +352,6 @@ onMounted(() => {
@change="fnTableChange"
:scroll="{ x: true }"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'alarmTitle'">
<a-tooltip>
<template #title>{{ record.operResult }}</template>
<div class="alarmTitleText">{{ record.alarmTitle }}</div>
</a-tooltip>
</template>
</template>
</a-table>
</a-card>
</PageContainer>
@@ -369,8 +361,4 @@ onMounted(() => {
.table :deep(.ant-pagination) {
padding: 0 24px;
}
.alarmTitleText {
max-width: 300px;
cursor: pointer;
}
</style>