NEZ-2550 feat: endpoint 故障诊断页面开发

This commit is contained in:
likexuan
2023-02-13 17:33:35 +08:00
parent 0b940fd2ba
commit 057c042282
14 changed files with 416 additions and 16 deletions

View File

@@ -0,0 +1,106 @@
#diagnosisTab{
.el-dialog__header{
padding: 16px 20px;
.el-dialog__title{
font-size: 14px;
font-weight: 600;
}
border-bottom: 1px solid $--border-color-light;
}
.el-dialog__body{
padding: 0;
.dialog-header{
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 30px;
padding-right: 38px;
border-bottom: 1px solid $--border-color-light;
background: $--background-color-base;
font-size: 12px;
color:$--color-text-regular;
.dialog-header-l{
display: flex;
justify-content: start;
align-items: center;
i.nz-icon{
font-size: 72px;
color: #AEB8C2;
margin-right: 11px;
}
.dialog-header-name{
font-size: 14px;
letter-spacing: 0;
line-height: 22px;
font-weight: 600;
margin-bottom: 4px;
}
.dialog-header-item{
text-transform: uppercase;
color: $--color-text-secondary;
span{
margin-right: 10px;
}
}
}
}
.diagnosis-table{
padding-left: 20px;
#diagnosisTable{
&::before{
display: none;
}
.has-gutter{
display: none;
}
.el-table__expand-icon{
transform: rotate(90deg);
}
.el-table__expand-icon--expanded{
color: $--color-primary;
transform: rotate(270deg);
}
td.el-table__expanded-cell {
padding: 15px 0 15px 45px;
background-color: $--background-color-empty !important;
}
td.el-table__expanded-cell:hover {
padding: 15px 0 15px 45px;
background-color: $--background-color-base !important;
}
.expand-details{
color: $--color-primary;
}
.el-table__body {
tr{
background: $--background-color-empty;
td{
border-color: $--border-color-light;
}
&:nth-last-of-type(1){
td{
border-color: transparent;
}
}
}
}
&.el-table--enable-row-hover .el-table__body tr:hover>td{
background-color: $--background-color-base !important;
}
}
}
.my-loading-box{
opacity: 1 !important;
}
}
.el-dialog__footer{
border-top: 1px solid $--border-color-light;
padding: 13px 20px;
margin-top: 0;
#diagnosis-cancel{
padding: 0 11px;
margin-right: 0;
font-weight: 600;
}
}
}

View File

