Authored by wangtao

故障诊断调整

Showing 33 changed files with 931 additions and 648 deletions
<div>
<div style="padding: 2px 0px 6px 10px">
<div>
{{detailInfo.info}}
</div>
<el-progress :text-inside="true" :stroke-width="26" :percentage="detailInfo.rate*100" :status="detailInfo.rate*100 == 0 ? 'exception' : 'success'">
<span style="color: black">正常占比:{{detailInfo.rate*100}}%</span>
</el-progress>
</div>
<div>
<cm-table-page v-if="list.columns.length > 0" :columns="list.columns"
:dataList="list.dataList"
@loaddata="getPageInfo"
:showIndex="true"
:showBorder="true"
:showPage="false"
:showTools="showDetail"
:maxWidth="width"
size="mini"
:height="300">
<template #tools="{scope}">
<el-button type="text" size="small" @click.prevent="handleClick(scope.row,scope.$index)">
明细
</el-button>
</template>
</cm-table-page>
</div>
<!-- 弹框区域 -->
<!-- 曲线图 -->
<cm-dialog top="3vh" title="曲线图" width="1000px" :showDialogVisible="showLineDialog"
@hidedialog="closeLineDialog" :showFooter="false">
<template v-slot>
<div style="height: 300px" v-if="dataSet.length > 0">
<echarts-line :sourceData="dataSet" height="300px" width="980px" />
</div>
</template>
</cm-dialog>
<!-- 资源明细 -->
<cm-dialog top="3vh" title="资源明细" width="80%" :showDialogVisible="resListDialog"
@hidedialog="showResListDialog" :showFooter="false">
<template v-slot>
<div>
<cm-table-page v-if="resList.columns.length > 0" :columns="resList.columns"
:dataList="resList.dataList"
:showIndex="true"
:showBorder="true"
@loaddata="loadPage"
:showPage="false"
:height="500"
:showTools="false">
</cm-table-page>
</div>
</template>
</cm-dialog>
<!-- 告警列表 -->
<cm-dialog top="3vh" title="告警列表" width="90%" :showDialogVisible="alarmFlg"
@hidedialog="showAlarmDialog" :showFooter="false">
<template v-slot>
<div style="height:720px;max-height:720px;overflow-y: auto;">
<cm-table-page v-if="alarmList.columns.length > 0" :columns="alarmList.columns"
:dataList="alarmList.dataList"
:showIndex="true"
:showBorder="true"
@loaddata="loadPage"
:showPage="false"
:height="720"
:showTools="false">
</cm-table-page>
</div>
</template>
</cm-dialog>
</div>
... ...
/**
* 折线图
* <p>
* 作者: Wang
* 时间:2021/12/15 19:59
*/
const lineDetail = (props) => {
const {proxy} = Vue.getCurrentInstance();
let showLineDialog = Vue.ref(false);
let dataSet = Vue.ref([]);
let closeLineDialog = (flg) => {
showLineDialog.value = flg;
}
let openLine = (row) => {
closeLineDialog(true);
getLineData(row);
}
let getLineData = (row) =>{
let params = {
faultNo: props.faultNo,
targetType: props.targetType,
resId: row.resId,
kpiId: row.kpiId,
flag: row.flag
}
proxy.$http.get('/api-web/fault/result/findLineData', params, function (res) {
if (res && res.success) {
if (res.data) {
let arr = [];
arr.push(['product',res.data[0].resName ]);
res.data.forEach(function (v){
let time = v.collTime;
let val = v.kpiValue;
arr.push([time,val ]);
})
dataSet.value = arr;
}
} else {
proxy.$global.showMsg(res.msg, "warning");
}
});
}
return {
showLineDialog,
closeLineDialog,
openLine,
dataSet
}
}
/**
* 告警列表
* <p>
* 作者: Wang
* 时间:2021/12/15 19:59
*/
const alarmDialog = (props) => {
const {proxy} = Vue.getCurrentInstance();
let alarmFlg = Vue.ref(false);
let alarmList = Vue.ref({
columns: [{
prop: "resId",
label: "资源ID",
width:120
}, {
prop: "kpiId",
label: "指标ID",
width:120
}, {
prop: "flag",
label: "指标标识",
width:120
}, {
prop: "alarmId",
label: "告警ID",
width:120
},{
prop: "alarmContent",
label: "告警内容",
width:250
}, {
prop: "firstAlarmTime",
label: "首次告警时间",
width:120
}, {
prop: "recentAlarmTime",
label: "最近告警时间",
width:120
}, {
prop: "alarmRepeatCnt",
label: "告警次数",
width:80
}, {
prop: "noticeContent",
label: "通知内容",
width:300
}, {
prop: "alarmLevel",
label: "告警级别",
width:80,
render: function (row) {
let obj = proxy.$global.getAlarmLevel(row.alarmLevel);
if (obj) {
return `<span style="color: ${obj.color}">${obj.name}</span>`
}
return '';
}
}/*, {
prop: "firstAlarmTime",
label: "时间戳",
}*/],
dataList: [],
total: 0
});
let showAlarmDialog = (flg) => {
alarmFlg.value = flg;
}
let openAlarmDialog = (row) => {
showAlarmDialog(true);
// 获取告警列表
let params ={
faultNo: props.faultNo,
targetType: props.targetType,
resId: row.resId,
kpiId: row.kpiId,
flag: row.flg
}
proxy.$http.get(`/api-web/fault/result/findAlarmList`, params, function (res) {
if (res && res.success) {
if (res.data) {
alarmList.value.dataList = res.data;
}
} else {
proxy.$global.showMsg(res.msg ? res.msg : '暂无告警数据!', "warning");
}
});
}
return {
showAlarmDialog,
openAlarmDialog,
alarmList,
alarmFlg
}
}
/**
* 数据转换
* <p>
* 作者: Wang
* 时间:2021/12/15 18:08
*/
const colTypes = (props, list,openLine,openAlarmDialog) => {
let widths ={
errcode:150
}
// 展示折线图指标
let lineKpiIds = ['point_succ', 'count', 'response_rate', 'success_rate'];
/**
* 拨测
* @param row
* @returns {`<span style="${string}">${string}</span>`}
*/
let point_succ = (val) =>{
let css = "text-decoration: underline;";
if(val != undefined && val === 0){
css += "color: red;";
} else {
css += "color: blue;";
}
return `<span style="${css}">${val}</span>`;
}
/**
* NPM 成功率
* @param row
* @returns {`<span style="${string}">${string}</span>`}
*/
let success_rate = (val) =>{
let css = "text-decoration: underline;";
if(val != undefined && val === 100){
css += "color: blue;";
} else {
css += "color: red;";
}
return `<span style="${css}">${val}</span>`;
}
/**
* NPM 响应率
* @param row
* @returns {`<span style="${string}">${string}</span>`}
*/
let response_rate = (val) =>{
let css = "text-decoration: underline;";
if(val != undefined && val === 100){
css += "color: blue;";
} else {
css += "color: red;";
}
return `<span style="${css}">${val}</span>`;
}
let getItem = (v) => {
let item = {};
item.resId = v.resId;
item.resName = v.resName;
item.kpiName = v.kpiName;
item.bizId = v.bizId;
item.bizName = v.bizName;
item.kpiId = v.kpiId;
item.flag = v.flag;
return item;
}
/**
* KPI数据处理方式
* <p>
* 作者: Wang
* 时间:2021/12/15 16:12
*/
let dataTypeByKpi = (data) => {
let dataList = [];
let col = [{
prop: 'resName',
label: props.itemName,
width: 150
}];
let index = 0;
for (let resId in data) {
let list = data[resId];
let item = getItem(list[0]);
list.forEach(function (v) {
item[v.kpiId] = v.kpiValue;
item.kpiName = v.kpiName;
if (index == 0) {
let prop = v.kpiId;
let colInfo = {
prop: prop,
label: v.kpiName,
width: widths[prop] == undefined ? 50 : 100
};
if (lineKpiIds.indexOf(prop) != -1) {
colInfo['click'] = function (row) {
row.kpiId = prop;
row.flag = v.flag;
openLine(row);
}
colInfo['render'] = function (row) {
try {
if(row && Object.keys(row).length > 0 && prop){
let html = eval(prop + '(' + row[prop] + ')');
if(html){
return html;
}
}
}catch (e){
}
return `<span style="text-decoration: underline;color: blue;">${row[v.kpiId]}</span>`;;
}
}
col.push(colInfo)
}
});
dataList.push(item);
index++;
}
// 设置数据
list.value.dataList = dataList;
list.value.columns = col;
}
/**
* KPI数据处理方式
* <p>
* 作者: Wang
* 时间:2021/12/15 16:12
*/
let dataTypeByFlag = (data) => {
let flags = [{
prop: "count",
width:80,
label: "检测项目数",
}, {
prop: "normal",
width:80,
label: "正常数",
render: function (row) {
return `<span >${row.normal == undefined ? 0 : row.normal }</span>`
}
}, {
prop: "abnormal",
width:80,
label: "异常出",
render: function (row) {
return `<span >${row.abnormal == undefined ? 0 : row.abnormal }</span>`
}
}, {
prop: "alarm",
width:80,
label: "告警",
click: function (row) {
openAlarmDialog(row);
},
render: function (row) {
return `<span style="text-decoration: underline;color: blue;">${row.alarm == undefined ? 0 : row.alarm }</span>`
}
}];
let dataList = [];
let col = [{
prop: 'kpiName',
label: props.itemName,
width: 150
}];
flags.forEach(function (item) {
col.push(item)
})
let index = 0;
for (let resId in data) {
let list = data[resId];
let item = getItem(list[0]);
list.forEach(function (v) {
item[v.flag] = v.kpiValue;
});
dataList.push(item);
index++;
}
// 设置数据
list.value.dataList = dataList;
list.value.columns = col;
}
return {dataTypeByKpi, dataTypeByFlag}
}
const resDetail = (props,openLine) => {
const {proxy} = Vue.getCurrentInstance();
let resListDialog = Vue.ref(false);
let resList = Vue.ref({
columns: [{
prop: "resType",
label: "资源类型",
}, {
prop: "resName",
label: "资源名称",
}, {
prop: "kpiName",
label: "指标名称",
}, {
prop: "kpiValue",
label: "指标值",
click:function (row){
openLine(row);
},
render:function (row){
return `<span style="text-decoration: underline;color: blue;">${row.kpiValue}</span>`
}
}, {
prop: "collTime",
label: "采集时间",
}],
dataList: [],
total: 0
});
let showResListDialog = (flg) => {
resListDialog.value = flg;
}
let handleClick = (row, index) => {
showResListDialog(true);
getResListPage(row);
}
let getResListPage = (row) => {
let params = {
faultNo: props.faultNo,
targetType: props.targetType,
resId: row.resId,
kpiId: row.kpiId,
flag: row.flag
}
proxy.$http.get('/api-web/fault/result/findResList', params, function (res) {
if (res && res.success) {
if (res.data) {
resList.value.dataList = res.data;
}
} else {
proxy.$global.showMsg(res.msg, "warning");
}
});
}
let loadPage = () => {
}
return {
resList,
resListDialog,
showResListDialog,
getResListPage,
loadPage,
handleClick
}
}
export default {
name: 'resultItemIndex',
template: '',
components: {
'echarts-line': Vue.defineAsyncComponent(
() => myImport('components/common/echarts/line/index')
)
},
data() {
return {}
},
props: {
targetType: {
type: String,
default: ''
},
faultNo: {
type: String,
default: ''
},
itemName: {
type: String,
default: ''
},
// 展示详情页
showDetail: {
type: String,
default: ''
},
// 数据转行方式
colType: {
type: String,
default: 'kpi'
},
},
setup(props, {attrs, slots, emit}) {
let width = Vue.ref(window.innerWidth * 0.8 - 220);
const {proxy} = Vue.getCurrentInstance();
let list = Vue.ref({
columns: [],
dataList: [],
total: 0
});
let detailInfo = Vue.ref({
rate: 0,
info: ''
});
const {
showLineDialog,
closeLineDialog,
openLine,
dataSet
} = lineDetail(props);
const {
resList,
resListDialog,
showResListDialog,
getResListPage,
loadPage,
handleClick
} = resDetail(props,openLine);
const {
showAlarmDialog,
openAlarmDialog,
alarmList,
alarmFlg
} = alarmDialog(props);
// 数据统计方式
const {dataTypeByKpi, dataTypeByFlag} = colTypes(props, list,openLine,openAlarmDialog);
/**
* 获取表格数据
* <p>
* 作者: Wang
* 时间:2021/12/15 17:26
*/
let getPage = () => {
let params = {
faultNo: props.faultNo,
targetType: props.targetType
}
proxy.$http.get('/api-web/fault/result/findResult', params, function (res) {
if (res && res.success) {
if (res.map) {
callback(res.map);
}
} else {
proxy.$global.showMsg(res.msg, "warning");
}
});
// 设置数据
let callback = (data) => {
switch (props.colType) {
case 'kpi':
dataTypeByKpi(data);
break;
case 'flag':
dataTypeByFlag(data);
break;
}
}
}
/**
* 获取统计信息
*/
let findCountInfo = () => {
let params = {
faultNo: props.faultNo,
targetType: props.targetType
}
proxy.$http.get('/api-web/fault/result/findCountInfo', params, function (res) {
if (res && res.success) {
if (res.map) {
detailInfo.value = res.map;
}
} else {
proxy.$global.showMsg(res.msg, "warning");
}
});
}
// 监听编辑状态
Vue.watch(() => props.faultNo, (newValue, oldVlaue) => {
getPage();
});
// 挂载完
Vue.onMounted(() => {
getPage();
findCountInfo();
})
return {
width,
list,
detailInfo,
// 折线图
showLineDialog,
closeLineDialog,
openLine,
dataSet,
// 资源详情
resList,
resListDialog,
showResListDialog,
getResListPage,
loadPage,
handleClick,
// 告警弹框
showAlarmDialog,
openAlarmDialog,
alarmList,
alarmFlg
}
}
}
... ...
<div>
<div style="padding: 2px 0px 6px 10px">
<div>
{{detailInfo.info}}
<div class="d-flex">
<img src="../src/style/img/fault/base.gif">
<h3 style="margin-left: 10px">基础资源</h3>
<div style="width: calc(100% - 200px);line-height: 54px" class="align-right">
<a class="m-r-20" @click="allCard()">更多</a>
<a @click="closeCard()">收起</a>
</div>
<el-progress :text-inside="true" :stroke-width="26" :percentage="detailInfo.rate*100" :status="detailInfo.rate*100 == 0 ? 'exception' : 'success'">
<span style="color: black">正常占比:{{detailInfo.rate*100}}%</span>
</el-progress>
</div>
<div>
<cm-table-page v-if="list.columns.length > 0" :columns="list.columns"
:dataList="list.dataList"
@loaddata="getPageInfo"
:showIndex="true"
:showBorder="true"
:showPage="false"
:showTools="showDetail"
:maxWidth="width"
size="mini"
:height="300">
<template #tools="{scope}">
<el-button type="text" size="small" @click.prevent="handleClick(scope.row,scope.$index)">
明细
</el-button>
</template>
</cm-table-page>
<el-divider/>
<div class="d-flex" v-model="dialTest">
<div style="width: 300px;text-align: center;"><a>汇总信息</a></div>
<div>
<div class="d-flex align-left">
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;">
<img src="../src/style/img/disRes.png">
<span style="margin: 0px 6px 0px 6px;width: 95px">诊断资源</span>
<h>{{dialTest && dialTest.diagnosticResources ?dialTest.diagnosticResources:0}}</h>
</div>
|
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;">
<img src="../src/style/img/disKpi.png">
<span style="margin: 0px 6px 0px 6px;width: 95px">诊断指标</span>
<h>{{dialTest && dialTest.diagnosticIndicators ?dialTest.diagnosticIndicators:0}}</h>
</div>
|
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;">
<img src="../src/style/img/disItem.png">
<span style="margin: 0px 6px 0px 6px;width: 95px">诊断项</span>
<h>{{dialTest && dialTest.diagnosticItem ?dialTest.diagnosticItem:0}}</h>
</div>
</div>
<div style="text-align: left;display: flex;margin-top: 10px;">
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;color: yellowgreen">
<img src="../src/style/img/success.png">
<span style="margin: 0px 6px 0px 6px;width: 95px;">正常</span>
<h style="font-size: 20px">{{dialTest && dialTest.normal ?dialTest.normal:0}}</h>
</div>
|
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;color: #f8d305">
<img src="../src/style/img/error.png">
<span style="margin: 0px 6px 0px 6px;width: 95px;"> 异常</span>
<h style="font-size: 20px">{{dialTest && dialTest.abnormal ?dialTest.abnormal:0}}</h>
</div>
</div>
</div>
<div class="d-flex" style="flex: 1">
<div>正常占比</div>
<div class="progress-con">
<el-progress :text-inside="true" :stroke-width="26"
:percentage="dialTest && dialTest.normalProportion?dialTest.normalProportion*100:0"
color="#64A64C"/>
</div>
</div>
</div>
<!-- 弹框区域 -->
<!-- 曲线图 -->
<cm-dialog top="3vh" title="曲线图" width="1000px" :showDialogVisible="showLineDialog"
@hidedialog="closeLineDialog" :showFooter="false">
<template v-slot>
<div style="height: 300px" v-if="dataSet.length > 0">
<echarts-line :sourceData="dataSet" height="300px" width="980px" />
</div>
</template>
</cm-dialog>
<!-- 资源明细 -->
<cm-dialog top="3vh" title="资源明细" width="80%" :showDialogVisible="resListDialog"
@hidedialog="showResListDialog" :showFooter="false">
<template v-slot>
<div>
<cm-table-page v-if="resList.columns.length > 0" :columns="resList.columns"
:dataList="resList.dataList"
:showIndex="true"
:showBorder="true"
@loaddata="loadPage"
:showPage="false"
:height="500"
:showTools="false">
</cm-table-page>
</div>
</template>
</cm-dialog>
<res-item />
<!-- 告警列表 -->
<cm-dialog top="3vh" title="告警列表" width="90%" :showDialogVisible="alarmFlg"
@hidedialog="showAlarmDialog" :showFooter="false">
<template v-slot>
<div style="height:720px;max-height:720px;overflow-y: auto;">
<cm-table-page v-if="alarmList.columns.length > 0" :columns="alarmList.columns"
:dataList="alarmList.dataList"
:showIndex="true"
:showBorder="true"
@loaddata="loadPage"
:showPage="false"
:height="720"
:showTools="false">
</cm-table-page>
</div>
</template>
</cm-dialog>
</div>
... ...
/**
* 折线图
* <p>
* 作者: Wang
* 时间:2021/12/15 19:59
*/
const lineDetail = (props) => {
const {proxy} = Vue.getCurrentInstance();
let showLineDialog = Vue.ref(false);
let dataSet = Vue.ref([]);
let closeLineDialog = (flg) => {
showLineDialog.value = flg;
}
let openLine = (row) => {
closeLineDialog(true);
getLineData(row);
}
let getLineData = (row) =>{
let params = {
faultNo: props.faultNo,
targetType: props.targetType,
resId: row.resId,
kpiId: row.kpiId,
flag: row.flag
}
proxy.$http.get('/api-web/fault/result/findLineData', params, function (res) {
if (res && res.success) {
if (res.data) {
let arr = [];
arr.push(['product',res.data[0].resName ]);
res.data.forEach(function (v){
let time = v.collTime;
let val = v.kpiValue;
arr.push([time,val ]);
})
dataSet.value = arr;
}
} else {
proxy.$global.showMsg(res.msg, "warning");
}
});
}
return {
showLineDialog,
closeLineDialog,
openLine,
dataSet
}
}
/**
* 告警列表
* <p>
* 作者: Wang
* 时间:2021/12/15 19:59
*/
const alarmDialog = (props) => {
const {proxy} = Vue.getCurrentInstance();
let alarmFlg = Vue.ref(false);
let alarmList = Vue.ref({
columns: [{
prop: "resId",
label: "资源ID",
width:120
}, {
prop: "kpiId",
label: "指标ID",
width:120
}, {
prop: "flag",
label: "指标标识",
width:120
}, {
prop: "alarmId",
label: "告警ID",
width:120
},{
prop: "alarmContent",
label: "告警内容",
width:250
}, {
prop: "firstAlarmTime",
label: "首次告警时间",
width:120
}, {
prop: "recentAlarmTime",
label: "最近告警时间",
width:120
}, {
prop: "alarmRepeatCnt",
label: "告警次数",
width:80
}, {
prop: "noticeContent",
label: "通知内容",
width:300
}, {
prop: "alarmLevel",
label: "告警级别",
width:80,
render: function (row) {
let obj = proxy.$global.getAlarmLevel(row.alarmLevel);
if (obj) {
return `<span style="color: ${obj.color}">${obj.name}</span>`
}
return '';
}
}/*, {
prop: "firstAlarmTime",
label: "时间戳",
}*/],
dataList: [],
total: 0
});
let showAlarmDialog = (flg) => {
alarmFlg.value = flg;
}
let openAlarmDialog = (row) => {
showAlarmDialog(true);
// 获取告警列表
let params ={
faultNo: props.faultNo,
targetType: props.targetType,
resId: row.resId,
kpiId: row.kpiId,
flag: row.flg
}
proxy.$http.get(`/api-web/fault/result/findAlarmList`, params, function (res) {
if (res && res.success) {
if (res.data) {
alarmList.value.dataList = res.data;
}
} else {
proxy.$global.showMsg(res.msg ? res.msg : '暂无告警数据!', "warning");
}
});
}
return {
showAlarmDialog,
openAlarmDialog,
alarmList,
alarmFlg
}
}
/**
* 数据转换
* <p>
* 作者: Wang
* 时间:2021/12/15 18:08
*/
const colTypes = (props, list,openLine,openAlarmDialog) => {
let widths ={
errcode:150
}
// 展示折线图指标
let lineKpiIds = ['point_succ', 'count', 'response_rate', 'success_rate'];
/**
* 拨测
* @param row
* @returns {`<span style="${string}">${string}</span>`}
*/
let point_succ = (val) =>{
let css = "text-decoration: underline;";
if(val != undefined && val === 0){
css += "color: red;";
} else {
css += "color: blue;";
}
return `<span style="${css}">${val}</span>`;
}
/**
* NPM 成功率
* @param row
* @returns {`<span style="${string}">${string}</span>`}
*/
let success_rate = (val) =>{
let css = "text-decoration: underline;";
if(val != undefined && val === 100){
css += "color: blue;";
} else {
css += "color: red;";
}
return `<span style="${css}">${val}</span>`;
}
/**
* NPM 响应率
* @param row
* @returns {`<span style="${string}">${string}</span>`}
*/
let response_rate = (val) =>{
let css = "text-decoration: underline;";
if(val != undefined && val === 100){
css += "color: blue;";
} else {
css += "color: red;";
}
return `<span style="${css}">${val}</span>`;
}
let getItem = (v) => {
let item = {};
item.resId = v.resId;
item.resName = v.resName;
item.kpiName = v.kpiName;
item.bizId = v.bizId;
item.bizName = v.bizName;
item.kpiId = v.kpiId;
item.flag = v.flag;
return item;
}
/**
* KPI数据处理方式
* <p>
* 作者: Wang
* 时间:2021/12/15 16:12
*/
let dataTypeByKpi = (data) => {
let dataList = [];
let col = [{
prop: 'resName',
label: props.itemName,
width: 150
}];
let index = 0;
for (let resId in data) {
let list = data[resId];
let item = getItem(list[0]);
list.forEach(function (v) {
item[v.kpiId] = v.kpiValue;
item.kpiName = v.kpiName;
if (index == 0) {
let prop = v.kpiId;
let colInfo = {
prop: prop,
label: v.kpiName,
width: widths[prop] == undefined ? 50 : 100
};
if (lineKpiIds.indexOf(prop) != -1) {
colInfo['click'] = function (row) {
row.kpiId = prop;
row.flag = v.flag;
openLine(row);
}
colInfo['render'] = function (row) {
try {
if(row && Object.keys(row).length > 0 && prop){
let html = eval(prop + '(' + row[prop] + ')');
if(html){
return html;
}
}
}catch (e){
}
return `<span style="text-decoration: underline;color: blue;">${row[v.kpiId]}</span>`;;
}
}
col.push(colInfo)
}
});
dataList.push(item);
index++;
}
// 设置数据
list.value.dataList = dataList;
list.value.columns = col;
}
/**
* KPI数据处理方式
* <p>
* 作者: Wang
* 时间:2021/12/15 16:12
*/
let dataTypeByFlag = (data) => {
let flags = [{
prop: "count",
width:80,
label: "检测项目数",
}, {
prop: "normal",
width:80,
label: "正常数",
render: function (row) {
return `<span >${row.normal == undefined ? 0 : row.normal }</span>`
}
}, {
prop: "abnormal",
width:80,
label: "异常出",
render: function (row) {
return `<span >${row.abnormal == undefined ? 0 : row.abnormal }</span>`
}
}, {
prop: "alarm",
width:80,
label: "告警",
click: function (row) {
openAlarmDialog(row);
},
render: function (row) {
return `<span style="text-decoration: underline;color: blue;">${row.alarm == undefined ? 0 : row.alarm }</span>`
}
}];
let dataList = [];
let col = [{
prop: 'kpiName',
label: props.itemName,
width: 150
}];
flags.forEach(function (item) {
col.push(item)
})
let index = 0;
for (let resId in data) {
let list = data[resId];
let item = getItem(list[0]);
list.forEach(function (v) {
item[v.flag] = v.kpiValue;
});
dataList.push(item);
index++;
}
// 设置数据
list.value.dataList = dataList;
list.value.columns = col;
}
return {dataTypeByKpi, dataTypeByFlag}
}
const resDetail = (props,openLine) => {
const {proxy} = Vue.getCurrentInstance();
let resListDialog = Vue.ref(false);
let resList = Vue.ref({
columns: [{
prop: "resType",
label: "资源类型",
}, {
prop: "resName",
label: "资源名称",
}, {
prop: "kpiName",
label: "指标名称",
}, {
prop: "kpiValue",
label: "指标值",
click:function (row){
openLine(row);
},
render:function (row){
return `<span style="text-decoration: underline;color: blue;">${row.kpiValue}</span>`
}
}, {
prop: "collTime",
label: "采集时间",
}],
dataList: [],
total: 0
});
let showResListDialog = (flg) => {
resListDialog.value = flg;
}
let handleClick = (row, index) => {
showResListDialog(true);
getResListPage(row);
}
let getResListPage = (row) => {
let params = {
faultNo: props.faultNo,
targetType: props.targetType,
resId: row.resId,
kpiId: row.kpiId,
flag: row.flag
}
proxy.$http.get('/api-web/fault/result/findResList', params, function (res) {
if (res && res.success) {
if (res.data) {
resList.value.dataList = res.data;
}
} else {
proxy.$global.showMsg(res.msg, "warning");
}
});
}
let loadPage = () => {
}
return {
resList,
resListDialog,
showResListDialog,
getResListPage,
loadPage,
handleClick
}
}
import store from '/vue3/src/store/index.js';
export default {
name: 'resultItemIndex',
name: 'faultDialTest',
template: '',
components: {
'echarts-line': Vue.defineAsyncComponent(
() => myImport('components/common/echarts/line/index')
)
},
data() {
return {}
'res-item': Vue.defineAsyncComponent(
() => myImport('components/page/faultDiagnosis/result/item/resItem/index')
),
},
props: {
targetType: {
type: String,
default: ''
},
faultNo: {
type: String,
default: ''
},
itemName: {
type: String,
default: ''
},
// 展示详情页
showDetail: {
type: String,
default: ''
},
// 数据转行方式
colType: {
type: String,
default: 'kpi'
},
}
},
data() {
return {}
},
setup(props, {attrs, slots, emit}) {
let width = Vue.ref(window.innerWidth * 0.8 - 220);
const {proxy} = Vue.getCurrentInstance();
let list = Vue.ref({
columns: [],
dataList: [],
total: 0
});
let detailInfo = Vue.ref({
rate: 0,
info: ''
});
const {
showLineDialog,
closeLineDialog,
openLine,
dataSet
} = lineDetail(props);
const {
resList,
resListDialog,
showResListDialog,
getResListPage,
loadPage,
handleClick
} = resDetail(props,openLine);
const {
showAlarmDialog,
openAlarmDialog,
alarmList,
alarmFlg
} = alarmDialog(props);
// 数据统计方式
const {dataTypeByKpi, dataTypeByFlag} = colTypes(props, list,openLine,openAlarmDialog);
/**
* 获取表格数据
* <p>
* 作者: Wang
* 时间:2021/12/15 17:26
*/
let getPage = () => {
let params = {
faultNo: props.faultNo,
targetType: props.targetType
}
proxy.$http.get('/api-web/fault/result/findResult', params, function (res) {
if (res && res.success) {
if (res.map) {
callback(res.map);
}
} else {
proxy.$global.showMsg(res.msg, "warning");
}
});
// 设置数据
let callback = (data) => {
switch (props.colType) {
case 'kpi':
dataTypeByKpi(data);
break;
case 'flag':
dataTypeByFlag(data);
break;
}
}
let dialTest = Vue.ref();
let card = Vue.ref({})
let cardOpen = Vue.ref(false);
let allCard = () => {
cardOpen.value = true;
}
/**
* 获取统计信息
*/
let findCountInfo = () => {
let closeCard = () => {
cardOpen.value = false;
}
let getDialtestList = () => {
let params = {
faultNo: props.faultNo,
targetType: props.targetType
targetType: "dialtest"
}
proxy.$http.get('/api-web/fault/result/findCountInfo', params, function (res) {
if (res && res.success) {
if (res.map) {
detailInfo.value = res.map;
}
} else {
proxy.$global.showMsg(res.msg, "warning");
store.dispatch('getFaultList', params).then((res) => {
if (res.data && res.success) {
dialTest.value = res.data[0];
card.value = dialTest.value.faultFixInfoList[0];
}
});
}).catch(e => {
console.log(e);
})
}
// 监听编辑状态
Vue.watch(() => props.faultNo, (newValue, oldVlaue) => {
getPage();
});
// 挂载完
Vue.onMounted(() => {
getPage();
findCountInfo();
getDialtestList();
})
return {
width,
list,
detailInfo,
// 折线图
showLineDialog,
closeLineDialog,
openLine,
dataSet,
// 资源详情
resList,
resListDialog,
showResListDialog,
getResListPage,
loadPage,
handleClick,
// 告警弹框
showAlarmDialog,
openAlarmDialog,
alarmList,
alarmFlg
card,
allCard,
closeCard,
cardOpen,
dialTest
}
}
}
... ...
<el-divider/>
<div class="d-flex" v-model="dialTest">
<div class="d-flex align-center" style="width: 300px;justify-content: center;">
<span style="width: 10px;height: 10px;background-color: red;border-radius: 50%">&nbsp;</span>
<img class="m-l-6" src="../src/style/img/fault/base/resType/数据库.png">
<a class="m-l-6">数据库</a>
</div>
<div>
<div class="d-flex align-left">
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;">
<img src="../src/style/img/disRes.png">
<span style="margin: 0px 6px 0px 6px;width: 95px">诊断资源</span>
<h>{{dialTest && dialTest.diagnosticResources ?dialTest.diagnosticResources:0}}</h>
</div>
|
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;">
<img src="../src/style/img/disKpi.png">
<span style="margin: 0px 6px 0px 6px;width: 95px">诊断指标</span>
<h>{{dialTest && dialTest.diagnosticIndicators ?dialTest.diagnosticIndicators:0}}</h>
</div>
|
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;">
<img src="../src/style/img/disItem.png">
<span style="margin: 0px 6px 0px 6px;width: 95px">诊断项</span>
<h>{{dialTest && dialTest.diagnosticItem ?dialTest.diagnosticItem:0}}</h>
</div>
</div>
<div style="text-align: left;display: flex;margin-top: 10px;">
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;color: yellowgreen">
<img src="../src/style/img/success.png">
<span style="margin: 0px 6px 0px 6px;width: 95px;">正常</span>
<h style="font-size: 20px">{{dialTest && dialTest.normal ?dialTest.normal:0}}</h>
</div>
|
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;color: #f8d305">
<img src="../src/style/img/error.png">
<span style="margin: 0px 6px 0px 6px;width: 95px;"> 异常</span>
<h style="font-size: 20px">{{dialTest && dialTest.abnormal ?dialTest.abnormal:0}}</h>
</div>
|
<div style="width: 200px;margin-left: 20px;display: flex;align-self: center;color: red">
<img src="../src/style/img/fault/base/alarm.png">
<span style="margin: 0px 6px 0px 6px;width: 95px;"> 告警</span>
<h style="font-size: 20px">{{dialTest && dialTest.abnormal ?dialTest.abnormal:0}}</h>
</div>
</div>
</div>
<div class="align-center" style="flex: 1">
<a class="m-r-20" @click="allCard()">更多</a>
<a @click="closeCard()">收起</a>
</div>
</div>
<div v-if="cardOpen"
style="margin-top: 10px;background-color: whitesmoke;display: flex;justify-content: flex-start;flex-wrap: wrap;padding: 6px;">
<div v-for="item in 10" style="width: 25%">
<div style="min-width: 338px;height: 160px;background: url(../src/style/img/fault/base/bg.png) no-repeat;background-size: 100% 100%;padding-top: 10px;">
<el-row style="height: 70px;padding: 10px 30px;">
<el-col :span="4" style="line-height: 55px;">
<img src="../src/style/img/fault/base/基础-数据库-黄.png">
</el-col>
<el-col :span="16">
资源名称xxxxxx<br>
127.0.0.0.111111
</el-col>
<el-col :span="4">
<i class="iconfont">more</i>
</el-col>
</el-row>
<el-row style="height: 70px;padding: 10px 30px;">
<el-col :span="4">
<img src="../src/style/img/fault/base/连接失败.png">
</el-col>
<el-col :span="1" style="line-height: 36px">
|
</el-col>
<el-col :span="4">
<img src="../src/style/img/fault/base/CPU-绿.png"><br/>
21%
</el-col>
<el-col :span="1" style="line-height: 36px">
|
</el-col>
<el-col :span="4">
<img src="../src/style/img/fault/base/内存.png"><br/>
21%
</el-col>
<el-col :span="1" style="line-height: 36px">
|
</el-col>
<el-col :span="4">
<img src="../src/style/img/fault/base/alarm.png"><br/>
21%
</el-col>
<el-col :span="1" style="line-height: 36px">
|
</el-col>
<el-col :span="4">
<img src="../src/style/img/fault/base/时间-绿.png"><br/>
30分钟
</el-col>
</el-row>
</div>
</div>
</div>
... ...
import store from '/vue3/src/store/index.js';
export default {
name: 'faultDialTest',
template: '',
components: {},
props: {
faultNo: {
type: String,
default: ''
}
},
data() {
return {}
},
setup(props, {attrs, slots, emit}) {
const {proxy} = Vue.getCurrentInstance();
let dialTest = Vue.ref();
let card = Vue.ref({})
let cardOpen = Vue.ref(false);
let allCard = () => {
cardOpen.value = true;
}
let closeCard = () => {
cardOpen.value = false;
}
let getDialtestList = () => {
let params = {
faultNo: props.faultNo,
targetType: "dialtest"
}
store.dispatch('getFaultList', params).then((res) => {
if (res.data && res.success) {
dialTest.value = res.data[0];
card.value = dialTest.value.faultFixInfoList[0];
}
}).catch(e => {
console.log(e);
})
}
// 挂载完
Vue.onMounted(() => {
getDialtestList();
})
return {
card,
allCard,
closeCard,
cardOpen,
dialTest
}
}
}
... ...
... ... @@ -2,9 +2,9 @@ export default {
name: 'resIndex',
template: '',
components: {
// 'result-item': Vue.defineAsyncComponent(
// () => myImport('components/page/faultDiagnosis/result/item/index')
// ),
'result-item': Vue.defineAsyncComponent(
() => myImport('components/page/faultDiagnosis/result/item/index')
),
'dialtest-item': Vue.defineAsyncComponent(
() => myImport('components/page/faultDiagnosis/result/dialtest/index')
),
... ... @@ -29,7 +29,7 @@ export default {
components: 'netLinks',
color: '#409EFF',
detail:true,
state:'1'
state:'0'
},{
faultType: 'DIALTEST',
faultTypeName: '拨测',
... ... @@ -38,7 +38,7 @@ export default {
itemName: '场景名称',
detail: false,
colType: 'kpi',
state:'1'
state:'0'
}, {
faultType: 'NPM',
faultTypeName: 'NPM',
... ... @@ -47,7 +47,7 @@ export default {
itemName: '链路(流名称)',
detail: false,
colType: 'kpi',
state:'1'
state:'0'
}, {
faultType: 'BASE',
faultTypeName: '基础',
... ... @@ -56,7 +56,7 @@ export default {
itemName: '检测指标',
detail: true,
colType: 'flag',
state:'1'
state:'0'
}, {
faultType: 'APM',
faultTypeName: 'APM',
... ... @@ -65,7 +65,7 @@ export default {
itemName: '检测指标',
detail: true,
colType: 'flag',
state:'1'
state:'0'
}, {
faultType: 'faultHis',
faultTypeName: '知识库',
... ... @@ -74,7 +74,7 @@ export default {
itemName: '知识库',
detail: true,
colType: 'flag',
state:'1'
state:'0'
}]
});
... ...