@@ -86,6 +86,7 @@
@import './common/searchInput.scss';
@import './common/timePicker.scss';
@import './common/deleteButton.scss';
@import './common/diagnosisTab.scss';
@import './common/filterSearch/filterSearch.scss';
@import './common/panel/panelVariables.scss';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -6,7 +6,13 @@
"description": "",
"glyphs": [
{
<<<<<<< HEAD
"icon_id": "34053254",
"name": "编组 2",
"font_class": "Diagnosis1",
"unicode": "e7d1",
"unicode_decimal": 59345
},
{
"icon_id": "33998082",
"name": "右纵轴",
"font_class": "youzongzhou",
@@ -21,8 +27,6 @@
"unicode_decimal": 59343
},
{
=======
>>>>>>> 61106c08d5bd1c9b7263e6b915880385934c3c7d
"icon_id": "33991102",
"name": "全部收起",
"font_class": "quanbushouqi",

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,238 @@
<template>
<div>
<el-dialog
ref="diagnosisDialog"
v-if="dialogVisible"
id="diagnosisTab"
class="diagnosisTab"
:title="$t('overall.diagnosis')"
:visible.sync="dialogVisible"
@close='handleClose'
width="780px"
:modal-append-to-body="true"
:append-to-body="true"
>
<div style="position: relative;">
<!-- 头部 -->
<div class="dialog-header" style="vertical-align:top;">
<div class="dialog-header-l">
<i class="nz-icon nz-icon-Diagnosis1"></i>
<div>
<div class="dialog-header-name">{{$t('project.endpoint.endpointName')}}</div>
<div v-html="suspendedStr(diagnosisTabData.row.configs[0].state)" class="dialog-header-item">
</div>
</div>
</div>
<div class="dialog-header-r">{{$t('overall.serviceTime')}}{{secondFormatter(elapsedTime)}}</div>
</div>
<!-- 表格 -->
<div class="diagnosis-table">
<el-table
id="diagnosisTable"
ref="dataTable"
:height="'286px'"
:data="tableData"
>
<el-table-column
v-for="(item, index) in tableTitle"
:key="`col-${index}`"
:label="item.label"
:min-width="`${item.minWidth}`"
:prop="item.prop"
:resizable="true"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span class="data-column__span">{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<template v-if="item.prop === 'state'">
<div>
<i v-if="scope.row[item.prop] == 1" class="nz-icon nz-icon-import-success1 green"></i>
<i v-else-if="scope.row[item.prop] == 2" class="nz-icon nz-icon-import-failed1 red"></i>
<i v-else class="nz-icon nz-icon-stop" style="color:#BEBEBE;"></i>
</div>
</template>
<template v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</template>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column type="expand">
<template slot-scope="{ row }">
<div class="expand-details">
<pre>{{row.resolution}}</pre>
</div>
</template>
</el-table-column>
<template slot="empty">
<div class="table-no-data">
<svg class="icon" aria-hidden="true">
<use xlink:href="#nz-icon-no-data-list"></use>
</svg>
<div class="table-no-data__title">No results found</div>
</div>
</template>
</el-table>
</div>
<loading ref="loading"></loading>
</div>
<!-- 底部按钮 -->
<span slot="footer" class="dialog-footer right-box__footer batch-delete-footer">
<div>
<button id="diagnosis-cancel" class="footer__btn footer__btn--light" type="button" @click="dialogVisible = false">{{$t('overall.close')}}</button>
</div>
</span>
</el-dialog>
</div>
</template>
<script>
import loading from '@/components/common/loading'
// 解决浏览器切换或者小化时定时器失效问题
function create (f) {
const blob = new Blob(['(' + f + ')()'])
const url = window.URL.createObjectURL(blob)
const worker = new Worker(url)
return worker
}
const createWorker = (callback, time) => {
const pollingWorker = create(`function (e) {
setInterval(function () {
this.postMessage(null)
}, ${time})
}`)
pollingWorker.onmessage = callback
return pollingWorker
}
const stopWorker = (vm) => {
try {
vm && vm.terminate()
} catch (err) {
console.log(err)
}
}
export default {
name: 'diagnosisTab',
components: { loading },
data () {
return {
dialogVisible: false,
timer: null, // 运行定时器
elapsedTime: 0, // 运行时间
tableData: [],
tableTitle: [ // table列
{
label: 'state',
prop: 'state',
minWidth: 34,
width: 34
}, {
label: 'name',
prop: 'item',
minWidth: 200
}]
}
},
props: {
diagnosisTabData: Object
},
methods: {
handleClose () {
this.dialogVisible = false
},
getTableData () {
this.$get('monitor/endpoint/diagnose/' + this.diagnosisTabData.row.id).then(response => {
if (response.code == 200) {
this.tableData = response.data.list
// 关闭定时器 取消任务
stopWorker(this.timer)
this.$refs.loading.endLoading()
} else {
this.$message.error(response.msg)
}
})
},
// 补零
zeroize (num) {
return num < 10 ? '0' + num : num
},
// 秒转为时-分-秒(000000)
secondFormatter (millisecond) {
const secondTime = parseInt(millisecond / 1000)
let time = '00:00:' + this.zeroize(secondTime)
if (secondTime > 60) {
const second = parseInt(secondTime % 60)
let min = parseInt(secondTime / 60)
time = '00:' + this.zeroize(min) + ':' + this.zeroize(second)
if (min > 60) {
min = parseInt(secondTime / 60 % 60)
const hour = parseInt((secondTime / 60) / 60)
time = this.zeroize(hour) + ':' + this.zeroize(min) + ':' + this.zeroize(second) + ':'
}
}
return time
},
suspendedStr (status) { // 10进制转为2进制 分别给对应的状态
if (!status || status === 1 || status == 0) { return '' }
const arr = status.toString(2).split('')
while (arr.length < 4) {
arr.unshift('0')
}
arr.pop()
let str = ''
arr.forEach((item, index) => {
if (index === 0) {
str += `<span><i class="active-icon inline-block ${item == '0' ? 'gray-bg' : 'green-bg'}"></i> DC</span>`
}
if (index === 1) {
str += `<span><i class="active-icon inline-block ${item == '0' ? 'gray-bg' : 'green-bg'}"></i> ASSET</span>`
}
if (index === 2) {
str += `<span><i class="active-icon inline-block ${item == '0' ? 'gray-bg' : 'green-bg'}"></i> ENDPOINT</span>`
}
})
return str
}
},
computed: {
showDiagnosisTab () {
return this.$store.getters.getShowDiagnosisTab
}
},
mounted () {
},
watch: {
// 展示弹窗
showDiagnosisTab (n) {
if (n) {
this.dialogVisible = true
// 定时获取运行时间
this.timer = createWorker(() => {
this.elapsedTime += 100
}, 100)
this.$nextTick(() => {
this.$refs.loading.startLoading()
this.getTableData()
})
}
},
// 关闭弹窗
dialogVisible (n) {
if (!n) {
this.$store.dispatch('dispatchShowDiagnosisTab', false)
}
}
},
beforeDestroy () {
stopWorker(this.timer)
}
}
</script>
<style>
</style>

View File

@@ -93,6 +93,14 @@ export default {
this.$emit('metricTarget', row, param)
break
}
case 'diagnosis': {
this.$store.dispatch('diagnosisTab', {
row: row,
url: this.api,
...param
})
break
}
default:
this.$emit(command, row, param)
break

View File

@@ -112,6 +112,11 @@
:delete-objs="singleDelete"
@before="delFlag=true"
></delete-button>
<diagnosis-tab
ref="diagnosisTab"
:api="diagnosisTabData.url"
:diagnosisTabData ="diagnosisTabData"
></diagnosis-tab>
</div>
</template>
@@ -124,6 +129,7 @@ import bus from '@/libs/bus'
import routerPathParams from '@/components/common/mixin/routerPathParams'
import SearchBox from '@/components/common/searchBox/searchBox'
import deleteButton from '@/components/common/deleteButton'
import diagnosisTab from '@/components/common/diagnosisTab'
export default {
name: 'nzDataList',
mixins: [routerPathParams],
@@ -131,7 +137,8 @@ export default {
SearchBox,
bottomBox,
panelChart,
deleteButton
deleteButton,
diagnosisTab
},
props: {
from: {
@@ -179,6 +186,9 @@ export default {
},
deleteTableRel () {
return this.$store.getters.getDeleteTableRel
},
diagnosisTab () {
return this.$store.getters.getDiagnosisTab
}
},
data () {
@@ -207,7 +217,9 @@ export default {
showCustomTableTitle: false // 自定义列弹框是否显示
},
showLayout: [],
timeRange: [new Date(), new Date()]
timeRange: [new Date(), new Date()],
// 故障诊断数据
diagnosisTabData: {}
}
},
mounted () {
@@ -294,6 +306,9 @@ export default {
if (n) {
this.delTableRelRow(this.deleteTableRel.url, this.deleteTableRel.row, this.deleteTableRel.forceDeleteShow, this.deleteTableRel.single, this.deleteTableRel.deleteTitle)
}
},
diagnosisTab (n) {
this.diagnosisTabData = n
}
},
beforeDestroy () {

View File

@@ -181,6 +181,7 @@
<el-dropdown-item v-has="'monitor_endpoint_edit'" :command="['copy', scope.row, 'project']"><i class="nz-icon nz-icon-override"></i><span class="operation-dropdown-text">{{$t('overall.duplicate')}}</span></el-dropdown-item>
<el-dropdown-item v-has="'alertSilence_add'" :command="['fastSilence', scope.row, 'endpoint']"><i class="nz-icon nz-icon-fast-silence"></i><span class="operation-dropdown-text">{{$t('overall.silenceAlert')}}</span></el-dropdown-item>
<el-dropdown-item v-has="'asset_add'" :command="['topology', scope.row, 'endpoint']"><i class="nz-icon nz-icon-Topology"></i><span class="operation-dropdown-text">{{$t('overall.topology')}}</span></el-dropdown-item>
<el-dropdown-item v-has="'asset_add'" :command="['diagnosis', scope.row]"><i class="nz-icon nz-icon-diagnosis"></i><span class="operation-dropdown-text">{{$t('overall.diagnosis')}}</span></el-dropdown-item>
<el-dropdown-item v-has="'monitor_endpoint_add'" :command="['metricTarget', scope.row, 'endpoint']" :disabled="scope.row.configs[0].config.protocol !== ('http'||'https')"><i class="nz-icon nz-icon-Metrics"></i><span class="operation-dropdown-text">{{$t('endpoints.metricTarget')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
@@ -210,13 +211,11 @@ import table from '@/components/common/mixin/table'
import alertLabel from '../../alert/alertLabel'
import nzTooltip from '../../alert/nzTooltip'
import alertLabelMixin from '@/components/common/mixin/alertLabelMixin'
import deleteButton from '@/components/common/deleteButton'
export default {
name: 'endpointTable',
components: {
alertLabel,
nzTooltip,
deleteButton
nzTooltip
},
mixins: [table, alertLabelMixin],
props: {

View File

@@ -50,7 +50,9 @@ const store = new Vuex.Store({
nowPath: '',
myEvent: new Event('resize'),
deleteTableRel: {},
showDeleteTableRel: false
showDeleteTableRel: false,
diagnosisTab: {}, // 故障诊断
showDiagnosisTab: false
},
getters: {
getGlobalSearchId (state) {
@@ -112,6 +114,12 @@ const store = new Vuex.Store({
},
getShowDeleteTableRel (state) {
return state.showDeleteTableRel
},
getDiagnosisTab (state) {
return state.diagnosisTab
},
getShowDiagnosisTab (state) {
return state.showDiagnosisTab
}
},
mutations: {
@@ -228,6 +236,12 @@ const store = new Vuex.Store({
if (!flag) {
state.deleteTableRel = {}
}
},
setDiagnosisTab (state, payload) {
state.diagnosisTab = payload
},
setShowDiagnosisTab (state, flag) {
state.showDiagnosisTab = flag
}
},
actions: {
@@ -237,6 +251,13 @@ const store = new Vuex.Store({
},
dispatchShowDeleteTableRel (store, flag) {
store.commit('setShowDeleteTableRel', flag)
},
diagnosisTab (store, payload) { // 故障诊断
store.commit('setDiagnosisTab', payload)
store.commit('setShowDiagnosisTab', true)
},
dispatchShowDiagnosisTab (store, flag) {
store.commit('setShowDiagnosisTab', flag)
}
}
})