perf: 数据列表样式统一

This commit is contained in:
chenjinsong
2021-04-13 20:33:12 +08:00
parent 9659955cef
commit 124d69688f
41 changed files with 2565 additions and 3500 deletions

View File

@@ -94,6 +94,16 @@
border: 1px solid #E7EAED; border: 1px solid #E7EAED;
border-bottom: none; border-bottom: none;
.caret-wrapper {
height: 23px;
.sort-caret.ascending {
top: 1px;
}
.sort-caret.descending {
bottom: 0;
}
}
.el-table-column--selection { .el-table-column--selection {
width: 55px !important; width: 55px !important;
} }
@@ -145,15 +155,16 @@
border: none; border: none;
border-radius: $--button-border-radius; border-radius: $--button-border-radius;
background-color: $--button-primary-background-color; background-color: $--button-primary-background-color;
opacity: .8; opacity: 1;
cursor: pointer; cursor: pointer;
transition: all .2s;
i { i {
color: $--button-primary-color; color: $--button-primary-color;
font-size: 12px; font-size: 12px;
} }
} }
>.table-operation-item:hover { >.table-operation-item:hover {
opacity: .8;
} }
.table-operation-item.table-operation-item--more { .table-operation-item.table-operation-item--more {
justify-content: space-between; justify-content: space-between;
@@ -186,10 +197,11 @@
.el-table--border td { .el-table--border td {
border-right: none !important; border-right: none !important;
} }
.el-table--border .el-table__body-wrapper td:nth-last-child(2) { /* 最后一列用box-shadow模拟边框 */
.el-table:not(.no-operation).el-table--border .el-table__body-wrapper td:nth-last-child(2) {
box-shadow: 1px 0 #E7EAED; box-shadow: 1px 0 #E7EAED;
} }
.el-table--border .el-table__header-wrapper th:nth-last-child(3) { .el-table:not(.no-operation).el-table--border .el-table__header-wrapper th:nth-last-child(3) {
border-right: none !important; border-right: none !important;
box-shadow: 1px 0 #E7EAED; box-shadow: 1px 0 #E7EAED;
} }

View File

@@ -133,7 +133,7 @@ import loading from '../common/loading'
import axios from 'axios' import axios from 'axios'
import pickTime from '../common/pickTime' import pickTime from '../common/pickTime'
import chart from '../page/dashboard/overview/chart' import chart from '../page/dashboard/overview/chart'
import alertMessageTable from '@/components/common/alert/alertMessageTable.vue' import alertMessageTable from '@/components/common/table/alert/alertMessageTable.vue'
export default { export default {
name: 'chartTable', name: 'chartTable',
components: { components: {

View File

@@ -89,13 +89,13 @@
<script> <script>
import axios from 'axios' import axios from 'axios'
import bus from '../../../../libs/bus' import bus from '../../../../libs/bus'
import alertMessageTable from '@/components/common/alert/alertMessageTable.vue' import alertMessageTable from '@/components/common/table/alert/alertMessageTable.vue'
import deleteButton from '../../deleteButton' import deleteButton from '../../deleteButton'
export default { export default {
name: 'alertMessageTab', name: 'alertMessageTab',
components: { components: {
alertMessageTable: alertMessageTable, alertMessageTable,
'delete-button': deleteButton deleteButton
}, },
props: { props: {
from: String, // 来自哪个主页面,有:"asset"、"alertRule" from: String, // 来自哪个主页面,有:"asset"、"alertRule"

View File

@@ -267,14 +267,14 @@ export default {
clearSelectedMetrics () { clearSelectedMetrics () {
this.$refs.endpointQueryTable.clearSelection() this.$refs.endpointQueryTable.clearSelection()
}, },
changeTime: function (size, unit) { changeTime (size, unit) {
this.formatTime = this.getTime(size, unit) this.formatTime = this.getTime(size, unit)
this.showEndpoint() this.showEndpoint()
}, },
pickTime: function () { pickTime () {
this.showEndpoint() this.showEndpoint()
}, },
getTime: function (size, unit) { // 计算时间 getTime (size, unit) { // 计算时间
const now = !this.formatTime ? new Date(bus.computeTimezone(new Date().getTime())) : new Date(this.formatTime) const now = !this.formatTime ? new Date(bus.computeTimezone(new Date().getTime())) : new Date(this.formatTime)
if (unit) { if (unit) {
switch (unit) { switch (unit) {
@@ -383,17 +383,17 @@ export default {
} }
return tableData return tableData
}, },
selectChange: function (selection) { // selection 选中的row的数组 selectChange (selection) { // selection 选中的row的数组
this.selectedEndpoints = selection this.selectedEndpoints = selection
}, },
selectable: function (row, index) { selectable (row, index) {
if (this.selectedEndpoints.length >= 20 && !this.selectedEndpoints.includes(row)) { if (this.selectedEndpoints.length >= 20 && !this.selectedEndpoints.includes(row)) {
return false return false
} else { } else {
return true return true
} }
}, },
viewGraph: function () { viewGraph () {
if (this.selectedEndpoints.length < 1) { if (this.selectedEndpoints.length < 1) {
return return
} }
@@ -412,7 +412,7 @@ export default {
this.queryChartDate() this.queryChartDate()
}) })
}, },
dialogClose: function () { dialogClose () {
this.$refs.pickTime.$refs.multipleTime.searchTime = [] this.$refs.pickTime.$refs.multipleTime.searchTime = []
this.$refs.pickTime.$refs.multipleTime.showTime = { this.$refs.pickTime.$refs.multipleTime.showTime = {
id: 12, id: 12,
@@ -421,13 +421,13 @@ export default {
this.$refs.pickTime.$refs.multipleTime.showDropdown = false this.$refs.pickTime.$refs.multipleTime.showDropdown = false
this.graphShow = false this.graphShow = false
}, },
chartUnitChange: function (unit) { chartUnitChange (unit) {
this.chartUnit = unit this.chartUnit = unit
this.$nextTick(() => { this.$nextTick(() => {
this.queryChartDate() this.queryChartDate()
}) })
}, },
queryChartDate: function () { queryChartDate () {
const start = this.searchTime[0] ? this.searchTime[0] : this.getTime(-1, 'h') const start = this.searchTime[0] ? this.searchTime[0] : this.getTime(-1, 'h')
const end = this.searchTime[1] ? this.searchTime[1] : this.getTime(0, 'h') const end = this.searchTime[1] ? this.searchTime[1] : this.getTime(0, 'h')
this.searchTime = [start, end] this.searchTime = [start, end]
@@ -572,7 +572,7 @@ export default {
return element.indexOf(this.queryExpression) !== -1 return element.indexOf(this.queryExpression) !== -1
}) })
}, },
tableFilterHistory: function (expression) { tableFilterHistory (expression) {
let metric = '' let metric = ''
let labels = [] let labels = []
if (/\w*\{.*\}.*/i.test(expression)) { if (/\w*\{.*\}.*/i.test(expression)) {
@@ -640,13 +640,13 @@ export default {
} }
} }
}, },
focusInput: function () { focusInput () {
let classVal = document.getElementById('elementQuery').parentElement.getAttribute('class') let classVal = document.getElementById('elementQuery').parentElement.getAttribute('class')
classVal = classVal.replace('query-input-inactive', 'query-input-active') classVal = classVal.replace('query-input-inactive', 'query-input-active')
document.getElementById('elementQuery').parentElement.setAttribute('class', classVal) document.getElementById('elementQuery').parentElement.setAttribute('class', classVal)
this.$refs.elementQuery.focus() this.$refs.elementQuery.focus()
}, },
blurInput: function () { blurInput () {
if (!this.queryExpression || this.queryExpression == '') { if (!this.queryExpression || this.queryExpression == '') {
setTimeout(function () { setTimeout(function () {
let classVal = document.getElementById('elementQuery').parentElement.getAttribute('class') let classVal = document.getElementById('elementQuery').parentElement.getAttribute('class')
@@ -655,7 +655,7 @@ export default {
}, 100) }, 100)
} }
}, },
clearInput: function () { clearInput () {
this.$refs.elementQuery.focus() this.$refs.elementQuery.focus()
}, },
queryElementTips: async function () { queryElementTips: async function () {
@@ -667,7 +667,7 @@ export default {
} }
} }
}, },
getStateContent: function (row) { getStateContent (row) {
if (row) { if (row) {
if (row.state == 1) { if (row.state == 1) {
return 'up' + '[' + this.formatUpdateTime(row.lastUpdate) + ']' return 'up' + '[' + this.formatUpdateTime(row.lastUpdate) + ']'
@@ -676,14 +676,14 @@ export default {
} }
} }
}, },
formatUpdateTime: function (date) { formatUpdateTime (date) {
const time = new Date(date) const time = new Date(date)
const hours = time.getHours() > 9 ? time.getHours() : '0' + time.getHours() const hours = time.getHours() > 9 ? time.getHours() : '0' + time.getHours()
const minutes = time.getMinutes() > 9 ? time.getMinutes() : '0' + time.getMinutes() const minutes = time.getMinutes() > 9 ? time.getMinutes() : '0' + time.getMinutes()
return hours + ':' + minutes return hours + ':' + minutes
}, },
getStateErrorMsg: function (row) { getStateErrorMsg (row) {
const errCodes = [230009, 230010, 230011] const errCodes = [230009, 230010, 230011]
if (row) { if (row) {
if (row.state == 0) { if (row.state == 0) {

View File

@@ -12,124 +12,34 @@
</div> </div>
</div> </div>
</div> </div>
<el-table <operation-log-table
id="role-list-table"
ref="dataTable" ref="dataTable"
v-loading="tools.loading" v-loading="tools.loading"
:data="tableData" :api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight" :height="mainTableHeight"
border :table-data="tableData"
@header-dragend="dragend" @del="del"
@sort-change="tableDataSort" @edit="edit"
@selection-change="(selection)=>{batchDeleteObjs=selection}" @orderBy="tableDataSort"
> @reload="getTableData"
<el-table-column @selectionChange="selectionChange"></operation-log-table>
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</span>
</template>
<template slot-scope="scope" :column="item">
<span v-if="item.prop === 'time'">
{{scope.row[item.prop]}} ms
</span>
<span v-else-if="item.prop === 'username'">{{formatUsername(scope.row)}}</span>
<span v-else-if="item.prop === 'createDate'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<span v-else>{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
</el-table>
</div> </div>
</template> </template>
<script> <script>
import tableMixin from '@/components/common/mixin/dataList' import dataListMixin from '@/components/common/mixin/dataList'
import operationLogTable from '@/components/common/table/settings/operationLogTable'
export default { export default {
name: 'operationLogTab', name: 'operationLogTab',
mixins: [tableMixin], mixins: [dataListMixin],
components: {
operationLogTable
},
data () { data () {
return { return {
tableId: 'operationLogTable', // 需要分页的table的id用于记录每页数量 url: 'sys/log/list',
tableTitle: [ tableId: 'operationLogTable',
{
label: this.$t('config.operationlog.id'),
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.operationlog.username'),
prop: 'username',
show: true
},
{
label: this.$t('config.operationlog.ip'),
prop: 'ip',
show: true
},
{
label: this.$t('config.operationlog.operation'),
prop: 'operation',
show: true
},
{
label: this.$t('config.operationlog.type'),
prop: 'type',
show: true
},
{
label: this.$t('config.operationlog.state'),
prop: 'state',
show: true
},
// {
// label: this.$t('config.operationlog.userId'),
// prop: 'userId',
// show: false,
// },
{
label: this.$t('config.operationlog.operaId'),
prop: 'operaId',
show: false
},
{
label: this.$t('config.operationlog.createDate'),
prop: 'createDate',
show: true
},
{
label: this.$t('config.operationlog.time'),
prop: 'time',
show: false
},
{
label: this.$t('config.operationlog.params'),
prop: 'params',
show: false
},
{
label: this.$t('config.operationlog.response'),
prop: 'response',
show: false
}
],
searchMsg: { // 给搜索框子组件传递的信息 searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true, zheze_none: true,
searchLabelList: [ searchLabelList: [

View File

@@ -52,7 +52,7 @@ export default {
<style scoped> <style scoped>
.delete-button{ .delete-button{
margin-left: 10px; margin-right: 10px;
opacity: 0.7; opacity: 0.7;
border-radius: 2px; border-radius: 2px;
} }

View File

@@ -2,40 +2,7 @@ import i18n from '../i18n'
export const defaultPageSize = 20 export const defaultPageSize = 20
export const staticMenus = { export const agent = {
settings: {
title: i18n.t('overall.config'),
menu: [
{ route: '/account', name: i18n.t('config.account.account') },
{ route: '/roles', name: i18n.t('config.roles.roles') },
{ route: '/promServer', name: i18n.t('config.promServer.promServerList') },
{ route: '/dc', name: i18n.t('config.dc.dc') },
{ route: '/model', name: i18n.t('config.model.model') },
{ route: '/mib', name: i18n.t('config.mib.mib') },
{ route: '/system', name: i18n.t('config.system.system') },
{ route: '/terminalLog', name: i18n.t('config.terminallog.terminallog') },
{ route: '/operationLog', name: i18n.t('config.operationlog.operationlog') },
{ route: '/about', name: i18n.t('overall.about') }
]
},
alerts: {
title: i18n.t('alert.alert'),
menu: [
{ route: '/alertList', name: i18n.t('alert.alertList') },
{ route: '/alertConfig', name: i18n.t('alert.alertConfig') }
]
},
dashboards: {
title: i18n.t('dashboard.title'),
menu: [
{ route: '/overview', name: i18n.t('dashboard.overview.title') },
{ route: '/panel', name: i18n.t('dashboard.panel.title') },
{ route: '/explore', name: i18n.t('dashboard.metricPreview.title') }
]
}
}
export const promServer = {
theData: [ theData: [
{ {
label: 'Federation', label: 'Federation',
@@ -87,7 +54,7 @@ export const promServer = {
] ]
} }
export const promServer2 = { export const agent2 = {
theData: [ theData: [
{ {
label: 'Global', label: 'Global',
@@ -179,8 +146,9 @@ export const terminalLog = {
export const fromRoute = { export const fromRoute = {
panel: 'panel', panel: 'panel',
explore: 'explore', explore: 'explore',
message: 'message', alertMessage: 'alertMessage',
rule: 'rule', alertRule: 'alertRule',
alertSilence: 'alertSilence',
model: 'model', model: 'model',
mib: 'mib', mib: 'mib',
asset: 'asset', asset: 'asset',
@@ -188,7 +156,7 @@ export const fromRoute = {
assetState: 'assetState', assetState: 'assetState',
expressionTemplate: 'expressionTemplate', expressionTemplate: 'expressionTemplate',
user: 'user', user: 'user',
promServer: 'promServer', agent: 'agent',
dc: 'dc', dc: 'dc',
role: 'role', role: 'role',
endpoint: 'endpoint', endpoint: 'endpoint',

View File

@@ -1,6 +1,7 @@
import { getChart } from './common' import { getChart } from './common'
import MessageBox from 'element-ui/packages/message-box/src/main' import MessageBox from 'element-ui/packages/message-box/src/main'
import i18n from '../i18n' import i18n from '../i18n'
import bus from '@/libs/bus'
/* 弹窗点击外部后关闭 */ /* 弹窗点击外部后关闭 */
const exceptClassName = ['config-dropdown', 'nz-pop', 'el-picker', 'chart-box-dropdown', 'metric-dropdown', 'el-cascader__dropdown', 'asset-dropdown', 'no-style-class', 'el-message-box', 'nz-dashboard-dropdown', 'el-autocomplete-suggestion', 'nz-temp-box', 'el-time-panel'] // clickoutside排除的class(白名单) no-style-class没有任何样式的class const exceptClassName = ['config-dropdown', 'nz-pop', 'el-picker', 'chart-box-dropdown', 'metric-dropdown', 'el-cascader__dropdown', 'asset-dropdown', 'no-style-class', 'el-message-box', 'nz-dashboard-dropdown', 'el-autocomplete-suggestion', 'nz-temp-box', 'el-time-panel'] // clickoutside排除的class(白名单) no-style-class没有任何样式的class
export const clickoutside = { export const clickoutside = {
@@ -283,6 +284,47 @@ export function stringTimeParseToUnix (stringTime) {
const time = new Date(stringTime).getTime() const time = new Date(stringTime).getTime()
return time / 1000 return time / 1000
} }
export function getTime (size, unit) { // 计算时间
const now = new Date(bus.computeTimezone(new Date().getTime()))
if (unit) {
switch (unit) {
case 'y':
now.setFullYear(now.getFullYear() + size)
break
case 'M':
now.setMonth(now.getMonth() + size)
break
case 'd':
now.setDate(now.getDate() + size)
break
case 'h':
now.setHours(now.getHours() + size)
break
case 'm':
now.setMinutes(now.getMinutes() + size)
break
case 's':
now.setSeconds(now.getSeconds() + size)
break
default:
console.error('unit error')
}
} else {
now.setSeconds(now.getSeconds() + size)
}
const year = now.getFullYear()
let month = now.getMonth() + 1
month = month < 10 ? '0' + month : month
let day = now.getDate()
day = day < 10 ? '0' + day : day
let hour = now.getHours()
hour = hour < 10 ? '0' + hour : hour
let minute = now.getMinutes()
minute = minute < 10 ? '0' + minute : minute
let second = now.getSeconds()
second = second < 10 ? '0' + second : second
return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second
}
export function calcDurationByStringTime (startTime, endTime) { export function calcDurationByStringTime (startTime, endTime) {
const durationSecond = stringTimeParseToUnix(endTime) - stringTimeParseToUnix(startTime) const durationSecond = stringTimeParseToUnix(endTime) - stringTimeParseToUnix(startTime)
let result = `${durationSecond % 60}s` let result = `${durationSecond % 60}s`

View File

@@ -7,7 +7,7 @@ const cn = {
alert: '告警', alert: '告警',
asset: '资产', asset: '资产',
config: '设置', config: '设置',
administration: '行政管理', administration: '系统管理',
configuration: '设置', configuration: '设置',
create: '新增', create: '新增',
edit: '编辑', edit: '编辑',
@@ -712,6 +712,7 @@ const cn = {
checkTime: '检查时间', checkTime: '检查时间',
dataCenter: '数据中心', dataCenter: '数据中心',
agent: { agent: {
agent: 'Agent',
title: '下载Agent', title: '下载Agent',
download: '下载', download: '下载',
osType: 'OS 类型', osType: 'OS 类型',
@@ -1421,7 +1422,8 @@ const cn = {
view: '查看', view: '查看',
add: '新增', add: '新增',
edit: '修改', edit: '修改',
delete: '删除' delete: '删除',
expire: '过期'
}, },
...zhLocale ...zhLocale
} }

View File

@@ -706,8 +706,7 @@ const en = {
editMenu: 'Edit menu', editMenu: 'Edit menu',
orderNum: 'Order' orderNum: 'Order'
}, },
promServer: { agent: {
promServerList: 'Prometheus server', // "Prometheus Server"
// 侧滑框 // 侧滑框
promId: 'Prometheus server ID', // "Prometheus Server ID" promId: 'Prometheus server ID', // "Prometheus Server ID"
createProm: 'New prometheus server', // "新增Prometheus Server" createProm: 'New prometheus server', // "新增Prometheus Server"
@@ -716,6 +715,7 @@ const en = {
checkTime: 'Check time', checkTime: 'Check time',
dataCenter: 'Data center', dataCenter: 'Data center',
agent: { agent: {
agent: 'Agent',
title: 'Download agent', title: 'Download agent',
download: 'Download', download: 'Download',
osType: 'OS type', osType: 'OS type',
@@ -747,7 +747,7 @@ const en = {
state: 'State', state: 'State',
longitude: 'Longitude', longitude: 'Longitude',
latitude: 'Latitude', latitude: 'Latitude',
lnglat: 'Coordinate', lnglat: 'Coordinate'
}, },
model: { model: {
model: 'Asset model', model: 'Asset model',
@@ -1036,8 +1036,8 @@ const en = {
alert: 'Alerts', // "告警" alert: 'Alerts', // "告警"
message: 'Message', // '信息' message: 'Message', // '信息'
rule: 'Rule', // '规则' rule: 'Rule', // '规则'
alertList: 'Alert message', // "告警信息" alertMessage: 'Alert message', // "告警信息"
alertConfig: 'Alert rule', // "告警规则" alertRule: 'Alert rule', // "告警规则"
alertName: 'Alert name', // "告警名称" alertName: 'Alert name', // "告警名称"
severity: 'Priority', // "等级" severity: 'Priority', // "等级"
description: 'Description', // "描述" description: 'Description', // "描述"
@@ -1305,7 +1305,8 @@ const en = {
view: 'View', view: 'View',
add: 'Add', add: 'Add',
edit: 'Edit', edit: 'Edit',
delete: 'Delete' delete: 'Delete',
expire: 'Expire'
}, },
...enLocale ...enLocale
} }

View File

@@ -30,6 +30,10 @@ export default {
this.$emit('del', row) this.$emit('del', row)
break break
} }
case 'record': {
this.$emit('showBottomBox', 'record', row)
break
}
default: default:
break break
} }

View File

@@ -1,10 +1,10 @@
<template> <template>
<div class="right-box right-box-prom" v-clickoutside="{obj:editPromServer,func:clickOutside}"> <div v-clickoutside="{obj:editPromServer,func:clickOutside}" class="right-box right-box-prom">
<!-- begin--顶部按钮--> <!-- begin--顶部按钮-->
<div class="right-box-top-btns right-box-form-delete"> <div class="right-box-top-btns right-box-form-delete">
<button @click="del" type="button" v-has="'prom_delete'" v-if="editPromServer.id" <button v-if="editPromServer.id" id="promServer-edit-del" v-has="'prom_delete'" class="nz-btn nz-btn-size-normal nz-btn-size-alien"
class="nz-btn nz-btn-size-normal nz-btn-size-alien" type="button"
id="promServer-edit-del"> @click="del">
<span class="right-box-top-btn-icon"><i class="nz-icon nz-icon-delete"></i></span> <span class="right-box-top-btn-icon"><i class="nz-icon nz-icon-delete"></i></span>
<span class="right-box-top-btn-txt">{{$t('overall.delete')}}</span> <span class="right-box-top-btn-txt">{{$t('overall.delete')}}</span>
</button> </button>
@@ -17,12 +17,12 @@
<!-- begin--表单--> <!-- begin--表单-->
<div class="right-box-form-box"> <div class="right-box-form-box">
<el-form class="right-box-form right-box-form-left" :model="editPromServer" label-position = "top" label-width="120px" :rules="rules" ref="promServerForm"> <el-form ref="promServerForm" :model="editPromServer" :rules="rules" class="right-box-form right-box-form-left" label-position = "top" label-width="120px">
<!--DC--> <!--DC-->
<el-form-item :label="$t('config.dc.dc')" prop="idc.name"> <el-form-item :label="$t('config.dc.dc')" prop="dc.name">
<div class="right-box-form-content"> <div class="right-box-form-content">
<el-select value-key="id" popper-class="config-dropdown" v-model="editPromServer.idc" placeholder="" size="small" id="prom-box-input-idc"> <el-select id="prom-box-input-dc" v-model="editPromServer.dc" placeholder="" popper-class="config-dropdown" size="small" value-key="id">
<el-option v-for="item in dcData" :key="item.id" :label="item.name" :value="item" :id="'prom-edit-idc-op-'+item.id"> <el-option v-for="item in dcData" :id="'prom-edit-dc-op-'+item.id" :key="item.id" :label="item.name" :value="item">
<span class="config-dropdown-label-txt">{{item.name}}</span> <span class="config-dropdown-label-txt">{{item.name}}</span>
</el-option> </el-option>
</el-select> </el-select>
@@ -31,11 +31,11 @@
<!--host--> <!--host-->
<el-form-item label="Host" prop="host"> <el-form-item label="Host" prop="host">
<el-input type="text" placeholder="" v-model="editPromServer.host" size="small" id="prom-box-input-host"></el-input> <el-input id="prom-box-input-host" v-model="editPromServer.host" placeholder="" size="small" type="text"></el-input>
</el-form-item> </el-form-item>
<!--Port--> <!--Port-->
<el-form-item label="Port" prop="port"> <el-form-item label="Port" prop="port">
<el-input type="text" placeholder="" v-model.number="editPromServer.port" size="small" id="prom-box-input-port"></el-input> <el-input id="prom-box-input-port" v-model.number="editPromServer.port" placeholder="" size="small" type="text"></el-input>
</el-form-item> </el-form-item>
<!--type--> <!--type-->
<el-form-item :label="$t('config.promServer.type')" prop="type"> <el-form-item :label="$t('config.promServer.type')" prop="type">
@@ -48,14 +48,14 @@
<!-- :options="$CONSTANTS.promServer.theData"--> <!-- :options="$CONSTANTS.promServer.theData"-->
<!-- :props="{ multiple: false, checkStrictly: false ,emitPath:false}"--> <!-- :props="{ multiple: false, checkStrictly: false ,emitPath:false}"-->
<!-- clearable></el-cascader>--> <!-- clearable></el-cascader>-->
<el-select placeholder="" v-model="editPromServer.type" :disabled="editPromServer.id != null&& editPromServer.id != ''" popper-class="config-dropdown" value-key="value" size="small"> <el-select v-model="editPromServer.type" :disabled="editPromServer.id != null&& editPromServer.id != ''" placeholder="" popper-class="config-dropdown" size="small" value-key="value">
<el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in $CONSTANTS.promServer2.theData"> <el-option v-for="item in agent2.theData" :key="item.value" :label="item.label" :value="item.value">
<span class="panel-dropdown-label-txt" >{{item.label}}</span> <span class="panel-dropdown-label-txt" >{{item.label}}</span>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="Token" prop="token"> <el-form-item label="Token" prop="token">
<el-input class="right-box-row-with-btn" type="text" placeholder="" v-model="editPromServer.token" size="small" id="prom-box-input-token"> <el-input id="prom-box-input-token" v-model="editPromServer.token" class="right-box-row-with-btn" placeholder="" size="small" type="text">
<i slot="suffix" class="nz-icon nz-icon-refresh" @click="refreshToken"></i> <i slot="suffix" class="nz-icon nz-icon-refresh" @click="refreshToken"></i>
</el-input> </el-input>
</el-form-item> </el-form-item>
@@ -64,12 +64,12 @@
<!-- end--表单--> <!-- end--表单-->
<!--底部按钮--> <!--底部按钮-->
<div class="right-box-bottom-btns"> <div class="right-box-bottom-btns">
<button v-cancel="{obj:editPromServer,func:esc}" id="prom-esc" <button id="prom-esc" v-cancel="{obj:editPromServer,func:esc}"
class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new"> class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new">
<span>{{$t('overall.cancel')}}</span> <span>{{$t('overall.cancel')}}</span>
</button> </button>
<button @click="save" id="prom-save" <button id="prom-save" :class="{'nz-btn-disabled':prevent_opt.save}"
class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" :disabled="prevent_opt.save" :class="{'nz-btn-disabled':prevent_opt.save}"> :disabled="prevent_opt.save" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" @click="save">
<span>{{$t('overall.save')}}</span> <span>{{$t('overall.save')}}</span>
</button> </button>
</div> </div>
@@ -77,16 +77,17 @@
</template> </template>
<script> <script>
import { host, port } from '../../common/js/validate' import { host, port } from '../../common/js/validate'
import { agent2 } from '@/components/common/js/constants'
export default { export default {
name: 'promServerBox', name: 'agentBox',
props: { props: {
promServer: Object promServer: Object
}, },
data () { data () {
return { return {
agent2: agent2,
rules: { rules: {
'idc.name': [ 'dc.name': [
{ required: true, message: this.$t('validate.required'), trigger: 'change' } { required: true, message: this.$t('validate.required'), trigger: 'change' }
], ],
host: [ host: [
@@ -176,7 +177,7 @@ export default {
}, },
// dc // dc
getDcData () { getDcData () {
this.$get('idc', { pageSize: -1 }).then(response => { this.$get('dc', { pageSize: -1 }).then(response => {
if (response.code === 200) { if (response.code === 200) {
this.dcData = response.data.list this.dcData = response.data.list
} }
@@ -192,8 +193,8 @@ export default {
this.editPromServer = JSON.parse(JSON.stringify(n)) this.editPromServer = JSON.parse(JSON.stringify(n))
} }
}, },
'editPromServer.idc': function (n, o) { 'editPromServer.dc': function (n, o) {
this.editPromServer.idcId = n.id this.editPromServer.dcId = n.id
} }
}, },
mounted () { mounted () {

View File

@@ -1,8 +1,8 @@
<template> <template>
<div class="right-box right-box-alert-config" v-clickoutside="{obj:editAlertRule,func:clickOutside}"> <div v-clickoutside="{obj: editAlertRule, func: clickOutside}" class="right-box right-box-alert-config">
<!-- begin--顶部按钮--> <!-- begin--顶部按钮-->
<div class="right-box-top-btns right-box-form-delete"> <div class="right-box-top-btns right-box-form-delete">
<button @click="del" class="nz-btn nz-btn-size-normal nz-btn-size-alien" id="alert-box-del" type="button" v-has="'rule_delete'" v-if="alertRule.id"> <button v-if="alertRule.id" id="alert-box-del" v-has="'rule_delete'" class="nz-btn nz-btn-size-normal nz-btn-size-alien" type="button" @click="del">
<span class="right-box-top-btn-icon"><i class="nz-icon nz-icon-delete"></i></span> <span class="right-box-top-btn-icon"><i class="nz-icon nz-icon-delete"></i></span>
<span class="right-box-top-btn-txt">{{$t('overall.delete')}}</span> <span class="right-box-top-btn-txt">{{$t('overall.delete')}}</span>
</button> </button>
@@ -15,54 +15,54 @@
<!-- begin--表单--> <!-- begin--表单-->
<div class="right-box-form-box"> <div class="right-box-form-box">
<el-form class="right-box-form right-box-form-left" :model="editAlertRule" label-position = "top" label-width="120px" :rules="rules" ref="alertRuleForm"> <el-form ref="alertRuleForm" :model="editAlertRule" :rules="rules" class="right-box-form right-box-form-left" label-position = "top" label-width="120px">
<!--alertName--> <!--name-->
<el-form-item :label='$t("alert.config.name")' prop="alertName"> <el-form-item :label='$t("alert.config.name")' prop="name">
<el-input placeholder="" maxlength="64" show-word-limit v-model="editAlertRule.alertName" size="small" id="alert-box-input-name"></el-input> <el-input id="alert-box-input-name" v-model="editAlertRule.name" maxlength="64" placeholder="" show-word-limit size="small"></el-input>
</el-form-item> </el-form-item>
<el-form-item style="width: calc(100% - 15px);margin-left: 15px" :label='$t("alert.config.expr")' prop="expr"> <el-form-item :label='$t("alert.config.expr")' prop="expr" style="width: calc(100% - 15px);margin-left: 15px">
<promql-input <promql-input
id="alert-box-input-promql"
ref="promql" ref="promql"
:expression-list.sync="expressions" :expression-list.sync="expressions"
:index="0" :index="0"
:styleType="2"
:required="true"
@change="metricChange"
:plugins="['metric-selector','metric-input']" :plugins="['metric-selector','metric-input']"
id="alert-box-input-promql" :required="true"
:styleType="2"
@change="metricChange"
></promql-input> ></promql-input>
</el-form-item> </el-form-item>
<!--threshold--> <!--threshold-->
<el-form-item :label="$t('alert.config.threshold')" prop="threshold" style="display: inline-block;"> <el-form-item :label="$t('alert.config.threshold')" prop="threshold" style="display: inline-block;">
<el-input type="text" placeholder="" v-model="editAlertRule.threshold" size="small" id="alert-box-input-threshold"> <el-input id="alert-box-input-threshold" v-model="editAlertRule.threshold" placeholder="" size="small" type="text">
<el-select popper-class="config-dropdown threshold-dropdown" v-model="editAlertRule.operator" placeholder="" size="small" id="alert-box-input-operator" slot="prepend" class="input-with-select"> <el-select id="alert-box-input-operator" slot="prepend" v-model="editAlertRule.operator" class="input-with-select" placeholder="" popper-class="config-dropdown threshold-dropdown" size="small">
<el-option :id="'operator-'+item.key" v-for="item in operators" :key="item.value" :label="item.label" :value="item.value"></el-option> <el-option v-for="item in operators" :id="'operator-'+item.key" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select> </el-select>
</el-input> </el-input>
</el-form-item> </el-form-item>
<!--unit--> <!--unit-->
<el-form-item :label="$t('alert.config.unit')" prop="unit"> <el-form-item :label="$t('alert.config.unit')" prop="unit">
<el-cascader filterable placeholder="" popper-class="no-style-class unit-popper-class" size="small" style="width: 100%" id="alert-box-input-unit" <el-cascader id="alert-box-input-unit" v-model="editAlertRule.unit" :options="unitOptions" :props="{ expandTrigger: 'click',emitPath:false }" :show-all-levels="false" filterable
:options="unitOptions" placeholder=""
:props="{ expandTrigger: 'click',emitPath:false }" popper-class="no-style-class unit-popper-class"
:show-all-levels="false" size="small"
v-model="editAlertRule.unit" style="width: 100%"
> >
</el-cascader> </el-cascader>
</el-form-item> </el-form-item>
<!--last--> <!--last-->
<el-form-item :label="$t('alert.config.for')" prop="last"> <el-form-item :label="$t('alert.config.for')" prop="last">
<el-input type="text" placeholder="" v-model.number="editAlertRule.last" size="small" id="alert-box-input-last"> <el-input id="alert-box-input-last" v-model.number="editAlertRule.last" placeholder="" size="small" type="text">
<template slot="append">{{$t('alert.config.second')}}</template> <template slot="append">{{$t('alert.config.second')}}</template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<!--severity--> <!--severity-->
<el-form-item :label="$t('alert.severity')" prop="severity"> <el-form-item :label="$t('alert.severity')" prop="severity">
<el-select popper-class="config-dropdown" v-model="editAlertRule.severity" placeholder="" size="small" id="alert-box-input-severity"> <el-select id="alert-box-input-severity" v-model="editAlertRule.severity" placeholder="" popper-class="config-dropdown" size="small">
<el-option :id="'alert-severity-'+item.value" v-for="item in $CONSTANTS.alertMessage.severityData" :key="item.value" :label="item.label" :value="item.value"> <el-option v-for="item in $CONSTANTS.alertMessage.severityData" :id="'alert-severity-'+item.value" :key="item.value" :label="item.label" :value="item.value">
<template v-if="!item.isEdit">{{item.label}}</template> <template v-if="!item.isEdit">{{item.label}}</template>
<span class="config-dropdown-label-input" v-if="item.isEdit" @click.stop> <span v-if="item.isEdit" class="config-dropdown-label-input" @click.stop>
<el-input type="text" v-model="item.value" size="mini"></el-input> <el-input v-model="item.value" size="mini" type="text"></el-input>
</span> </span>
</el-option> </el-option>
</el-select> </el-select>
@@ -76,16 +76,16 @@
</div> </div>
</div> </div>
<!--receiver--> <!--receiver-->
<el-form-item :label="$t('config.account.receiver')" prop="receiver"> <el-form-item :label="$t('config.user.receiver')" prop="receiver">
<el-select <el-select
id="alert-box-input-receiver" id="alert-box-input-receiver"
v-model.trim="editAlertRule.receiverShow" v-model.trim="editAlertRule.receiverShow"
placeholder=""
multiple
filterable filterable
multiple
placeholder=""
popper-class="no-style-class"
size="small" size="small"
value-key="userId" value-key="userId"
popper-class="no-style-class"
> >
<el-option <el-option
v-for="item in userData" v-for="item in userData"
@@ -97,11 +97,11 @@
</el-form-item> </el-form-item>
<!--summary--> <!--summary-->
<el-form-item :label="$t('alert.summary')" prop="summary"> <el-form-item :label="$t('alert.summary')" prop="summary">
<el-input maxlength="512" rows="3" type="textarea" show-word-limit placeholder="" v-model="editAlertRule.summary" size="small" id="alert-box-input-summary"></el-input> <el-input id="alert-box-input-summary" v-model="editAlertRule.summary" maxlength="512" placeholder="" rows="3" show-word-limit size="small" type="textarea"></el-input>
</el-form-item> </el-form-item>
<!--description--> <!--description-->
<el-form-item :label="$t('alert.description')" prop="description"> <el-form-item :label="$t('alert.description')" prop="description">
<el-input maxlength="512" rows="4" show-word-limit type="textarea" placeholder="" v-model="editAlertRule.description" size="small" id="alert-box-input-description"></el-input> <el-input id="alert-box-input-description" v-model="editAlertRule.description" maxlength="512" placeholder="" rows="4" show-word-limit size="small" type="textarea"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@@ -109,10 +109,10 @@
<!--底部按钮--> <!--底部按钮-->
<div class="right-box-bottom-btns"> <div class="right-box-bottom-btns">
<button v-cancel="{obj:editAlertRule,func:esc}" id="alert-box-esc" class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new"> <button id="alert-box-esc" v-cancel="{obj:editAlertRule,func:esc}" class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new">
<span>{{$t('overall.cancel')}}</span> <span>{{$t('overall.cancel')}}</span>
</button> </button>
<button :class="{'nz-btn-disabled':prevent_opt.save}" :disabled="prevent_opt.save" @click="save" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" id="alert-box-save"> <button id="alert-box-save" :class="{'nz-btn-disabled':prevent_opt.save}" :disabled="prevent_opt.save" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" @click="save">
<span>{{$t('overall.save')}}</span> <span>{{$t('overall.save')}}</span>
</button> </button>
</div> </div>
@@ -140,7 +140,7 @@ export default {
editAlertRule: {}, editAlertRule: {},
rules: { rules: {
alertName: [ name: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' } { required: true, message: this.$t('validate.required'), trigger: 'blur' }
], ],
expr: [ expr: [

View File

@@ -1,9 +1,9 @@
<template> <template>
<div class="right-box right-box-alert-config" v-clickoutside="{obj:editExprTemp,func:clickOutside}"> <div v-clickoutside="{obj:editExprTemp,func:clickOutside}" class="right-box right-box-alert-config">
<!-- begin--顶部按钮--> <!-- begin--顶部按钮-->
<div class="right-box-top-btns right-box-form-delete"> <div class="right-box-top-btns right-box-form-delete">
<button @click="del" class="nz-btn nz-btn-size-normal nz-btn-size-alien" id="alert-box-del" type="button" <button v-if="editExprTemp.id" id="alert-box-del" v-has="'alert_silence_delete'" class="nz-btn nz-btn-size-normal nz-btn-size-alien"
v-has="'alert_silence_delete'" v-if="editExprTemp.id"> type="button" @click="del">
<span class="right-box-top-btn-icon"><i class="nz-icon nz-icon-delete"></i></span> <span class="right-box-top-btn-icon"><i class="nz-icon nz-icon-delete"></i></span>
<span class="right-box-top-btn-txt">{{$t('overall.delete')}}</span> <span class="right-box-top-btn-txt">{{$t('overall.delete')}}</span>
</button> </button>
@@ -18,44 +18,44 @@
<!-- begin--表单--> <!-- begin--表单-->
<div class="right-box-form-box"> <div class="right-box-form-box">
<el-form class="right-box-form right-box-form-left" :model="editExprTemp" label-position="top" <el-form ref="ExprTempForm" :model="editExprTemp" :rules="rules"
label-width="120px" :rules="rules" ref="ExprTempForm"> class="right-box-form right-box-form-left" label-position="top" label-width="120px">
<el-form-item prop="name" :label="$t('config.exprTemp.name')"> <el-form-item :label="$t('config.exprTemp.name')" prop="name">
<el-input v-model="editExprTemp.name" size="small" :placeholder="$t('overall.placeHolder')"></el-input> <el-input v-model="editExprTemp.name" :placeholder="$t('overall.placeHolder')" size="small"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="gname" :label="$t('config.exprTemp.gname')"> <el-form-item :label="$t('config.exprTemp.gname')" prop="gname">
<!--<el-input v-model="editExprTemp.gname" size="small" :placeholder="$t('overall.placeHolder')"></el-input>--> <!--<el-input v-model="editExprTemp.gname" size="small" :placeholder="$t('overall.placeHolder')"></el-input>-->
<el-autocomplete <el-autocomplete
class="inline-input"
v-model="editExprTemp.gname" v-model="editExprTemp.gname"
:fetch-suggestions="querySearch" :fetch-suggestions="querySearch"
:placeholder="$t('overall.placeHolder')" :placeholder="$t('overall.placeHolder')"
class="inline-input"
size="small" size="small"
style="width: 100%;" style="width: 100%;"
></el-autocomplete> ></el-autocomplete>
</el-form-item> </el-form-item>
<el-form-item prop="expression" :label="$t('config.exprTemp.expression')"> <el-form-item :label="$t('config.exprTemp.expression')" prop="expression">
<!--<el-input v-model="editExprTemp.expression" size="small" :placeholder="$t('overall.placeHolder')"></el-input>--> <!--<el-input v-model="editExprTemp.expression" size="small" :placeholder="$t('overall.placeHolder')"></el-input>-->
<promql-input <promql-input
:expression-list="editExprTemp.expression"
:id="'promqlKeys0'" :id="'promqlKeys0'"
:index="0"
:key="'promqlKeys0'" :key="'promqlKeys0'"
:expression-list="editExprTemp.expression"
:index="0"
:plugins="['metric-selector', 'metric-input', 'remove']" :plugins="['metric-selector', 'metric-input', 'remove']"
:show-temp="false"
:showRemove="false" :showRemove="false"
:styleType="2" :styleType="2"
:show-temp="false"
@change="expressionChange" @change="expressionChange"
></promql-input> ></promql-input>
</el-form-item> </el-form-item>
<el-form-item prop="remark" :label="$t('config.exprTemp.remark')"> <el-form-item :label="$t('config.exprTemp.remark')" prop="remark">
<el-input <el-input
type="textarea"
:placeholder="$t('alert.description')"
v-model="editExprTemp.remark" v-model="editExprTemp.remark"
size="small" :placeholder="$t('alert.description')"
maxlength="512" maxlength="512"
show-word-limit show-word-limit
size="small"
type="textarea"
></el-input> ></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
@@ -65,12 +65,12 @@
<!--底部按钮--> <!--底部按钮-->
<div class="right-box-bottom-btns"> <div class="right-box-bottom-btns">
<button v-cancel="{obj:editExprTemp,func:esc}" id="alert-box-esc" <button id="alert-box-esc" v-cancel="{obj:editExprTemp,func:esc}"
class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new"> class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new">
<span>{{$t('overall.cancel')}}</span> <span>{{$t('overall.cancel')}}</span>
</button> </button>
<button :class="{'nz-btn-disabled':prevent_opt.save}" :disabled="prevent_opt.save" @click="save" <button id="alert-box-save" :class="{'nz-btn-disabled':prevent_opt.save}" :disabled="prevent_opt.save"
class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" id="alert-box-save"> class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" @click="save">
<span>{{$t('overall.save')}}</span> <span>{{$t('overall.save')}}</span>
</button> </button>
</div> </div>
@@ -227,7 +227,7 @@ export default {
} }
</script> </script>
<style scoped lang="scss"> <style lang="scss" scoped>
/deep/ .metric-selector-title{ /deep/ .metric-selector-title{
margin-left: 0 !important; margin-left: 0 !important;
} }

View File

@@ -1,62 +1,46 @@
<style lang="scss"> <style lang="scss">
@import '../../charts/chart'; @import '../../../charts/chart';
</style> </style>
<template> <template>
<div :class="{'contentTable':!projectAlertId,'relative-position':true,'contentProject':projectAlertId}"> <div>
<!-- 自定义table列 -->
<transition name="el-zoom-in-top">
<element-set
:id="id+'-element-set'"
v-if="tools.showCustomTableTitle"
@close="tools.showCustomTableTitle = false"
:custom-table-title.sync="tools.customTableTitle"
:original-table-title="tableTitle"
ref="customTableTitle"
:path="'/alertList'"
></element-set>
</transition>
<!--表格--> <!--表格-->
<el-table <el-table
class="nz-table tabelH100" id="alertMessageTable"
:data="tableData" ref="dataTable"
border
v-show="bottomBox.mainResizeShow"
ref="alertListTable"
tooltip-effect="light"
:height="tableHeight"
v-loading="tools.loading"
:cell-class-name="labelsClassName" :cell-class-name="labelsClassName"
@selection-change="selectChange" :data="tableData"
style="width: 100%;height: 100%" :height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort" @sort-change="tableDataSort"
:id="id+'-table'" @selection-change="selectChange"
> >
<el-table-column <el-table-column
:resizable="false" :resizable="false"
type="selection"
width="40"
align="center" align="center"
> type="selection"
width="55">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
:resizable="true" v-for="(item, index) in customTableTitle"
v-for="(item, index) in tools.customTableTitle"
v-if="item.show" v-if="item.show"
:key="`col-${index}`" :key="`col-${index}`"
:fixed="item.fixed"
:label="item.label" :label="item.label"
:show-overflow-tooltip="item.prop !== 'labels' && item.prop !== 'alertRule'" :min-width="`${item.minWidth}`"
:min-width="item.minWidth || item.width" :prop="item.prop"
:sortable="$tableSet.sortableShow(item.prop,'alertMessage')" :resizable="true"
:prop="$tableSet.propTitle(item.prop,'alertMessage')"
:sort-orders="['ascending', 'descending']" :sort-orders="['ascending', 'descending']"
:sortable="$tableSet.sortableShow(item.prop,'alertMessage')"
:width="`${item.width}`"
> >
<template slot-scope="scope" :column="item"> <template slot-scope="scope" :column="item">
<template v-if="item.prop === 'alertRule'"> <template v-if="item.prop === 'alertRule'">
<div v-if="scope.row.alertRule.alertName" > <div v-if="scope.row.alertRule.name" >
<span <span
@mouseenter="alertMessagehover(scope.row.alertRule, true, $event)" @mouseenter="alertMessageHover(scope.row.alertRule, true, $event)"
@mouseleave="alertMessagehover(scope.row.alertRule, false)" @mouseleave="alertMessageHover(scope.row.alertRule, false)"
>{{scope.row.alertRule.alertName}}</span> >{{scope.row.alertRule.name}}</span>
<alertRuleInfo v-if="scope.row.alertRule.loading" :id="scope.row.alertRule.id" :that="scope.row.alertRule"></alertRuleInfo> <alertRuleInfo v-if="scope.row.alertRule.loading" :id="scope.row.alertRule.id" :that="scope.row.alertRule"></alertRuleInfo>
</div> </div>
<template v-else>-</template> <template v-else>-</template>
@@ -75,15 +59,12 @@
</template> </template>
<span v-else-if="item.prop === 'severity'" class="severity"> <span v-else-if="item.prop === 'severity'" class="severity">
<span v-if="scope.row[item.prop] === 'P1'" class="P1">P1</span> <span v-if="scope.row[item.prop] === 'P1'" class="P1">P1</span>
<!--<i class="nz-icon nz-icon-arrow-up"></i> {{returnSeverityLabel(scope.row[item.prop])}}-->
<span v-if="scope.row[item.prop] === 'P2'" class="P2">P2</span> <span v-if="scope.row[item.prop] === 'P2'" class="P2">P2</span>
<!--{{returnSeverityLabel(scope.row[item.prop])}}-->
<span v-if="scope.row[item.prop] === 'P3'" class="P3">P3</span> <span v-if="scope.row[item.prop] === 'P3'" class="P3">P3</span>
<!--<i class="nz-icon nz-icon-arrow-down"></i>&nbsp;{{returnSeverityLabel(scope.row[item.prop])}}-->
</span> </span>
<span v-else-if="item.prop === 'startAt'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span> <span v-else-if="item.prop === 'startAt'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<template v-else-if="item.prop === 'duration'"> <template v-else-if="item.prop === 'duration'">
<el-tooltip placement="right" effect="light" :disabled="!scope.row.endAt"> <el-tooltip :disabled="!scope.row.endAt" effect="light" placement="right">
<div slot="content"> <div slot="content">
{{$t('config.terminallog.endTime')}}<br/> {{$t('config.terminallog.endTime')}}<br/>
{{scope.row.endAt}} {{scope.row.endAt}}
@@ -97,10 +78,10 @@
@mouseenter="labelHover(scope.row, item.label, true, $event)" @mouseenter="labelHover(scope.row, item.label, true, $event)"
@mouseleave="labelHover(scope.row, item.label, false)"> @mouseleave="labelHover(scope.row, item.label, false)">
<nz-alert-tag <nz-alert-tag
:label="item.label" :type="tagType(item.label)" style="margin: 5px 0 5px 5px;" v-if="item.label !== 'alertname' && item.label !== 'severity'" :key="item.label" :cursor-point="tagType(item.label) !== 'info'"
v-if="item.label !== 'alertname' && item.label !== 'severity'" :label="item.label"
:key="item.label" :type="tagType(item.label)"
:cursor-point="tagType(item.label) !== 'info'" style="margin: 5px 0 5px 5px;"
> >
{{item.value}} {{item.value}}
</nz-alert-tag> </nz-alert-tag>
@@ -112,33 +93,6 @@
:type="item.label" :type="item.label"
></alertLabel> ></alertLabel>
</span> </span>
<!--<el-tooltip
v-for="(item,i) in labelsSort(scope.row.labels)"
:placement="scope.$index==0?'right-start':(scope.$index==tableData.length-1?'right-end':'right')"
effect="light"
:disabled="!(item.label === 'asset' ||item.label === 'module' || item.label === 'project')"
:key="item.label"
>
<alertLabel
v-if="item.label === 'asset' ||item.label === 'module' || item.label === 'project'"
slot="content"
:id="scope.row[item.label].id"
:type="item.label"
:labelLoading="scope.row[item.label].loading"
></alertLabel>
<span @mouseover="labelHover(scope.row,scope.$index,item.label)" >
<nz-alert-tag
:label="item.label" :type="tagType(item.label)" style="margin: 5px 0 5px 5px;"
:cursor-point="tagType(item.label) == 'info' ? false : true"
:key="item.label"
v-if="item.label != 'alertname' && item.label != 'severity'"
>
{{item.value}}
</nz-alert-tag>
</span>
</el-tooltip>-->
</template> </template>
<span v-else-if="item.prop === 'state'" :class="{'green': scope.row['state'] == 2, 'red': scope.row['state'] == 1}"> <span v-else-if="item.prop === 'state'" :class="{'green': scope.row['state'] == 2, 'red': scope.row['state'] == 1}">
{{scope.row['state'] == 1 ? "Pending" : ""}} {{scope.row['state'] == 1 ? "Pending" : ""}}
@@ -148,141 +102,56 @@
<span v-if="!scope.row.current || scope.row.alertRule.buildIn == 1">-</span> <span v-if="!scope.row.current || scope.row.alertRule.buildIn == 1">-</span>
<el-popover v-else placement="right" trigger="hover"> <el-popover v-else placement="right" trigger="hover">
<div slot="reference"> <div slot="reference">
<span class="content-right-option" :id="'alert-list-detail-'+scope.row.id"><i class="nz-icon nz-icon-chart"></i></span> <span :id="'alert-list-detail-'+scope.row.id" class="content-right-option"><i class="nz-icon nz-icon-chart"></i></span>
<span>{{formatThreshold(scope.row.current[1],scope.row.alertRule.unit)}}</span> <span>{{formatThreshold(scope.row.current[1],scope.row.alertRule.unit)}}</span>
</div> </div>
<div>{{$unixTimeParseToString(scope.row.current[0])}}</div> <div>{{$unixTimeParseToString(scope.row.current[0])}}</div>
</el-popover> </el-popover>
</div> </div>
<div v-else-if="item.prop === 'option'" class="content-right-options">
<span :id="'alert-list-delete-'+scope.row.id" :title="$t('overall.delete')" @click="toDeleteMessage(scope.row)" class="content-right-option" v-has="`${from}_delete`"><i class="nz-icon nz-icon-delete"></i></span>
</div>
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</span> <span v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</span>
<template v-else>-</template> <template v-else>-</template>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column
<el-table-column width="28" :resizable="true"> :resizable="false"
<template slot="header"> :width="operationWidth"
<span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)" class="nz-table-gear"> fixed="right">
<i class="nz-icon nz-icon-gear"></i> <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
</span> <div slot-scope="scope" class="table-operation-items">
</template> <button class="table-operation-item" @click="toDeleteMessage(scope.row)"><i class="nz-icon nz-icon-delete"></i></button>
</div>
</el-table-column> </el-table-column>
</el-table> </el-table>
<button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn && bottomBox.mainResizeShow &&showTopBtn"><i class="nz-icon nz-icon-top"></i></button>
<!--<弹窗>-->
<!--导出-->
<div class="export-xlsx">
<el-dialog :visible.sync="importBox.show" :title="importBox.title" :modal-append-to-body='false' :show-close="true" width="300px" @close="closeDialog" class="nz-dialog">
<div class="upload-body">
<button @click="exportCur" class="el-button el-button--default el-button--small">
<span>{{$t('overall.exportCur')}}</span>
</button>
<button @click="exportAll" class="el-button el-button--default el-button--small">
<span>{{$t('overall.exportAll')}}</span>
</button>
</div>
</el-dialog>
</div>
<!--删除弹窗-->
<div class="export-xlsx">
<el-dialog :visible.sync="deleteBox.show" :title="$t('alert.list.remark')" :modal-append-to-body='false' :show-close="true" width="450px" @close="closeDialog" class="nz-message" @opened="openedDialog">
<div class="upload-body">
<el-form ref="remarkForm" :model="deleteBox">
<el-form-item prop="remark" :rules="[{required:true,message: $t('validate.required'), trigger: 'change'}]">
<el-input type="textarea" :placeholder="$t('alert.description')" v-model="deleteBox.remark"></el-input>
</el-form-item>
</el-form>
<div style="text-align: right; margin-top: 10px;">
<button @click="closeDialog" class="el-button el-button--default el-button--small">
<span>{{$t('tip.no')}}</span>
</button>
<button @click="deleteMessage" class="el-button el-button--default el-button--small el-button--primary">
<span>{{$t('tip.yes')}}</span>
</button>
</div>
</div>
</el-dialog>
</div>
<el-dialog class="line-chart-block-modal nz-dialog endpoint-dialog"
:title="$t('overall.detail')"
:visible.sync="graphShow"
width="90%"
id="viewGraphDialog"
@close="dialogClose"
:modal-append-to-body='false'>
<div slot="title">
{{$t("project.endpoint.dialogTitle")}}
<div class="float-right panel-calendar dialog-tool" style="display: flex">
<pick-time :refresh-data-func="queryChartDate" :use-refresh="false" :use-chart-unit="false" v-model="searchTime" style="height: 28px;" @unitChange="chartUnitChange"></pick-time>
</div>
</div>
<chart ref="messageChart" name="alertMessageChart" :unit="chartUnit"></chart>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import bus from '../../../libs/bus' import bus from '../../../../libs/bus'
import axios from 'axios' import axios from 'axios'
import nzAlertTag from '../../page/alert/nzAlertTag' import table from '@/components/common/mixin/table'
import chart from '../../page/dashboard/overview/chart' import nzAlertTag from '../../../page/alert/nzAlertTag'
import chartDataFormat from '../../charts/chartDataFormat' import chartDataFormat from '../../../charts/chartDataFormat'
import alertRuleInfo from '../../common/alert/alertRuleInfo' import alertRuleInfo from '../../alert/alertRuleInfo'
import alertLabel from '../../common/alert/alertLabel' import alertLabel from '../../alert/alertLabel'
import { calcDurationByStringTimeB } from '../js/tools' import { calcDurationByStringTimeB } from '../../js/tools'
export default { export default {
name: 'alertMessageTable', name: 'alertMessageTable',
components: { components: {
'nz-alert-tag': nzAlertTag, nzAlertTag,
chart: chart,
alertRuleInfo: alertRuleInfo, alertRuleInfo: alertRuleInfo,
alertLabel: alertLabel alertLabel: alertLabel
}, },
mixins: [bus],
props: { props: {
tableData: {}, nowTime: {
loading: {}, type: String
tableHeight: {}, }
tableId: {},
projectAlertId: {},
showTopBtn: {
type: Boolean,
default: true
},
from: { type: String },
id: String,
nowTime: {}
}, },
mixins: [table, bus],
data () { data () {
return { return {
/* 二级列表相关 */ /* 二级列表相关 */
tabList: [], // tabList: [], //
tabDetailList: [], // tabDetailList: [], //
bottomBox: {
tabList: [], //
tabDetailList: [], //
mainResizeShow: true, // dom|
subResizeShow: true,
isFullScreen: false, //
showSubList: false, //
targetTab: '', //
inTransform: false // transform
},
/* 工具参数 */
tools: {
loading: false, // table
toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-toptop
tableHover: false, // top
showTopBtn: false, // To top
showCustomTableTitle: false, //
customTableTitle: [] //
},
//
importBox: { show: false, title: this.$t('overall.exportExcel') },
deleteBox: { show: false, ids: '', remark: '', state: 2 },
// //
graphShow: false, graphShow: false,
@@ -292,11 +161,6 @@ export default {
searchTime: [new Date().setHours(new Date().getHours() - 1), new Date()], searchTime: [new Date().setHours(new Date().getHours() - 1), new Date()],
currentMsg: {}, currentMsg: {},
chartUnit: 5, chartUnit: 5,
pageObj: {
pageNo: 1,
pageSize: this.$CONSTANTS.defaultPageSize,
total: 0
},
tableTitle: [ tableTitle: [
{ {
label: 'ID', label: 'ID',
@@ -344,13 +208,7 @@ export default {
prop: 'startAt', prop: 'startAt',
show: true, show: true,
width: 150 width: 150
}, /* { }, {
label: this.$t('alert.endAt'),
prop: 'endAt',
show: true,
width: 150
}, */
{
label: this.$t('config.terminallog.duration'), label: this.$t('config.terminallog.duration'),
prop: 'duration', prop: 'duration',
show: true, show: true,
@@ -360,19 +218,9 @@ export default {
prop: 'current', prop: 'current',
show: true, show: true,
width: 100 width: 100
}, {
label: this.$t('overall.option'),
prop: 'option',
show: true,
width: 90
} }
], ],
viewProjectData: { id: '', name: '', remark: '' },
viewModuleData: { id: '', name: '', project: {}, port: '', path: '', param: '', paramObj: [] },
viewAssetState: false, viewAssetState: false,
scrollbarWrap: null,
delFlag: false,
tableDataInitNum: 0 tableDataInitNum: 0
} }
}, },
@@ -410,7 +258,7 @@ export default {
} }
}, },
methods: { methods: {
labelsSort: function (obj) { labelsSort (obj) {
const buildIn = ['asset', 'endpoint', 'module', 'project', 'datacenter'] const buildIn = ['asset', 'endpoint', 'module', 'project', 'datacenter']
if (typeof obj === 'string') obj = JSON.parse(obj) if (typeof obj === 'string') obj = JSON.parse(obj)
const labels = JSON.parse(JSON.stringify(obj)) const labels = JSON.parse(JSON.stringify(obj))
@@ -426,14 +274,7 @@ export default {
}) })
return result return result
}, },
chartUnitChange: function (unit) { formatThreshold (value, unit) {
this.chartUnit = unit
this.$nextTick(() => {
this.queryChartDate()
})
},
formatThreshold: function (value, unit) {
const unitMethod = chartDataFormat.getUnit(unit) const unitMethod = chartDataFormat.getUnit(unit)
if (unitMethod && value) { if (unitMethod && value) {
return unitMethod.compute(value, null, 2) return unitMethod.compute(value, null, 2)
@@ -485,7 +326,7 @@ export default {
symbol: ['circle', 'circle'], symbol: ['circle', 'circle'],
label: { label: {
distance: this.computeDistance(chartDataFormat.getUnit(this.currentMsg.alertRule.unit ? this.currentMsg.alertRule.unit : 2).compute(this.currentMsg.alertRule.threshold)), distance: this.computeDistance(chartDataFormat.getUnit(this.currentMsg.alertRule.unit ? this.currentMsg.alertRule.unit : 2).compute(this.currentMsg.alertRule.threshold)),
formatter: function (params) { formatter (params) {
return chartDataFormat.getUnit($temp.currentMsg.alertRule.unit ? $temp.currentMsg.alertRule.unit : 2).compute(params.value) return chartDataFormat.getUnit($temp.currentMsg.alertRule.unit ? $temp.currentMsg.alertRule.unit : 2).compute(params.value)
} }
}, },
@@ -548,7 +389,7 @@ export default {
}) })
} }
}, },
computeDistance: function (str) { computeDistance (str) {
let width = 0 let width = 0
const html = document.createElement('span') const html = document.createElement('span')
html.innerText = str html.innerText = str
@@ -558,7 +399,7 @@ export default {
document.querySelector('.getTextWidth').remove() document.querySelector('.getTextWidth').remove()
return Number('-' + (width + 5)) return Number('-' + (width + 5))
}, },
returnMarkArea: function () { returnMarkArea () {
if (this.currentMsg) { if (this.currentMsg) {
if (this.currentMsg.alertRule.operator == '>' || this.currentMsg.alertRule.operator == '>=') { if (this.currentMsg.alertRule.operator == '>' || this.currentMsg.alertRule.operator == '>=') {
return [{ yAxis: this.currentMsg.alertRule.threshold }, {}] return [{ yAxis: this.currentMsg.alertRule.threshold }, {}]
@@ -578,9 +419,7 @@ export default {
this.queryChartDate() this.queryChartDate()
}) })
}, },
dialogClose () {
this.graphShow = false
},
getAlertList () { getAlertList () {
if (!this.scrollbarWrap) { if (!this.scrollbarWrap) {
this.$nextTick(() => { this.$nextTick(() => {
@@ -653,23 +492,7 @@ export default {
} }
}, },
toDeleteMessage (obj) { toDeleteMessage (obj) {
if (obj) { this.$emit('toDelete', obj)
this.deleteBox.ids = obj.id + ''
}
this.deleteBox.remark = ''
this.deleteBox.show = true
},
deleteMessage () {
this.$refs.remarkForm.validate(valid => {
if (valid) {
this.delFlag = true
this.$emit('deleteMessage', this.deleteBox, () => {
this.deleteBox.ids = []
bus.$emit('alert-message-change')
})
this.deleteBox.show = false
}
})
}, },
selectChange (s) { selectChange (s) {
const ids = [] const ids = []
@@ -680,30 +503,11 @@ export default {
this.deleteBox.ids = ids.join(',') this.deleteBox.ids = ids.join(',')
this.$emit('select-change', s) this.$emit('select-change', s)
}, },
showExportDialog () {
this.importBox.show = true
},
openedDialog () {
this.$refs.remarkForm.clearValidate()
},
closeDialog () { closeDialog () {
this.importBox.show = false this.importBox.show = false
this.deleteBox.show = false this.deleteBox.show = false
}, },
exportCur: function () { getTimeString () {
const searchLabel = Object.assign({}, this.searchLabel)
this.$set(searchLabel, 'language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en')
this.exportExcel(searchLabel)
this.closeDialog()
},
exportAll: function () {
const temp = JSON.parse(JSON.stringify(this.searchLabel))
temp.pageSize = -1
this.$set(temp, 'language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en')
this.exportExcel(temp)
this.closeDialog()
},
getTimeString: function () {
const split = '-' const split = '-'
const date = new Date() const date = new Date()
const year = date.getFullYear() const year = date.getFullYear()
@@ -714,74 +518,9 @@ export default {
const seconds = this.formatNum(date.getSeconds()) const seconds = this.formatNum(date.getSeconds())
return year + split + month + split + day + ' ' + hours + split + minutes + split + seconds return year + split + month + split + day + ' ' + hours + split + minutes + split + seconds
}, },
formatNum: function (num) { formatNum (num) {
return num > 9 ? num : '0' + num return num > 9 ? num : '0' + num
}, },
exportExcel: function (params) {
for (const item in params) {
if (params[item]) {
if (item == 'alertMessageState') {
this.$set(params, 'state', params[item])
} else {
this.$set(params, item, params[item])
}
}
}
const temp = this
if (!params) {
params = temp.params
}
axios.get('alert/message/export', { responseType: 'blob', params: params }).then(res => {
const fileName = 'alert-message-' + temp.getTimeString() + '.xlsx'
if (window.navigator.msSaveOrOpenBlob) {
// ie11
const blobObject = new Blob([res.data])
window.navigator.msSaveOrOpenBlob(blobObject, fileName)
} else {
const url = URL.createObjectURL(new Blob([res.data]))
const a = document.createElement('a')
document.body.appendChild(a) // body
a.href = url
a.download = fileName
a.target = '_blank'
a.click()
a.remove() // a
}
})
},
//
fullScreen () {
const vm = this
this.$bottomBoxWindow.fullScreen(vm)
},
// 退
exitFullScreen () {
const vm = this
this.$bottomBoxWindow.exitFullScreen(vm)
},
//
listResize (e) {
const vm = this
this.$bottomBoxWindow.listResize(vm, e)
},
showTagDetail (data, key) {
let open = false
if (key == 'asset' || key == 'project' || key == 'module' || key == 'endpoint' || key == 'datacenter') {
open = true
}
if (open) {
const labelList = []
const detailList = []
for (const item in data) {
if (item == 'asset' || item == 'project' || item == 'module' || item == 'endpoint' || item == 'dc') {
labelList.push(item)
detailList.push(data[item])
}
}
this.bottomBox.showSubList = true
this.tabList = labelList
}
},
labelsClassName (row) { labelsClassName (row) {
if (row.column.label == this.$t('alert.list.labels')) { if (row.column.label == this.$t('alert.list.labels')) {
return 'alert-message-list-labels' return 'alert-message-list-labels'
@@ -795,27 +534,12 @@ export default {
return '' return ''
} }
}, },
fillProject: function (module) { closeViews () {
this.$get('project', { id: module.projectId }).then(response => {
if (response.code == 200) {
module.project = response.data.list[0]
}
})
},
closeViews: function () {
this.$refs.alertConfigBox.show(false, false) this.$refs.alertConfigBox.show(false, false)
this.$refs.projectBox.show(false, false) this.$refs.projectBox.show(false, false)
this.$refs.moduleBox.show(false, false) this.$refs.moduleBox.show(false, false)
this.viewAssetState = false this.viewAssetState = false
}, },
//
tableDataSort (item) {
this.$emit('tableDataSort', item)
},
pageNo (val) {
this.pageObj.pageNo = val
this.getTableData()
},
// label tooltip // label tooltip
labelToolTipDis (labelType) { labelToolTipDis (labelType) {
switch (labelType) { switch (labelType) {
@@ -827,8 +551,8 @@ export default {
default: return true default: return true
} }
}, },
// alertNmae // alertName
alertMessagehover (item, loading, e) { alertMessageHover (item, loading, e) {
if (e) { if (e) {
const dom = e.currentTarget const dom = e.currentTarget
const position = dom.getBoundingClientRect() const position = dom.getBoundingClientRect()
@@ -864,74 +588,6 @@ export default {
self.tools.tableHover = false; self.tools.tableHover = false;
} }
}, */ }, */
},
watch: {
showSubList (n) {
const vm = this
this.$bottomBoxWindow.showSubListWatch(vm, n)
},
loading: {
handler: function (n, o) {
this.tools.loading = n
},
immediate: true,
deep: true
},
tableData: {
deep: true,
handler (n) {
if (n.length === 0 && this.pageObj.pageNo > 1) {
this.pageNo(this.pageObj.pageNo - 1)
}
if (!this.delFlag) {
this.$refs.alertListTable.bodyWrapper.scrollTop = 0
}
this.tableDataInitNum++//
if (this.tableDataInitNum === 2) {
this.tableDataInitNum = 0
this.delFlag = false
}
}
}
},
mounted () {
//
this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + '/alertList')
? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + '/alertList'))
: this.tableTitle
this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
//
const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
if (pageSize != 'undefined' && pageSize != null) {
this.pageObj.pageSize = pageSize
}
this.getAlertList()
/* if(this.from=='alertMessage'){
this.tablelable = localStorage.getItem("nz-tableTitle-" + localStorage.getItem("nz-username") + "-" + this.$route.path)
? JSON.parse(localStorage.getItem("nz-tableTitle-" + localStorage.getItem("nz-username") + "-" + this.$route.path))
: this.tableTitle;
this.dropCol = localStorage.getItem("nz-tableTitle-" + localStorage.getItem("nz-username") + "-" + this.$route.path)
? JSON.parse(localStorage.getItem("nz-tableTitle-" + localStorage.getItem("nz-username") + "-" + this.$route.path))
: this.tableTitle;
}
if(this.from=='alertMessageTab' || this.from=='chartList'){
this.tablelable = localStorage.getItem("nz-tableTitle-" + localStorage.getItem("nz-username") + "-/alertList")
? JSON.parse(localStorage.getItem("nz-tableTitle-" + localStorage.getItem("nz-username") + "-/alertList"))
: this.tableTitle;
this.dropCol = localStorage.getItem("nz-tableTitle-" + localStorage.getItem("nz-username") + "-/alertList")
? JSON.parse(localStorage.getItem("nz-tableTitle-" + localStorage.getItem("nz-username") + "-/alertList"))
: this.tableTitle;
}
*/
},
beforeDestroy () {
if (this.scrollbarWrap) {
if (this.scrollbarWrap) {
this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
}
}
} }
} }

View File

@@ -0,0 +1,169 @@
<template>
<el-table
id="alertRuleTable"
ref="dataTable"
:data="tableData"
:height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:min-width="`${item.minWidth}`"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<span v-if="item.prop === 'severity'" class="severity">
<span v-if="scope.row[item.prop] == 'P1'" class="P1">P1</span>
<span v-if="scope.row[item.prop] == 'P2'" class="P2">P2</span>
<span v-if="scope.row[item.prop] == 'P3'" class="P3">P3</span>
</span>
<template v-else-if="item.prop === 'alertNum'">
<span class="link" @click="queryMessage(scope.row)">{{scope.row.alertNum + ' ' + $t('overall.active')}}</span>
</template>
<template v-else-if="item.prop === 'threshold'">{{formatThreshold(scope.row[item.prop], scope.row.unit)}}</template>
<template v-else-if="item.prop === 'receivers'">
<el-tag v-for="(user, index) in scope.row[item.prop]" v-if="user.userName" :key="index" class="alert-rule-tag" effect="dark" size="mini">{{user.userName}}&nbsp;</el-tag>
</template>
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</span>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" @click="showBottomBox('detail', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span></span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['edit', scope.row]" :disabled="isBuiltIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
<el-dropdown-item :command="['delete', scope.row]" :disabled="isBuiltIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
</template>
<script>
import table from '@/components/common/mixin/table'
import chartDataFormat from '@/components/charts/chartDataFormat'
export default {
name: 'roleTable',
mixins: [table],
data () {
return {
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('alert.alertName'),
prop: 'name',
show: true
}, {
label: this.$t('alert.config.expr'),
prop: 'expr',
show: true
}, {
label: this.$t('alert.config.operator'),
prop: 'operator',
show: true
}, {
label: this.$t('alert.config.threshold'),
prop: 'threshold',
show: true
}, {
label: this.$t('alert.config.for'),
prop: 'last',
show: true
}, {
label: this.$t('alert.severity'),
prop: 'severity',
show: true
}, {
label: this.$t('alert.summary'),
prop: 'summary',
show: true
}, {
label: this.$t('alert.description'),
prop: 'description',
show: true
}, {
label: this.$t('alert.message'),
prop: 'alertNum',
show: true,
width: 90
}, {
label: this.$t('alert.config.receiver'),
prop: 'receivers',
show: true
}
]
}
},
methods: {
queryMessage (row) {
this.$emit('queryMessage', row)
},
formatThreshold (value, unit) {
const unitMethod = chartDataFormat.getUnit(unit)
if (unitMethod && value) {
return unitMethod.compute(value, null, 2)
} else {
return value
}
}
}
}
</script>
<style>
.severity .P1{
background: #F5846A;
border-radius: 2px;
font-size: 12px;
color: #FFFFFF;
padding: 2px 6px;
}
.severity .P2{
background: #F7A54A;
border-radius: 2px;
font-size: 12px;
color: #FFFFFF;
padding: 2px 6px;
}
.severity .P3{
background: #F1C13D;
border-radius: 2px;
font-size: 12px;
color: #FFFFFF;
padding: 2px 6px;
}
</style>

View File

@@ -0,0 +1,224 @@
<template>
<el-table
id="alertSilenceTable"
ref="dataTable"
:data="tableData"
:height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:min-width="`${item.minWidth}`"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<template v-if="item.prop === 'duration'">
<el-tooltip :disabled="!scope.row.endAt" effect="light" placement="right">
<div slot="content">
{{$t('config.terminallog.endTime')}}<br/>
{{scope.row.endAt}}
</div>
<span>{{getDuration(scope.row)}}</span>
</el-tooltip>
</template>
<template v-else-if="item.prop === 'matchers'">
<div class="nz-silence-tag-box">
<span v-if="scope.row.linkId!==-1" class="nz-silence-tag blue">
<span class="nz-silence-tag-title">{{scope.row.type}}</span>
<span :title="scope.row.linkName" class="nz-silence-tag-content">{{scope.row.linkName}}</span>
</span>
<span v-if="scope.row.ruleId!==-1" class="nz-silence-tag rule-gray">
<span class="nz-silence-tag-title">Alert rule</span>
<span :title="scope.row.ruleName" class="nz-silence-tag-content">{{scope.row.ruleName}}</span>
</span>
</div>
</template>
<template v-else-if="item.prop === 'state'">
<span v-if="scope.row.state===1" class="silence-pending">pending</span>
<span v-if="scope.row.state===2" class="silence-active">active</span>
<span v-if="scope.row.state===3" class="silence-expired">expired</span>
</template>
<template v-else-if="item.prop === 'utime'">
{{utcTimeToTimezoneStr(scope.row[item.prop])}}
</template>
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop] || '-'}}</span>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" @click="copyRow(scope.row,'alertSilence')"><i class="nz-icon nz-icon-override"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span></span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['edit', scope.row]"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
<el-dropdown-item :command="['delete', scope.row]"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('buttons.expire')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
</template>
<script>
import table from '@/components/common/mixin/table'
import { calcDurationByStringTimeB } from '@/components/common/js/tools'
export default {
name: 'alertSilenceTable',
mixins: [table],
data () {
return {
/* 表格相关 */
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: 'matchers',
prop: 'matchers',
show: true
}, {
label: 'Start time',
prop: 'startAt',
show: true,
width: 300
}, {
label: this.$t('config.terminallog.duration'),
prop: 'duration',
show: true,
width: 120
}, {
label: 'Reason',
prop: 'reason',
show: true,
width: 120
}, {
label: 'Update time',
prop: 'utime',
show: true,
width: 120
}, {
label: 'State',
prop: 'state',
show: true,
width: 120
}
]
}
},
computed: {
getDuration () {
return function (record) {
if (record.endAt) {
return calcDurationByStringTimeB(record.startAt, record.endAt)
}
return calcDurationByStringTimeB(record.startAt, this.nowTime)
}
}
}
}
</script>
<style lang="scss" scoped>
.nz-silence-tag-box{
width: 100%;
height: 100%;
.nz-silence-tag{
/*float: left;*/
/*margin-top: 5px;*/
}
}
.nz-silence-tag{
min-width: 80px;
margin-right: 5px;
border-radius: 4px;
display: inline-flex;
width: auto;
height: 20px;
line-height: 20px;
.nz-silence-tag-title{
color: #fff;
text-align: center;
padding: 0 5px;
}
.nz-silence-tag-content{
padding: 0 10px;
max-width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
}
}
.nz-silence-tag.blue{
border: 1px solid #3C92F1;
.nz-silence-tag-title{
background: #3C92F1;
}
}
.nz-silence-tag.rule-gray{
border: 1px solid #7F8696;
.nz-silence-tag-title{
background: #7F8696;
}
}
.silence-active{
background: #E3F2D9;
border-radius: 4px;
font-family: PingFangSC-Regular;
font-size: 14px;
color: #0AB000;
line-height: 14px;
font-weight: 400;
padding: 0 5px;
}
.silence-pending{
background: #FFECD9;
border-radius: 4px;
font-family: PingFangSC-Regular;
font-size: 14px;
color: #FA901C;
line-height: 20px;
font-weight: 400;
padding: 0 5px;
}
.silence-expired{
background: #9e9c98;
border-radius: 4px;
font-family: PingFangSC-Regular;
font-size: 14px;
color: #ffffff;
line-height: 14px;
font-weight: 400;
padding: 0 5px;
}
</style>

View File

@@ -9,11 +9,11 @@
<slot name="top-tool-left"></slot> <slot name="top-tool-left"></slot>
</div> </div>
<div :class="{'top-tool-main-right-to-left': bottomBox.showSubList}" class="top-tool-main-right"> <div :class="{'top-tool-main-right-to-left': bottomBox.showSubList}" class="top-tool-main-right">
<div v-if="layout.indexOf('searchInput') > -1" class="top-tool-search"> <div v-if="layout.indexOf('searchInput') > -1" class="top-tool-search margin-r-20">
<search-input ref="searchInput" :inTransform="bottomBox.inTransform" :searchMsg="searchMsg" @search="search"></search-input> <search-input ref="searchInput" :inTransform="bottomBox.inTransform" :searchMsg="searchMsg" @search="search"></search-input>
</div> </div>
<slot name="top-tool-right"></slot> <slot name="top-tool-right"></slot>
<button v-if="layout.indexOf('elementSet') > -1" id="account-column-setting" class="top-tool-btn margin-l-10" <button v-if="layout.indexOf('elementSet') > -1" id="account-column-setting" class="top-tool-btn"
type="button" @click="tools.showCustomTableTitle = true"> type="button" @click="tools.showCustomTableTitle = true">
<i class="nz-icon-gear nz-icon"></i> <i class="nz-icon-gear nz-icon"></i>
</button> </button>

View File

@@ -0,0 +1,130 @@
<template>
<el-table
id="roleTable"
ref="dataTable"
:data="tableData"
:height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:min-width="`${item.minWidth}`"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<span v-if="item.prop === 'dc'" >{{scope.row[item.prop]?scope.row[item.prop].name:'-'}}</span>
<span v-else-if="item.prop === 'type'">
{{findServerType(scope.row[item.prop]).text}}
</span>
<span v-else-if="item.prop === 'checkTime'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<span v-else-if="item.prop === 'status'">
<el-popover :content="$t('asset.assetStatPre')+(scope.row.checkTime?utcTimeToTimezoneStr(scope.row.checkTime):$t('asset.assetStatDown'))" placement="right" trigger="hover" width="200">
<div slot="reference" style="width: 20px">
<div :class="{'active-icon green':scope.row[item.prop] == '1','active-icon red':scope.row[item.prop] == '0' || scope.row[item.prop] == '-1' || scope.row[item.prop] == '-2'}"></div>
</div>
</el-popover>
</span>
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</span>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" @click="tableOperation(['edit', scope.row])"><i class="nz-icon nz-icon-edit"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span></span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['delete', scope.row]" :disabled="isBuiltIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
</template>
<script>
import table from '@/components/common/mixin/table'
import { agent } from '@/components/common/js/constants'
export default {
name: 'agentTable',
mixins: [table],
data () {
return {
agent: agent,
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.dc.dc'),
prop: 'dc',
show: true
}, {
label: 'Host',
prop: 'host',
show: true
}, {
label: 'Port',
prop: 'port',
show: true
}, {
label: this.$t('config.agent.type'),
prop: 'type',
show: true
}, {
label: this.$t('asset.state'),
prop: 'status',
show: true
}, {
label: this.$t('config.agent.checkTime'),
prop: 'checkTime',
show: false
}
]
}
},
methods: {
findServerType (type) {
if (!this.promServerType) {
this.promServerType = []
this.agent.theData.forEach(item => {
this.promServerType = this.promServerType.concat(item.children)
})
}
return this.promServerType.find(item => {
return item.value == type
})
}
}
}
</script>

View File

@@ -0,0 +1,163 @@
<template>
<el-table
id="roleTable"
ref="dataTable"
:data="tableData"
:height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:min-width="`${item.minWidth}`"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<template v-if="item.prop === 'principal'">
<template v-if="scope.row.principal">
<template v-for="item in userData">
<template v-if="scope.row.principal == item.userId">{{item.username}}</template>
</template>
</template>
<template v-else>-</template>
</template>
<template v-else-if="item.prop === 'state'">
<el-switch
v-model="scope.row.state"
:disabled="!hasButton('dc_toEdit') || !hasButton('dc_toEdit')"
active-color="#ee9d3f"
active-value="ON"
inactive-value="OFF"
@change="(val)=>{statusChange(scope.row)}"
/>
</template>
<template v-else-if="item.prop === 'longitude'">
<template v-if="regNumTest(scope.row.longitude)">{{scope.row.longitude}}</template>
<template v-else>-</template>
</template>
<template v-else-if="item.prop === 'latitude'">
<template v-if="regNumTest(scope.row.latitude)">{{scope.row.latitude}}</template>
<template v-else>-</template>
</template>
<template v-else-if="item.prop === 'assetStat' && scope.row.assetStat">
<el-popover
:content="$t('overall.result.total') + '' + scope.row.assetStat.total + '' + $t('asset.inStock') + '' + scope.row.assetStat.inStock + '' + $t('asset.notInStock') + '' + scope.row.assetStat.outStock + '' + $t('asset.suspended') + '' + scope.row.assetStat.suspended"
placement="top"
trigger="hover">
<div slot="reference" class="dc-asset-states">
<span class="dc-asset-state dc-asset-state-total">{{scope.row.assetStat.total}}</span>
<span class="dc-asset-state dc-asset-state-in">{{scope.row.assetStat.inStock}}</span>
<span class="dc-asset-state dc-asset-state-out">{{scope.row.assetStat.outStock}}</span>
<span class="dc-asset-state dc-asset-state-suspended">{{scope.row.assetStat.suspended}}</span>
</div>
</el-popover>
</template >
<template v-else-if="item.prop === 'cabinetNum'">
<span class="link" @click="showBottomBox('cabinet', scope.row)">{{scope.row[item.prop]}}</span>
</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
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" @click="tableOperation(['edit', scope.row])"><i class="nz-icon nz-icon-edit"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span></span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['delete', scope.row]" :disabled="isBuiltIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
</template>
<script>
import table from '@/components/common/mixin/table'
export default {
name: 'dcTable',
mixins: [table],
data () {
return {
regNum: /^[0-9]+.?[0-9]*/,
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('overall.name'),
prop: 'name',
show: true
}, {
label: this.$t('asset.location'),
prop: 'location',
show: true
}, {
label: this.$t('config.dc.cabinetNum'),
prop: 'cabinetNum',
show: true
}, {
label: this.$t('config.dc.assets'),
prop: 'assetStat',
show: true
}, {
label: this.$t('asset.tel'),
prop: 'tel',
show: true
}, {
label: this.$t('asset.principal'),
prop: 'principal',
show: true
}, {
label: this.$t('config.dc.longitude'),
prop: 'longitude',
show: false
}, {
label: this.$t('config.dc.latitude'),
prop: 'latitude',
show: false
}, {
label: this.$t('config.dc.state'),
prop: 'state',
show: true
}
]
}
},
methods: {
regNumTest (val) { // 校验是否是数字
return this.regNum.test(val)
}
}
}
</script>

View File

@@ -0,0 +1,95 @@
<template>
<el-table
id="roleTable"
ref="dataTable"
:data="tableData"
:height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:min-width="`${item.minWidth}`"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<span v-if="scope.row[item.prop]">{{scope.row[item.prop] || '-'}}</span>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" title="Copy" @click="copyRow(scope.row,'exprTemp')"><i class="nz-icon nz-icon-override"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span></span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['edit', scope.row]"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
<el-dropdown-item :command="['delete', scope.row]"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
</template>
<script>
import table from '@/components/common/mixin/table'
export default {
name: 'roleTable',
mixins: [table],
data () {
return {
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.exprTemp.name'),
prop: 'name',
show: true
}, {
label: this.$t('config.exprTemp.gname'),
prop: 'gname',
show: true
}, {
label: this.$t('config.exprTemp.expression'),
prop: 'expression',
show: true
}, {
label: this.$t('config.exprTemp.remark'),
prop: 'remark',
show: true
}
]
}
}
}
</script>

View File

@@ -0,0 +1,163 @@
<template>
<el-table
id="mibTable"
ref="dataTable"
:data="tableData"
:height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:min-width="`${item.minWidth}`"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<template v-if="item.prop == 'updateUser'" >{{scope.row[item.prop].name}}</template>
<template v-else-if="item.prop == 'fileName' && scope.row[item.prop]" >
<span class="link" @click="downloadMib(scope.row)">{{scope.row[item.prop]}}</span>
</template>
<template v-else-if="item.prop === 'modelsDetail' && scope.row['modelsDetail'] && scope.row['modelsDetail'].length >0" >
<div style="height: 100%">
<div style="height: 100%; overflow: auto;">
<div v-for="(n,i) in scope.row['modelsDetail']" :key="n.name+'-'+n.id+'-'+i" class="detail-item-content">
<el-popover placement="top" trigger="hover" >
<div>
<div>
<span>{{$t('overall.name')}}:</span>
<span>{{n.name}}</span>
</div>
<div>
<span>{{$t('config.mib.vendor')}}:</span>
<span>{{n.vendor}}</span>
</div>
<div>
<span>{{$t('config.mib.type')}}:</span>
<span>{{n.type}}</span>
</div>
</div>
<template slot="reference">
<div v-if="i < scope.row['modelsDetail'].length-1" class="detail-item-content">{{n.name}},</div>
<div v-else class="detail-item-content">{{n.name}}</div>
</template>
</el-popover>
</div>
</div>
</div>
</template>
<span v-else-if="item.prop === 'updateAt'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<template v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</template>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" title="Download" @click="downloadMib(scope.row)"><i class="nz-icon nz-icon-download"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span></span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['edit', scope.row]"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
<el-dropdown-item :command="['delete', scope.row]"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
</template>
<script>
import table from '@/components/common/mixin/table'
import axios from 'axios'
export default {
name: 'roleTable',
mixins: [table],
data () {
return {
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('overall.name'),
prop: 'name',
show: true
}, {
label: this.$t('config.mib.fileName'),
prop: 'fileName',
show: true
}, {
label: this.$t('config.mib.models'),
prop: 'modelsDetail',
show: true
}, {
label: this.$t('config.mib.remark'),
prop: 'remark',
show: true
}, {
label: this.$t('config.mib.updateUser'),
prop: 'updateUser',
show: true
}, {
label: this.$t('config.mib.updateAt'),
prop: 'updateAt',
show: true
}
]
}
},
methods: {
downloadMib (mib) {
axios.get('/mib/download?id=' + mib.id, { responseType: 'blob' }).then(data => {
let fileName = new Date().getTime() + '.txt'
const disposition = data.headers['content-disposition']
if (disposition) {
fileName = disposition.split(';')[1].split('filename=')[1]
}
// 由于ie不支持download属性故需要做兼容判断
if (navigator.appVersion.toString().indexOf('.NET') > 0) {
// ie独有的msSaveBlob属性data.data为Blob文件流
window.navigator.msSaveBlob(data.data, fileName)
} else {
// 以下流程即为文章开始的下载流程
const url = window.URL.createObjectURL(data.data)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.download = fileName
document.body.appendChild(link)
link.click()
window.URL.revokeObjectURL(link.href)
}
})
}
}
}
</script>

View File

@@ -0,0 +1,131 @@
<template>
<el-table
id="roleTable"
ref="dataTable"
:data="tableData"
:height="height"
border
class="no-operation"
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:min-width="`${item.minWidth}`"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<span v-if="item.prop === 'time'">
{{scope.row[item.prop]}} ms
</span>
<span v-else-if="item.prop === 'username'">{{formatUsername(scope.row)}}</span>
<span v-else-if="item.prop === 'createDate'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<span v-else>{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
</el-table>
</template>
<script>
import table from '@/components/common/mixin/table'
export default {
name: 'roleTable',
mixins: [table],
data () {
return {
tableTitle: [
{
label: this.$t('config.operationlog.id'),
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.operationlog.username'),
prop: 'username',
show: true
},
{
label: this.$t('config.operationlog.ip'),
prop: 'ip',
show: true
},
{
label: this.$t('config.operationlog.operation'),
prop: 'operation',
show: true
},
{
label: this.$t('config.operationlog.type'),
prop: 'type',
show: true
},
{
label: this.$t('config.operationlog.state'),
prop: 'state',
show: true
},
// {
// label: this.$t('config.operationlog.userId'),
// prop: 'userId',
// show: false,
// },
{
label: this.$t('config.operationlog.operaId'),
prop: 'operaId',
show: false
},
{
label: this.$t('config.operationlog.createDate'),
prop: 'createDate',
show: true
},
{
label: this.$t('config.operationlog.time'),
prop: 'time',
show: false
},
{
label: this.$t('config.operationlog.params'),
prop: 'params',
show: false
},
{
label: this.$t('config.operationlog.response'),
prop: 'response',
show: false
}
]
}
},
methods: {
formatUsername (row) {
if (row.username) {
return row.username
} else if (row.operation === 'login' && !row.username) { // 如果是登录 且登录失败
return JSON.parse(row.params).username
} else {
return '-'
}
}
}
}
</script>

View File

@@ -0,0 +1,179 @@
<template>
<el-table
id="roleTable"
ref="dataTable"
:data="tableData"
:height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:min-width="`${item.minWidth}`"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<span v-if="item.prop === 'time'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<template v-else-if="item.prop === 'status'">
<span>{{getStatusText(scope.row.status)}}</span>
</template>
<template v-else-if="item.prop === 'uuid'">
<span>{{scope.row.uuid.substring(0, 8).toUpperCase()}}</span>
</template>
<template v-else-if="item.prop === 'remote'">
<span>{{getRemoteText(scope.row)}}</span>
</template>
<template v-else-if="item.prop === 'duration'">
<el-tooltip :disabled="!scope.row.status" effect="light" placement="right">
<div slot="content">
{{$t('config.terminallog.endTime')}}<br/>
{{scope.row.endTime}}
</div>
<span>{{getDuration(scope.row)}}</span>
</el-tooltip>
</template>
<template v-else-if="item.prop === 'authType'">
<span v-if="scope.row.authType == 1">{{$t('config.terminallog.password')}}</span>
<span v-else-if="scope.row.authType == 2">{{$t('config.terminallog.key')}}</span>
</template>
<span v-else>{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<template v-if="scope.row.status == 0">
<button :title="$t('config.terminallog.monitor.monitor')" class="table-operation-item" @click="$refs.dataList.showBottomBox('monitor', scope.row)"><i class="nz-icon nz-icon-JC"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span></span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['shutdown', scope.row]"><i class="nz-icon nz-icon-ZD"></i><span class="operation-dropdown-text">Kill</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<template v-else>
<button class="table-operation-item" @click="showBottomBox('cmd', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span></span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['record', scope.row]"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('config.terminallog.record.record')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</div>
</el-table-column>
</el-table>
</template>
<script>
import { terminalLog } from '@/components/common/js/constants'
import { calcDurationByStringTimeB } from '@/components/common/js/tools'
import table from '@/components/common/mixin/table'
export default {
name: 'roleTable',
mixins: [table],
data () {
return {
tableTitle: [
{
label: this.$t('config.terminallog.id'),
prop: 'id',
show: true,
width: 80
}, {
label: 'Session ID',
prop: 'uuid',
show: true
}, {
label: 'Username',
prop: 'username',
show: true
},
{
label: this.$t('config.terminallog.source'),
prop: 'remoteAddr',
show: true
},
{
label: this.$t('config.terminallog.remote'),
prop: 'remote',
show: true
},
{
label: this.$t('config.terminallog.protocol'),
prop: 'protocol',
show: true
},
{
label: this.$t('config.terminallog.startTime'),
prop: 'startTime',
show: true
},
{
label: this.$t('config.terminallog.duration'),
prop: 'duration',
show: true
},
{
label: 'AuthType',
prop: 'authType',
show: false
},
{
label: this.$t('config.terminallog.status'), // killusername鼠标悬停形式
prop: 'status',
show: true,
width: 100
}
]
}
},
computed: {
getStatusText () {
return function (status) {
return terminalLog.status[status]
}
},
getRemoteText () {
return function (record) {
return `${record.loginUser}@${record.host}:${record.port}`
}
},
getDuration () {
return function (record) {
if (record.endTime) {
return calcDurationByStringTimeB(record.startTime, record.endTime)
}
return calcDurationByStringTimeB(record.startTime, this.nowTime)
}
}
}
}
</script>

View File

@@ -46,7 +46,7 @@
<el-switch <el-switch
v-model="scope.row.status" v-model="scope.row.status"
:active-color="theme.themeColor" :active-color="theme.themeColor"
:disabled="isCurrentUser(scope.row.username) || !hasButton('account_toEdit') || !hasButton('account_toAdd') || (scope.row.username === 'admin' && scope.row.id === 1)" :disabled="isCurrentUser(scope.row.username) || !hasButton('user_edit') || (scope.row.username === 'admin' && scope.row.id === 1)"
active-value="1" active-value="1"
inactive-value="0" inactive-value="0"
@change="val => {statusChange(scope.row)}"> @change="val => {statusChange(scope.row)}">

View File

@@ -8,7 +8,7 @@
</div> </div>
</el-menu-item> </el-menu-item>
</el-menu> </el-menu>
<el-menu :collapse="isShrink" :default-active="route" active-text-color="#FA901C" background-color="#202F3F" class="menu-list" mode="vertical" text-color="#BEBEBE" @select="jump"> <el-menu :collapse="isShrink" :default-active="route" active-text-color="#FA901C" background-color="#202F3F" class="menu-list" mode="vertical" text-color="#BEBEBE" unique-opened @select="jump">
<template v-for="(menu, index) in menuList"> <template v-for="(menu, index) in menuList">
<el-submenu v-if="menu.children && menu.children.length > 0" :key="index" :index="`${index}`"> <el-submenu v-if="menu.children && menu.children.length > 0" :key="index" :index="`${index}`">
<template slot="title"> <template slot="title">

View File

@@ -1,145 +1,120 @@
<style scoped>
.list {
height: 100%;
}
/deep/ .too-long-split{
cursor: pointer;
vertical-align: bottom;
}
span.el-tooltip {
display: inline-block;
}
/deep/.top-tools{
z-index: 1;
}
</style>
<style lang="scss"> <style lang="scss">
@import '../../charts/chart'; @import '../../charts/chart';
</style> </style>
<template> <template>
<div class="list"> <div>
<div class="main-list main-and-sub-transition" :class="{'main-list-with-sub': bottomBox.showSubList}"> <nz-data-list
<div class="top-tools" v-show="bottomBox.mainResizeShow"> ref="dataList"
<div class="top-tool-main-right" :class="{'top-tool-main-right-to-left': bottomBox.showSubList}"> :api="url"
<pick-time :refresh-data-func="getAlertList" v-model="searchTime" :use-chart-unit="false" :use-refresh="false" :default-pick="12" :show-empty="true"></pick-time> :custom-table-title.sync="tools.customTableTitle"
<div class="top-tool-search margin-r-20"> :from="fromRoute.alertMessage"
<search-input :inTransform="bottomBox.inTransform" :searchMsg="searchMsg" @search="search"></search-input> :layout="['searchInput', 'elementSet']"
</div> :search-msg="searchMsg">
<button :title="$t('overall.exportExcelLower')" @click="showExportDialog" type="button" v-has="'message_export'" <template v-slot:top-tool-right>
class="nz-btn nz-btn-size-normal nz-btn-style-light" id="alert-list-export"> <pick-time v-model="searchTime" :default-pick="12" :refresh-data-func="getTableData" :show-empty="true" :use-chart-unit="false" :use-refresh="false"></pick-time>
<i class="nz-icon nz-icon-download1"></i> <button id="roles-add" v-has="'alertMessage_view'" :title="$t('overall.exportExcelLower')" class="top-tool-btn margin-r-10"
</button> type="button" @click="showExportDialog">
<delete-button :clickFunction="openDelMessageBox" :delete-objs="batchDeleteObjs" @after="getAlertList" api="alert/message" v-has="'message_delete'" id="alert-msg-batch-delete"></delete-button> <i class="nz-icon-download1 nz-icon"></i>
</div> </button>
<div class="pagination-top pagination-top-hide display-none"></div> <delete-button id="alert-msg-batch-delete" v-has="'message_delete'" :api="url" :clickFunction="openDelMessageBox" :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true"></delete-button>
</div> </template>
<alertMessageTable <template v-slot:default="slotProps">
id="alert-msg-table" <alert-message-table
ref="alertMessageTable" ref="dataTable"
:tableData="tableData" v-loading="slotProps.loading"
:loading="tools.loading" :api="url"
:tableHeight="mainTableHeight" :custom-table-title="tools.customTableTitle"
:tableId="tableId" :height="mainTableHeight"
@tableDataSort="tableDataSort" :now-time="nowTime"
:from="$CONSTANTS.fromRoute.message" :table-data="tableData"
@deleteMessage="deleteMessage" @del="del"
@select-change="(selection)=>{this.batchDeleteObjs=selection}" @edit="edit"
:now-time="nowTime" @orderBy="tableDataSort"
></alertMessageTable> @reload="getTableData"
<div class="pagination-bottom" v-show="!bottomBox.showSubList"> @selectionChange="selectionChange"
<Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination> @showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"
</div> @toDelete="toDeleteMessage"></alert-message-table>
</div> </template>
<bottom-box v-if="bottomBox.showSubList" :show-sub-list="bottomBox.showSubList" :sub-resize-show="bottomBox.subResizeShow" :is-full-screen="bottomBox.isFullScreen" :from="'alertMessage'" :target-tab.sync="bottomBox.targetTab" :detailList="tabDetailList" <!-- 分页组件 -->
@closeSubList="bottomBox.showSubList = false" @fullScreen="fullScreen" @exitFullScreen="exitFullScreen" @listResize="listResize" :tabList="tabList"></bottom-box> <template v-slot:pagination>
<Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
</template>
</nz-data-list>
<!--导出--> <!--导出-->
<div class="export-xlsx"> <div class="export-xlsx">
<el-dialog :visible.sync="importBox.show" :title="importBox.title" :modal-append-to-body='false' :show-close="true" width="300px" @close="closeDialog" class="nz-dialog"> <el-dialog :modal-append-to-body='false' :show-close="true" :title="importBox.title" :visible.sync="importBox.show" class="nz-dialog" width="300px" @close="closeDialog">
<div class="upload-body"> <div class="upload-body">
<button @click="exportCur" class="el-button el-button--default el-button--small" id="alert-msg-exportcur"> <button id="alert-msg-exportcur" class="el-button el-button--default el-button--small" @click="exportCur">
<span>{{$t('overall.exportCur')}}</span> <span>{{$t('overall.exportCur')}}</span>
</button> </button>
<button @click="exportAll" class="el-button el-button--default el-button--small" id="alert-msg-exportall"> <button id="alert-msg-exportall" class="el-button el-button--default el-button--small" @click="exportAll">
<span>{{$t('overall.exportAll')}}</span> <span>{{$t('overall.exportAll')}}</span>
</button> </button>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
<!--export--> <!--删除弹窗-->
<!--<div class="export-xlsx">--> <div class="export-xlsx">
<!--<el-dialog :visible.sync="deleteBox.show" :title="$t('overall.delete')" :modal-append-to-body='false' :show-close="true" width="300px" @close="closeDialog" class="nz-message">--> <el-dialog :modal-append-to-body='false' :show-close="true" :title="$t('alert.list.remark')" :visible.sync="deleteBox.show" class="nz-message" width="450px" @close="closeDialog" @opened="openedDialog">
<!--<div class="upload-body">--> <div class="upload-body">
<!--<el-input type="textarea" :placeholder="$t('alert.description')" v-model="deleteBox.remark"></el-input>--> <el-form ref="remarkForm" :model="deleteBox">
<!--<div style="text-align: right; margin-top: 10px;">--> <el-form-item :rules="[{required:true,message: $t('validate.required'), trigger: 'change'}]" prop="remark">
<!--<button @click="closeDialog" class="el-button el-button&#45;&#45;default el-button&#45;&#45;small">--> <el-input v-model="deleteBox.remark" :placeholder="$t('alert.description')" type="textarea"></el-input>
<!--<span>{{$t('tip.no')}}</span>--> </el-form-item>
<!--</button>--> </el-form>
<!--<button @click="deleteMessage" class="el-button el-button&#45;&#45;default el-button&#45;&#45;small el-button&#45;&#45;primary">--> <div style="text-align: right; margin-top: 10px;">
<!--<span>{{$t('tip.yes')}}</span>--> <button class="el-button el-button--default el-button--small" @click="closeDialog">
<!--</button>--> <span>{{$t('tip.no')}}</span>
<!--</div>--> </button>
<!--</div>--> <button class="el-button el-button--default el-button--small el-button--primary" @click="deleteMessage">
<!--</el-dialog>--> <span>{{$t('tip.yes')}}</span>
<!--</div>--> </button>
<!--<el-dialog class="line-chart-block-modal nz-dialog endpoint-dialog"--> </div>
<!--:title="$t('overall.detail')"--> </div>
<!--:visible.sync="graphShow"--> </el-dialog>
<!--width="90%"--> </div>
<!--id="viewGraphDialog"--> <el-dialog id="viewGraphDialog"
<!--@close="dialogClose">--> :modal-append-to-body='false'
<!--<div slot="title">--> :title="$t('overall.detail')"
<!--{{$t("project.endpoint.dialogTitle")}}--> :visible.sync="graphShow"
<!--<div class="float-right panel-calendar dialog-tool" style="display: flex">--> class="line-chart-block-modal nz-dialog endpoint-dialog"
<!--<pick-time :refresh-data-func="queryChartDate" :use-refresh="false" :use-chart-unit="false" v-model="searchTime" style="height: 28px;" @unitChange="chartUnitChange"></pick-time>--> width="90%"
<!--</div>--> @close="dialogClose">
<!--</div>--> <div slot="title">
<!--<chart ref="messageChart" name="alertMessageChart" :unit="chartUnit"></chart>--> {{$t("project.endpoint.dialogTitle")}}
<!--</el-dialog>--> <div class="float-right panel-calendar dialog-tool" style="display: flex">
<pick-time v-model="searchTime" :refresh-data-func="queryChartDate" :use-chart-unit="false" :use-refresh="false" style="height: 28px;" @unitChange="chartUnitChange"></pick-time>
</div>
</div>
<chart ref="messageChart" :unit="chartUnit" name="alertMessageChart"></chart>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import bus from '../../../libs/bus' import bus from '@/libs/bus'
import axios from 'axios' import axios from 'axios'
import pickTime from '../../common/pickTime' import pickTime from '@/components/common/pickTime'
import alertMessageTable from '../../common/alert/alertMessageTable.vue' import { getTime } from '@/components/common/js/tools'
import deleteButton from '../../common/deleteButton' import alertMessageTable from '@/components/common/table/alert/alertMessageTable.vue'
import deleteButton from '@/components/common/deleteButton'
import nzDataList from '@/components/common/table/nzDataList'
import dataListMixin from '@/components/common/mixin/dataList'
import chartDataFormat from '@/components/charts/chartDataFormat'
export default { export default {
name: 'alertList', name: 'alertList',
components: { components: {
alertMessageTable: alertMessageTable, alertMessageTable,
'pick-time': pickTime, pickTime,
'delete-button': deleteButton nzDataList,
deleteButton
}, },
mixins: [dataListMixin],
data () { data () {
return { return {
/* 二级列表相关 */ url: 'alert/message',
mainTableHeight: this.$tableHeight.normal, // table
/* 二级页面相关 */
bottomBox: {
tabList: [], //
tabDetailList: [], //
mainResizeShow: true, // dom|
subResizeShow: true,
isFullScreen: false, //
showSubList: false, //
targetTab: '', //
inTransform: false // transform
},
/* 工具参数 */
tools: {
loading: false, // table
toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-toptop
tableHover: false, // top
showTopBtn: false, // To top
showCustomTableTitle: false, //
customTableTitle: [] //
},
// //
importBox: { show: false, title: this.$t('overall.exportExcel') }, importBox: { show: false, title: this.$t('overall.exportExcel') },
deleteBox: { show: false, ids: '', remark: '', state: 2 }, deleteBox: { show: false, ids: '', remark: '', state: 2 },
batchDeleteObjs: [],
// //
graphShow: false, graphShow: false,
chartDatas: [], chartDatas: [],
@@ -150,68 +125,7 @@ export default {
currentMsg: {}, currentMsg: {},
chartUnit: 5, chartUnit: 5,
tableId: 'alertListTable', // tableid tableId: 'alertMessageTable', // tableid
pageObj: {
pageNo: 1,
pageSize: this.$CONSTANTS.defaultPageSize,
total: 0
},
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('alert.alertName'),
prop: 'alertRule',
show: true,
width: 180
}, {
label: this.$t('alert.list.labels'),
prop: 'labels',
show: true,
width: 350
}, {
label: this.$t('alert.severity'),
prop: 'severity',
show: true,
width: 100
}, {
label: this.$t('alert.summary'),
prop: 'summary',
show: true
}, {
label: this.$t('alert.description'),
prop: 'description',
show: true
}, {
label: this.$t('alert.list.state'),
prop: 'state',
show: true,
width: 100
}, {
label: this.$t('alert.startAt'),
prop: 'startAt',
show: true,
width: 150
}, {
label: this.$t('alert.endAt'),
prop: 'endAt',
show: true,
width: 150
}, {
label: this.$t('overall.value'),
prop: 'current',
show: true,
width: 100
}, {
label: this.$t('overall.option'),
prop: 'option',
show: true,
width: 90
}
],
searchMsg: { // searchMsg: { //
zheze_none: true, zheze_none: true,
searchLabelList: [{ searchLabelList: [{
@@ -277,10 +191,6 @@ export default {
readonly: true readonly: true
}] }]
}, },
searchLabel: { //
},
tableData: [],
requestIndex: 0, requestIndex: 0,
viewAssetState: false, viewAssetState: false,
nowTime: '' nowTime: ''
@@ -312,7 +222,7 @@ export default {
} }
}, },
methods: { methods: {
labelsSort: function (obj) { labelsSort (obj) {
const buildIn = ['asset', 'endpoint', 'module', 'project', 'datacenter'] const buildIn = ['asset', 'endpoint', 'module', 'project', 'datacenter']
const labels = JSON.parse(JSON.stringify(obj)) const labels = JSON.parse(JSON.stringify(obj))
const result = [] const result = []
@@ -327,12 +237,120 @@ export default {
}) })
return result return result
}, },
chartUnitChange (unit) {
getAlertList () { this.chartUnit = unit
if (!this.hasButton('message_view')) { this.$nextTick(() => {
this.$message.error(this.$t('tip.noAccess')) this.queryChartDate()
return })
},
queryChartDate () {
const $temp = this
const start = this.searchTime[0] ? this.searchTime[0] : getTime(-1, 'h')
const end = this.searchTime[1] ? this.searchTime[1] : getTime(0, 'h')
this.searchTime = [start, end]
const timeDiff = (new Date(end).getTime() - new Date(start).getTime()) / 1000 / (24 * 60 * 60)
let step = '15s'
if (timeDiff < 1) {
step = '15s'
} else if (timeDiff < 7) {
step = '5m'
} else if (timeDiff < 30) {
step = '10m'
} else {
step = '30m'
} }
if (this.$refs.messageChart) {
this.$refs.messageChart.startLoading()
const axiosArr = []
const paramStr = JSON.stringify(this.promQueryParamConvert(this.currentMsg))
axiosArr.push(axios.get('/prom/api/v1/query_range?query=' + paramStr.substring(1, paramStr.length - 1).replace(/\+/g, '%2B').replace(/ /g, '%20').replace(/\\/g, '') + '&start=' + this.$stringTimeParseToUnix(start) + '&end=' + this.$stringTimeParseToUnix(end) + '&step=' + step))
this.legend = []
this.chartDatas = []
axios.all(axiosArr).then(res => {
try {
res.forEach((response, promIndex) => {
if (response.status == 200) {
if (response.data.status == 'success') {
const queryData = response.data.data.result[0]
if (queryData) {
const chartData = {
type: 'line',
symbol: 'none', //
smooth: 0.2, // 线
name: '',
lineStyle: {
width: 1,
opacity: 0.9
},
markLine: {
silent: true,
symbol: ['circle', 'circle'],
label: {
distance: this.computeDistance(chartDataFormat.getUnit(this.currentMsg.alertRule.unit ? this.currentMsg.alertRule.unit : 2).compute(this.currentMsg.alertRule.threshold)),
formatter (params) {
return chartDataFormat.getUnit($temp.currentMsg.alertRule.unit ? $temp.currentMsg.alertRule.unit : 2).compute(params.value)
}
},
lineStyle: {
color: '#d64f40',
width: 2,
type: 'dotted'
},
data: [{
yAxis: Number(this.currentMsg.alertRule.threshold)
}]
},
markArea: {
itemStyle: {
color: '#d64f40',
opacity: 0.1
},
data: [this.returnMarkArea()]
}
}
if (this.currentMsg.alertRule.operator == '==' || this.currentMsg.alertRule.operator == '!=') {
delete chartData.markArea
}
let alias = chartData.name
chartData.name += '{'
alias += '{'
Object.keys(queryData.metric).forEach((item, index) => {
const label = item
const value = queryData.metric[label]
chartData.name += label + "='" + value + "',"
})
chartData.name = chartData.name.charAt(chartData.name.length - 1) == ',' ? chartData.name.substr(0, chartData.name.length - 1) : chartData.name
chartData.name += '}'
const legend = {
name: chartData.name,
alias: alias,
isGray: false
}
this.legend.push(legend)
chartData.data = queryData.values.map((dpsItem, dpsIndex) => {
return [dpsItem[0] * 1000, parseFloat(dpsItem[1]).toFixed(2)]
})
this.chartDatas.push(chartData)
}
} else {
this.$message.error(response.data.error)
}
}
})
this.$nextTick(() => {
this.$refs.messageChart.setRandomColors(this.chartDatas.length)
this.$refs.messageChart.setLegend(this.legend)
this.$refs.messageChart.setSeries(this.chartDatas)
this.$refs.messageChart.endLoading()
})
} catch (err) {
this.$message.error(err)
this.$refs.messageChart.endLoading()
}
})
}
},
getTableData () {
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo) this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize) this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
if (this.searchTime && this.searchTime.length > 1) { if (this.searchTime && this.searchTime.length > 1) {
@@ -343,7 +361,7 @@ export default {
delete this.searchLabel.endAt delete this.searchLabel.endAt
} }
this.tools.loading = true this.tools.loading = true
this.$get('alert/message', this.searchLabel).then(response => { this.$get(this.url, this.searchLabel).then(response => {
this.tools.loading = false this.tools.loading = false
if (response.code == 200) { if (response.code == 200) {
this.nowTime = this.utcTimeToTimezoneStr(response.time) this.nowTime = this.utcTimeToTimezoneStr(response.time)
@@ -352,7 +370,7 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.tableData.forEach((item) => { this.tableData.forEach((item) => {
item.labels = JSON.parse(item.labels) item.labels = JSON.parse(item.labels)
if (item.alertRule.buildIn != 1) { if (!this.isBuildIn(item.alertRule)) {
const paramStr = JSON.stringify(this.promQueryParamConvert(item)) const paramStr = JSON.stringify(this.promQueryParamConvert(item))
axiosAll.push(axios.get('/prom/api/v1/query?query=' + paramStr.substring(1, paramStr.length - 1).replace(/\+/g, '%2B').replace(/ /g, '%20').replace(/\\/g, ''))) axiosAll.push(axios.get('/prom/api/v1/query?query=' + paramStr.substring(1, paramStr.length - 1).replace(/\+/g, '%2B').replace(/ /g, '%20').replace(/\\/g, '')))
} else { } else {
@@ -414,31 +432,6 @@ export default {
}()) }())
} }
return r return r
/* let result="(" + obj.alertRule.expr + ")";
if(obj.labels){
if(obj.labels.alertname){
delete obj.labels.alertname;
}
if(obj.labels.severity){
delete obj.labels.severity;
}
}
if(Object.keys(obj.labels).length>0){
result+=" and ("+function(){
let q = "{";
for (let k in obj.labels) {
q += k;
q += "=";
q += ("'" + obj.labels[k] + "',");
};
if (q.length > 1) {
q = q.substring(0, q.length-1);
}
q += "}";
return q;
}() + ")";
}
return result; */
}, },
// asset // asset
tabControl (data) { tabControl (data) {
@@ -447,7 +440,10 @@ export default {
this.$refs.assetEditUnit.tabView = false this.$refs.assetEditUnit.tabView = false
} }
}, },
openDelMessageBox: function () { openedDialog () {
this.$refs.remarkForm.clearValidate()
},
openDelMessageBox () {
if (this.batchDeleteObjs.length < 1) return if (this.batchDeleteObjs.length < 1) return
if (this.$refs.alertMessageTable) { if (this.$refs.alertMessageTable) {
this.$refs.alertMessageTable.toDeleteMessage(false) this.$refs.alertMessageTable.toDeleteMessage(false)
@@ -459,14 +455,19 @@ export default {
} }
this.deleteBox.show = true this.deleteBox.show = true
}, },
deleteMessage (deleteBox, cb) { deleteMessage () {
this.$put('alert/message', deleteBox).then(res => { this.$refs.remarkForm.validate(valid => {
if (res.code === 200) { if (valid) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') }) this.$put(this.url, this.deleteBox).then(res => {
this.getAlertList() if (res.code === 200) {
cb() this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
} else { this.deleteBox.ids = []
this.$message.error(res.msg) this.deleteBox.show = false
this.getTableData()
} else {
this.$message.error(res.msg)
}
})
} }
}) })
}, },
@@ -485,20 +486,23 @@ export default {
this.importBox.show = false this.importBox.show = false
this.deleteBox.show = false this.deleteBox.show = false
}, },
exportCur: function () { dialogClose () {
this.graphShow = false
},
exportCur () {
const searchLabel = Object.assign({}, this.searchLabel) const searchLabel = Object.assign({}, this.searchLabel)
this.$set(searchLabel, 'language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en') this.$set(searchLabel, 'language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en')
this.exportExcel(searchLabel) this.exportExcel(searchLabel)
this.closeDialog() this.closeDialog()
}, },
exportAll: function () { exportAll () {
const temp = JSON.parse(JSON.stringify(this.searchLabel)) const temp = JSON.parse(JSON.stringify(this.searchLabel))
temp.pageSize = -1 temp.pageSize = -1
this.$set(temp, 'language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en') this.$set(temp, 'language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en')
this.exportExcel(temp) this.exportExcel(temp)
this.closeDialog() this.closeDialog()
}, },
getTimeString: function () { getTimeString () {
const split = '-' const split = '-'
const date = new Date() const date = new Date()
const year = date.getFullYear() const year = date.getFullYear()
@@ -509,13 +513,13 @@ export default {
const seconds = this.formatNum(date.getSeconds()) const seconds = this.formatNum(date.getSeconds())
return year + split + month + split + day + ' ' + hours + split + minutes + split + seconds return year + split + month + split + day + ' ' + hours + split + minutes + split + seconds
}, },
formatNum: function (num) { formatNum (num) {
return num > 9 ? num : '0' + num return num > 9 ? num : '0' + num
}, },
exportExcel: function (params) { exportExcel (params) {
for (const item in params) { for (const item in params) {
if (params[item]) { if (params[item]) {
if (item == 'alertMessageState') { if (item === 'alertMessageState') {
this.$set(params, 'state', params[item]) this.$set(params, 'state', params[item])
} else { } else {
this.$set(params, item, params[item]) this.$set(params, item, params[item])
@@ -557,21 +561,6 @@ export default {
reader.readAsText(error.response.data) reader.readAsText(error.response.data)
}) })
}, },
//
fullScreen () {
const vm = this
this.$bottomBoxWindow.fullScreen(vm)
},
// 退
exitFullScreen () {
const vm = this
this.$bottomBoxWindow.exitFullScreen(vm)
},
//
listResize (e) {
const vm = this
this.$bottomBoxWindow.listResize(vm, e)
},
showTagDetail (data, key) { showTagDetail (data, key) {
let open = false let open = false
if (key == 'asset' || key == 'project' || key == 'module' || key == 'endpoint' || key == 'datacenter') { if (key == 'asset' || key == 'project' || key == 'module' || key == 'endpoint' || key == 'datacenter') {
@@ -588,26 +577,8 @@ export default {
} }
this.bottomBox.showSubList = true this.bottomBox.showSubList = true
this.tabList = labelList this.tabList = labelList
/* this.tabDetailList = detailList;
this.bottomBox.targetTab = key; */
} }
}, },
labelsClassName (row) {
if (row.column.label == this.$t('alert.list.labels')) {
return 'alert-message-list-labels'
} else {
return ''
}
},
pageNo (val) {
this.pageObj.pageNo = val
this.getAlertList()
},
pageSize (val) {
this.pageObj.pageSize = val
localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
this.getAlertList()
},
search (searchObj) { search (searchObj) {
let orderBy = '' let orderBy = ''
if (this.searchLabel.orderBy) { if (this.searchLabel.orderBy) {
@@ -628,16 +599,16 @@ export default {
this.$set(this.searchLabel, 'orderBy', orderBy) this.$set(this.searchLabel, 'orderBy', orderBy)
} }
this.$refs.alertMessageTable.$refs.alertListTable.bodyWrapper.scrollTop = 0 this.$refs.alertMessageTable.$refs.alertListTable.bodyWrapper.scrollTop = 0
this.getAlertList() this.getTableData()
}, },
fillProject: function (module) { fillProject (module) {
this.$get('project', { id: module.projectId }).then(response => { this.$get('project', { id: module.projectId }).then(response => {
if (response.code == 200) { if (response.code == 200) {
module.project = response.data.list[0] module.project = response.data.list[0]
} }
}) })
}, },
closeViews: function () { closeViews () {
this.$refs.alertConfigBox.show(false, false) this.$refs.alertConfigBox.show(false, false)
this.$refs.projectBox.show(false, false) this.$refs.projectBox.show(false, false)
this.$refs.moduleBox.show(false, false) this.$refs.moduleBox.show(false, false)
@@ -654,66 +625,8 @@ export default {
} }
this.pageObj.orderBy = orderBy this.pageObj.orderBy = orderBy
this.$set(this.searchLabel, 'orderBy', orderBy) this.$set(this.searchLabel, 'orderBy', orderBy)
this.getAlertList() this.getTableData()
},
// label tooltip
labelToolTipDis (labelType) {
switch (labelType) {
case 'asset':
case 'module':
case 'project':
return false
default: return true
}
},
// alertNmae
alertMessagehover (item, index) {
item.loading = true
this.$set(this.tableData, index, item)
},
// label
labelHover (item, index, type) {
if (this.labelToolTipDis(type)) {
return
}
item[type].loading = true
this.$set(this.tableData, index, item)
} }
},
watch: {
showSubList (n) {
const vm = this
this.$bottomBoxWindow.showSubListWatch(vm, n)
},
tableData: {
deep: true,
handler (n) {
if (n.length === 0 && this.pageObj.pageNo > 1) {
this.pageNo(this.pageObj.pageNo - 1)
}
}
}
},
created () {
//
const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
if (pageSize != 'undefined' && pageSize != null) {
this.pageObj.pageSize = pageSize
}
},
mounted () {
//
this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
: this.tableTitle
this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
//
const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
if (pageSize != 'undefined' && pageSize != null) {
this.pageObj.pageSize = pageSize
}
this.getAlertList()
} }
} }
</script> </script>

View File

@@ -0,0 +1,169 @@
<template>
<div>
<nz-data-list
ref="dataList"
:api="url"
:custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.alertRule"
:layout="['searchInput', 'elementSet']"
:search-msg="searchMsg">
<template v-slot:top-tool-right>
<export-excel
id="alert-rule"
:params="searchLabel"
:permissions="{import: 'rule_import', export: 'rule_export'}"
export-file-name="AlertRule"
export-url="/alert/rule/export"
import-url="/alert/rule/import"
@afterImport="getTableData"
>
<template slot="optionZone">
<button id="alert-add" v-has="'alertRule_add'" :title="$t('overall.createAlertRule')" class="top-tool-btn margin-r-10"
@click="add">
<i class="nz-icon-create-square nz-icon"></i>
</button>
</template>
</export-excel>
<delete-button id="alert-rule-batch-delete" v-has="'alertRule_delete'" :api="url" :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true"></delete-button>
</template>
<template v-slot:default="slotProps">
<alert-rule-table
ref="dataTable"
v-loading="slotProps.loading"
:api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight"
:table-data="tableData"
@del="del"
@edit="edit"
@orderBy="tableDataSort"
@queryMessage="queryMessage"
@reload="getTableData"
@selectionChange="selectionChange"
@showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"></alert-rule-table>
</template>
<!-- 分页组件 -->
<template v-slot:pagination>
<Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
</template>
</nz-data-list>
<transition name="right-box">
<alert-rule-box v-if="rightBox.show" ref="alertConfigBox" :alert-rule="object" @close="closeRightBox"></alert-rule-box>
</transition>
</div>
</template>
<script>
import bus from '@/libs/bus'
import exportXLSX from '@/components/common/exportXLSX'
import alertRuleBox from '@/components/common/rightBox/alertRuleBox'
import deleteButton from '@/components/common/deleteButton'
import nzDataList from '@/components/common/table/nzDataList'
import dataListMixin from '@/components/common/mixin/dataList'
import alertRuleTable from '@/components/common/table/alert/alertRuleTable'
export default {
name: 'alert-config',
components: {
deleteButton,
alertRuleBox,
alertRuleTable,
nzDataList,
'export-excel': exportXLSX
},
mixins: [dataListMixin],
data () {
return {
url: 'alert/rule',
tableId: 'alertRuleTable', // 需要分页的table的id用于记录每页数量
blankObject: {
id: '',
alertName: '',
linkObject: { id: '', name: '' },
expr: '',
unit: 2,
operator: '>',
last: 60,
severity: 'P2',
summary: '',
description: ''
},
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
id: 1,
name: 'ID',
type: 'input',
label: 'id',
disabled: false
}, {
id: 2,
name: this.$t('alert.alertName'),
type: 'input',
label: 'alertName',
disabled: false
}, {
id: 4,
name: this.$t('alert.severity'),
type: 'selectString',
label: 'severity',
disabled: false
}]
},
searchTime: bus.getTimezontDateRange()
}
},
methods: {
queryMessage (alertRule) {
if (!this.hasButton('alertMessage_view')) {
return
}
this.$refs.dataList.showBottomBox('alertMessage', alertRule)
},
getTableData () {
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
this.$get(this.url, this.searchLabel).then(response => {
this.tools.loading = false
if (response.code === 200) {
response.data.list.forEach(item => {
let temp = []
if (item.receiver) {
temp = item.receiver.split(',').map(t => {
return parseInt(t)
})
}
item.receiverShow = temp
})
this.tableData = response.data.list
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
this.scrollbarWrap = this.$refs.dataTable.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
initEvent () {
bus.$on('alert-rule-list-change', () => {
this.getTableData()
})
bus.$on('dc-list-change', () => {
this.getTableData()
})
bus.$on('alert-message-change', () => {
this.getTableData()
})
}
},
beforeDestroy () {
bus.$off('alert-rule-list-change')
bus.$off('dc-list-change')
bus.$off('alert-message-change')
},
mounted () {
this.initEvent()
}
}
</script>

View File

@@ -0,0 +1,173 @@
<template>
<div>
<nz-data-list
ref="dataList"
:api="url"
:custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.alertSilence"
:layout="['searchInput', 'elementSet']"
:search-msg="searchMsg">
<template v-slot:top-tool-right>
<button id="roles-add" v-has="'alertSilence_add'" :title="$t('overall.create')" class="top-tool-btn margin-r-10"
type="button" @click="add">
<i class="nz-icon-create-square nz-icon"></i>
</button>
<delete-button id="role-list-batch-delete" v-has="'alertSilence_expire'" :api="url" :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true"></delete-button>
</template>
<template v-slot:default="slotProps">
<alert-silence-table
ref="dataTable"
v-loading="slotProps.loading"
:api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight"
:table-data="tableData"
@del="del"
@edit="edit"
@orderBy="tableDataSort"
@reload="getTableData"
@selectionChange="selectionChange"
@showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"></alert-silence-table>
</template>
<!-- 分页组件 -->
<template v-slot:pagination>
<Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
</template>
</nz-data-list>
<transition name="right-box">
<alert-silence-box v-if="rightBox.show" :alert-silence="object" @close="closeRightBox"></alert-silence-box>
</transition>
<!--导出-->
<div class="export-xlsx">
<el-dialog :modal-append-to-body='false' :show-close="true" :title="importBox.title"
:visible.sync="importBox.show" class="nz-dialog" width="300px" @close="closeDialog">
<div class="upload-body">
<button id="alert-msg-exportcur" class="el-button el-button--default el-button--small" @click="exportCur">
<span>{{$t('overall.exportCur')}}</span>
</button>
<button id="alert-msg-exportall" class="el-button el-button--default el-button--small" @click="exportAll">
<span>{{$t('overall.exportAll')}}</span>
</button>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import bus from '@/libs/bus'
import alertSilenceBox from '@/components/common/rightBox/alertSilenceBox'
import deleteButton from '@/components/common/deleteButton'
import nzDataList from '@/components/common/table/nzDataList'
import dataListMixin from '@/components/common/mixin/dataList'
import alertSilenceTable from '@/components/common/table/alert/alertSilenceTable'
export default {
name: 'silence',
components: {
alertSilenceTable,
deleteButton,
nzDataList,
alertSilenceBox
},
mixins: [dataListMixin],
data () {
return {
url: 'alert/silence',
tableId: 'silenceTable',
/* 搜素相关 */
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [
{
id: 11,
name: this.$t('alert.silence.datacenter'),
type: 'input',
label: 'datacenter',
disabled: false
}, {
id: 12,
name: this.$t('alert.silence.project'),
type: 'input',
label: 'project',
disabled: false
}, {
id: 13,
name: this.$t('alert.silence.module'),
type: 'input',
label: 'module',
disabled: false
}, {
id: 14,
name: this.$t('alert.silence.endpoint'),
type: 'input',
label: 'endpoint',
disabled: false
}, {
id: 15,
name: this.$t('alert.silence.asset'),
type: 'input',
label: 'asset ',
disabled: false
}
]
},
// 导出相关
importBox: { show: false, title: this.$t('overall.exportExcel') },
deleteBox: { show: false, ids: '', remark: '', state: 2 },
// 创建修改相关
blackObject: {
id: '',
startAt: '',
endAt: '',
ruleId: '',
matcher: '',
type: 'asset',
linkId: '',
reason: ''
},
nowTime: ''
}
},
mounted () {
this.initEvent()
},
methods: {
initEvent () {
bus.$on('alert-rule-list-change', () => {
this.getTableData()
})
bus.$on('dc-list-change', () => {
this.getTableData()
})
bus.$on('alert-message-change', () => {
this.getTableData()
})
},
exportCur () {
const searchLabel = Object.assign({}, this.searchLabel)
this.$set(searchLabel, 'language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en')
this.exportExcel(searchLabel)
this.closeDialog()
},
exportAll () {
const temp = JSON.parse(JSON.stringify(this.searchLabel))
temp.pageSize = -1
this.$set(temp, 'language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en')
this.exportExcel(temp)
this.closeDialog()
},
closeDialog () {
this.importBox.show = false
this.deleteBox.show = false
},
add () {
this.blackObject.startAt = bus.timeFormate(bus.getOffsetTimezoneData(), 'yyyy-MM-dd hh:mm:ss')
this.blackObject.endAt = bus.timeFormate(bus.getOffsetTimezoneData(1), 'yyyy-MM-dd hh:mm:ss')
this.object = JSON.parse(JSON.stringify(this.blackObject))
this.rightBox.show = true
}
}
}
</script>

View File

@@ -1,552 +0,0 @@
<style scoped>
.config {
height: 100%;
}
.severity .P1{
background: #F5846A;
border-radius: 2px;
font-size: 12px;
color: #FFFFFF;
padding: 2px 6px;
}
.severity .P2{
background: #F7A54A;
border-radius: 2px;
font-size: 12px;
color: #FFFFFF;
padding: 2px 6px;
}
.severity .P3{
background: #F1C13D;
border-radius: 2px;
font-size: 12px;
color: #FFFFFF;
padding: 2px 6px;
}
</style>
<template>
<div class="config">
<div class="main-list" :class="{'main-list-with-sub': bottomBox.showSubList}">
<div class="main-modal"></div>
<div class="top-tools" v-show="bottomBox.mainResizeShow">
<div class="top-tool-main-right" :class="{'top-tool-main-right-to-left': bottomBox.showSubList}">
<div class="top-tool-search float-right margin-r-20">
<search-input :searchMsg="searchMsg" @search="search" :inTransform="bottomBox.inTransform"></search-input>
</div>
<export-excel
id="alert-rule"
export-file-name="AlertRule"
export-url="/alert/rule/export"
import-url="/alert/rule/import"
:params="searchLabel"
:permissions="{import: 'rule_import', export: 'rule_export'}"
@afterImport="getTableData"
>
<template slot="optionZone">
<button :title="$t('overall.createAlertRule')" @click="add" id="alert-add" v-has="'rule_toAdd'"
class="nz-btn nz-btn-size-normal nz-btn-style-light">
<i class="nz-icon-create-square nz-icon"></i>
</button>
</template>
</export-excel>
<delete-button :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true" api="alert/rule" v-has="'rule_delete'" id="alert-rule-batch-delete"></delete-button>
</div>
<div class="pagination-top pagination-top-hide display-none"></div>
</div>
<!-- 自定义table列 -->
<transition name="el-zoom-in-top">
<element-set
id="alert-rule-element-set"
v-if="tools.showCustomTableTitle"
@close="tools.showCustomTableTitle = false"
:custom-table-title.sync="tools.customTableTitle"
:original-table-title="tableTitle"
ref="customTableTitle"
></element-set>
</transition>
<el-table
id="alert-rule-table"
class="nz-table"
:data="tableData"
border
v-show="bottomBox.mainResizeShow"
ref="alertRuleTable"
tooltip-effect="light"
:height="mainTableHeight"
v-loading="tools.loading"
:cell-class-name="messageStyle"
style="width: 100%;"
@sort-change="tableDataSort"
@row-dblclick="detail"
@selection-change="(selection)=>{this.batchDeleteObjs=selection}"
>
<el-table-column
:resizable="false"
type="selection"
width="40"
align="center">
</el-table-column>
<el-table-column
:resizable="true"
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:label="item.label"
show-overflow-tooltip
:sort-orders="['ascending', 'descending']"
:sortable="$tableSet.sortableShow(item.prop,'alertRules')"
:prop="$tableSet.propTitle(item.prop,'alertRules')"
>
<template slot-scope="scope" :column="item">
<div v-if="item.prop == 'option'" class="content-right-options">
<span :title="$t('overall.view')" @click="detail(scope.row)" class="content-right-option" :id="'alert-detail-'+scope.row.id"><i class="nz-icon nz-icon-view"></i></span>&nbsp;
<span :id="'alert-edit-'+scope.row.id" :title="$t('overall.edit')" @click="edit(scope.row)" class="content-right-option" v-has="'rule_toEdit'" v-if="scope.row.buildIn != 1"><i class="nz-icon nz-icon-edit"></i></span>&nbsp;
<span :id="'alert-del-'+scope.row.id" :title="$t('overall.delete')" @click="del(scope.row)" class="content-right-option" v-has="'rule_delete'"><i class="nz-icon nz-icon-delete"></i></span>
</div>
<span v-else-if="item.prop == 'severity'" class="severity">
<span v-if="scope.row[item.prop] == 'P1'" class="P1">P1</span>
<!--<i class="nz-icon nz-icon-arrow-up"></i> {{returnSeverityLabel(scope.row[item.prop])}}-->
<span v-if="scope.row[item.prop] == 'P2'" class="P2">P2</span>
<!--{{returnSeverityLabel(scope.row[item.prop])}}-->
<span v-if="scope.row[item.prop] == 'P3'" class="P3">P3</span>
<!--<i class="nz-icon nz-icon-arrow-down"></i>&nbsp;{{returnSeverityLabel(scope.row[item.prop])}}-->
</span>
<template v-else-if="item.prop == 'alertNum'">
<span class="link" @click="queryMessage(scope.row)">{{scope.row.alertNum + ' ' + $t('overall.active')}}</span>
</template>
<template v-else-if="item.prop == 'threshold'">
<span >{{formatThreshold(scope.row[item.prop],scope.row.unit)}}</span>
</template>
<template v-else-if="item.prop == 'receivers'">
<el-tag effect="dark" v-if="user.userName" :key="index" size="mini" v-for="(user, index) in scope.row[item.prop]" class="alert-rule-tag">{{user.userName}}&nbsp;</el-tag>
</template>
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</span>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column width="28" :resizable="false">
<template slot="header">
<span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)" class="nz-table-gear">
<i class="nz-icon nz-icon-gear"></i>
</span>
</template>
</el-table-column>
</el-table>
<button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn && bottomBox.mainResizeShow" id="alert-rule-toTop"><i class="nz-icon nz-icon-top"></i></button>
<div class="pagination-bottom" v-show="!bottomBox.showSubList">
<Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
</div>
</div>
<transition name="el-zoom-in-bottom">
<bottom-box :detail="bottomBox.ruleDetail" :from="$CONSTANTS.fromRoute.rule" :is-full-screen="bottomBox.isFullScreen" :obj="bottomBox.alertRule" :sub-resize-show="bottomBox.subResizeShow" :target-tab.sync="bottomBox.targetTab" v-if="bottomBox.showSubList"
@closeSubList="bottomBox.showSubList = false" @fullScreen="fullScreen" @exitFullScreen="exitFullScreen" @listResize="listResize" ></bottom-box>
</transition>
<transition name="right-box">
<alert-config-box v-if="rightBox.show" :alert-rule="alertRule" @close="closeRightBox" ref="alertConfigBox"></alert-config-box>
</transition>
</div>
</template>
<script>
import bus from '../../../libs/bus'
import exportXLSX from '../../common/exportXLSX'
import chartDataFormat from '../../charts/chartDataFormat'
import deleteButton from '../../common/deleteButton'
export default {
name: 'alert-config',
components: {
'export-excel': exportXLSX,
'delete-button': deleteButton
},
data () {
return {
// 侧滑
rightBox: {
show: false
},
/* 二级页面相关 */
bottomBox: {
ruleDetail: {},
alertRule: {},
mainResizeShow: true, // dom高度改变时是否展示|隐藏
subResizeShow: true,
isFullScreen: false, // 全屏状态
showSubList: false, // 是否显示二级列表
targetTab: '', // 显示二级列表中的哪个页签
inTransform: false // 搜索框相关搜索条件下拉框是否在transform里
},
/* 工具参数 */
tools: {
loading: false, // 是否显示table加载动画
toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
tableHover: false, // 控制滚动条和top按钮同时出现
showTopBtn: false, // 显示To top按钮
showCustomTableTitle: false, // 自定义列弹框是否显示
customTableTitle: [] // 自定义列工具的数据
},
mainTableHeight: this.$tableHeight.normal, // 主列表table高度
batchDeleteObjs: [],
tableId: 'alertRuleTable', // 需要分页的table的id用于记录每页数量
alertRule: {},
blankAlertRule: {
id: '',
alertName: '',
linkObject: { id: '', name: '' },
expr: '',
unit: 2,
operator: '>',
last: 60,
severity: 'P2',
summary: '',
description: ''
},
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
id: 1,
name: 'ID',
type: 'input',
label: 'id',
disabled: false
}, {
id: 2,
name: this.$t('alert.alertName'),
type: 'input',
label: 'alertName',
disabled: false
}, {
id: 4,
name: this.$t('alert.severity'),
type: 'selectString',
label: 'severity',
disabled: false
}]
},
searchLabel: { // 搜索参数
},
pageObj: {
pageNo: 1,
pageSize: this.$CONSTANTS.defaultPageSize,
total: 0
},
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('alert.alertName'),
prop: 'alertName',
show: true
// width: 120
}, {
label: this.$t('alert.config.expr'),
prop: 'expr',
show: true
}, {
label: this.$t('alert.config.operator'),
prop: 'operator',
show: true
}, {
label: this.$t('alert.config.threshold'),
prop: 'threshold',
show: true
}, {
label: this.$t('alert.config.for'),
prop: 'last',
show: true
}, {
label: this.$t('alert.severity'),
prop: 'severity',
show: true
}, {
label: this.$t('alert.summary'),
prop: 'summary',
show: true
}, {
label: this.$t('alert.description'),
prop: 'description',
show: true
}, {
label: this.$t('alert.message'),
prop: 'alertNum',
show: true,
width: 90
}, {
label: this.$t('alert.config.receiver'),
prop: 'receivers',
show: true
}, {
label: this.$t('alert.config.option'),
prop: 'option',
show: true,
width: 120
}
],
tableData: [],
viewProjectData: {},
viewModuleData: {},
viewAsset: false,
searchTime: bus.getTimezontDateRange(),
scrollbarWrap: null,
delFlag: false
}
},
methods: {
queryMessage (alertRule) {
if (!this.hasButton('rule_alerts_view')) {
return
}
this.bottomBox.alertRule = alertRule
this.bottomBox.showSubList = true
this.bottomBox.targetTab = 'alertMessage'
},
edit (u) {
this.alertRule = JSON.parse(JSON.stringify(u))
this.rightBox.show = true
},
closeRightBox (refresh) {
this.rightBox.show = false
if (refresh) {
this.delFlag = true
this.getTableData()
}
},
del (u) {
this.$confirm(this.$t('tip.confirmDelete'), {
confirmButtonText: this.$t('tip.yes'),
cancelButtonText: this.$t('tip.no'),
type: 'warning'
}).then(() => {
this.$delete('alert/rule?ids=' + u.id).then(response => {
if (response.code === 200) {
this.delFlag = true
this.$message({ type: 'success', message: this.$t('tip.deleteSuccess') })
this.getTableData()
} else {
this.$message.error(response.msg)
}
})
})
},
formatThreshold (value, unit) {
const unitMethod = chartDataFormat.getUnit(unit)
if (unitMethod && value) {
return unitMethod.compute(value, null, 2)
} else {
return value
}
},
add () {
this.alertRule = this.newAlertRule()
this.rightBox.show = true
},
newAlertRule () {
return JSON.parse(JSON.stringify(this.blankAlertRule))
},
detail (u) {
this.bottomBox.alertRule = JSON.parse(JSON.stringify(u))
this.bottomBox.targetTab = 'panel'
this.bottomBox.showSubList = true
},
messageStyle (e) {
if (e.column.label == 'Message' || e.column.label == this.$t('alert.message')) {
if (e.row.alertNum > 0) {
return 'danger'
} else {
return 'success'
}
}
return ''
},
getTableData () {
if (!this.hasButton('rule_view')) {
this.$message.error(this.$t('tip.noAccess'))
return
}
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
this.$get('alert/rule', this.searchLabel).then(response => {
this.tools.loading = false
if (response.code == 200) {
response.data.list.forEach(item => {
let temp = []
if (item.receiver) {
temp = item.receiver.split(',').map(t => {
return parseInt(t)
})
}
item.receiverShow = temp
})
this.tableData = response.data.list
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
this.scrollbarWrap = this.$refs.alertRuleTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
jumpTo (data, id) {
bus.$emit('menu-change', data)
this.$router.push({
path: '/' + data,
query: {
t: +new Date()
}
})
},
pageNo (val) {
this.pageObj.pageNo = val
this.getTableData()
},
pageSize (val) {
this.pageObj.pageSize = val
localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
this.getTableData()
},
search (searchObj) {
let orderBy = ''
if (this.searchLabel.orderBy) {
orderBy = this.searchLabel.orderBy
}
this.searchLabel = {}
this.pageObj.pageNo = 1
for (const item in searchObj) {
if (searchObj[item]) {
this.$set(this.searchLabel, item, searchObj[item])
}
}
if (orderBy) {
this.$set(this.searchLabel, 'orderBy', orderBy)
}
if (this.$refs.alertRuleTable && this.$refs.alertRuleTable.bodyWrapper) {
this.$refs.alertRuleTable.bodyWrapper.scrollTop = 0
}
this.getTableData()
},
// 全屏
fullScreen () {
const vm = this
this.$bottomBoxWindow.fullScreen(vm)
},
// 退出全屏
exitFullScreen () {
const vm = this
this.$bottomBoxWindow.exitFullScreen(vm)
},
// 鼠标拖动二级列表
listResize (e) {
const vm = this
this.$bottomBoxWindow.listResize(vm, e)
},
convertToDetail (obj) {
const detail = {
id: obj.id,
alertName: obj.alertName,
expr: obj.expr
}
let type = ''
for (let i = 0; i < this.$CONSTANTS.alertMessage.typeData.length; i++) {
if (obj.type == this.$CONSTANTS.alertMessage.typeData[i].value) {
type = this.$CONSTANTS.alertMessage.typeData[i].label
break
}
}
detail.type = type
let link = ''
if (obj.type == 1 || obj.type == 2) {
link = obj.linkObject.name
} else if (obj.type == 3) {
link = obj.linkObject.host
}
detail.link = link
detail.last = obj.last
const severity = this.$CONSTANTS.alertMessage.severityData.find(s => { return s.value == obj.severity })
detail.severity = severity
detail.alertNum = obj.alertNum
detail.description = obj.description
return detail
},
// 数据排序
tableDataSort (item) {
let orderBy = ''
if (item.order === 'ascending') {
orderBy = item.prop
}
if (item.order === 'descending') {
orderBy = '-' + item.prop
}
this.$set(this.searchLabel, 'orderBy', orderBy)
this.getTableData()
},
initEvent () {
bus.$on('alert-rule-list-change', () => {
this.getTableData()
})
bus.$on('dc-list-change', () => {
this.getTableData()
})
bus.$on('alert-message-change', () => {
this.getTableData()
})
}
},
watch: {
'bottomBox.showSubList': function (n) {
const vm = this
this.$bottomBoxWindow.showSubListWatch(vm, n)
},
'bottomBox.alertRule': {
deep: true,
handler (n) {
this.bottomBox.ruleDetail = this.convertToDetail(n)
}
},
tableData: {
deep: true,
handler (n) {
if (n.length === 0 && this.pageObj.pageNo > 1) {
this.pageNo(this.pageObj.pageNo - 1)
}
if (!this.delFlag) { // 不是删除时回到顶部
this.$refs.alertRuleTable.bodyWrapper.scrollTop = 0
} else {
this.delFlag = false
}
}
}
},
beforeDestroy () {
bus.$off('alert-rule-list-change')
bus.$off('dc-list-change')
bus.$off('alert-message-change')
if (this.scrollbarWrap) {
this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
};
},
created () {
// 是否存在分页缓存
const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
if (pageSize != 'undefined' && pageSize != null) {
this.pageObj.pageSize = pageSize
}
},
mounted () {
// 初始化表头
this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
: this.tableTitle
this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
this.initEvent()
this.getTableData()
}
}
</script>

View File

@@ -1,581 +0,0 @@
<template>
<div class="main-list main-and-sub-transition" :class="{'main-list-with-sub': bottomBox.showSubList}">
<!--工具组-->
<div class="top-tools" v-show="bottomBox.mainResizeShow">
<div class="top-tool-main-right" :class="{'top-tool-main-right-to-left': bottomBox.showSubList}">
<div class="top-tool-search margin-r-20">
<search-input :searchMsg="searchMsg" @search="search"
:inTransform="bottomBox.inTransform" :single="true"></search-input>
</div>
<button :title="$t('overall.exportExcelLower')" @click="addSilence" type="button" v-has="'alertsilence_save'"
class="nz-btn nz-btn-size-normal nz-btn-style-light" id="alert-list-export">
<i class="nz-icon nz-icon-create-square"></i>
</button>
<delete-button :delete-objs="batchDeleteObjs" @after="getAlertSilence"
:api="'alert/silence'" v-has="'alert_silence_delete'" id="alert-msg-batch-delete"></delete-button>
</div>
<div class="pagination-top pagination-top-hide display-none"></div>
</div>
<!--表格开始-->
<transition name="el-zoom-in-top">
<element-set
id="alert-rule-element-set"
v-if="tools.showCustomTableTitle"
@close="tools.showCustomTableTitle = false"
:custom-table-title.sync="tools.customTableTitle"
:original-table-title="tableTitle"
ref="customTableTitle"
></element-set>
</transition>
<el-table
id="alert-rule-table"
class="nz-table"
:data="tableData"
border
v-show="bottomBox.mainResizeShow"
ref="alertSilenceTable"
tooltip-effect="light"
:height="mainTableHeight"
v-loading="tools.loading"
style="width: 100%;"
@sort-change="tableDataSort"
@selection-change="(selection)=>{this.batchDeleteObjs=selection}"
>
<el-table-column
:resizable="false"
type="selection"
width="40"
align="center">
</el-table-column>
<el-table-column
:resizable="true"
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:label="item.label"
:show-overflow-tooltip="item.prop!=='matchers'"
:sort-orders="['ascending', 'descending']"
:sortable="$tableSet.sortableShow(item.prop,'alertSilence')"
:prop="$tableSet.propTitle(item.prop,'alertSilence')"
:width="item.width"
>
<template slot-scope="scope" :column="item">
<div v-if="item.prop == 'option'" class="content-right-options">
<span :id="'alert-edit-'+scope.row.id" :title="$t('overall.edit')" @click.stop="edit(scope.row)"
class="content-right-option" v-has="'alert_silence_modify'" v-if="scope.row.state!==3">
<i class="nz-icon nz-icon-edit"></i>
</span>
<span
:id="'alert-del-'+scope.row.id"
:title="$t('overall.delete')"
@click="overtime(scope.row)"
class="content-right-option"
v-if="scope.row.state!==3"
v-has="'alert_silence_delete'">
<i class="nz-icon nz-icon-chaoshi"></i>
</span>
<span
:id="'alert-copy-'+scope.row.id"
:title="$t('overall.copy')"
@click="copyRow(scope.row,'alertSilence')"
class="content-right-option"
v-if="scope.row.state===3"
v-has="'alertsilence_save'">
<i class="nz-icon nz-icon-override"></i>
</span>
</div>
<template v-else-if="item.prop == 'duration'">
<el-tooltip placement="right" effect="light" :disabled="!scope.row.endAt">
<div slot="content">
{{$t('config.terminallog.endTime')}}<br/>
{{scope.row.endAt}}
</div>
<span>{{getDuration(scope.row)}}</span>
</el-tooltip>
</template>
<template v-else-if="item.prop == 'matchers'">
<div class="nz-silence-tag-box">
<span class="nz-silence-tag blue" v-if="scope.row.linkId!==-1">
<span class="nz-silence-tag-title">{{scope.row.type}}</span>
<span class="nz-silence-tag-content" :title="scope.row.linkName">{{scope.row.linkName}}</span>
</span>
<span class="nz-silence-tag rule-gray" v-if="scope.row.ruleId!==-1">
<span class="nz-silence-tag-title">Alert rule</span>
<span class="nz-silence-tag-content" :title="scope.row.ruleName">{{scope.row.ruleName}}</span>
</span>
</div>
</template>
<template v-else-if="item.prop === 'state'">
<span v-if="scope.row.state===1" class="silence-pending">pending</span>
<span v-if="scope.row.state===2" class="silence-active">active</span>
<span v-if="scope.row.state===3" class="silence-expired">expired</span>
</template>
<template v-else-if="item.prop === 'utime'">
{{utcTimeToTimezoneStr(scope.row[item.prop])}}
</template>
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop] || '-'}}</span>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column width="28" :resizable="false">
<template slot="header">
<span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)"
class="nz-table-gear">
<i class="nz-icon nz-icon-gear"></i>
</span>
</template>
</el-table-column>
</el-table>
<button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}"
@click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn && bottomBox.mainResizeShow"
id="alert-rule-toTop"><i class="nz-icon nz-icon-top"></i></button>
<!--表格结束-->
<!--分页部分-->
<div class="pagination-bottom" v-show="!bottomBox.showSubList">
<Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize'
ref="Pagination"></Pagination>
</div>
<!--导出-->
<div class="export-xlsx">
<el-dialog :visible.sync="importBox.show" :title="importBox.title" :modal-append-to-body='false'
:show-close="true" width="300px" @close="closeDialog" class="nz-dialog">
<div class="upload-body">
<button @click="exportCur" class="el-button el-button--default el-button--small" id="alert-msg-exportcur">
<span>{{$t('overall.exportCur')}}</span>
</button>
<button @click="exportAll" class="el-button el-button--default el-button--small" id="alert-msg-exportall">
<span>{{$t('overall.exportAll')}}</span>
</button>
</div>
</el-dialog>
</div>
<!--侧滑-->
<transition name="right-box">
<alert-silence-box v-if="rightBox.show" :alert-silence="alertSilence" @close="closeRightBox"
ref="alertSilenceBox"></alert-silence-box>
</transition>
</div>
</template>
<script>
import bus from '../../../libs/bus'
import deleteButton from '../../common/deleteButton'
import alertSilenceBox from '../../common/rightBox/alertSilenceBox'
import { calcDurationByStringTimeB } from '../../common/js/tools'
export default {
name: 'silence',
components: {
deleteButton,
alertSilenceBox
},
data () {
return {
tableId: 'silence',
// 侧滑
rightBox: {
show: false
},
/* 二级列表相关 */
mainTableHeight: this.$tableHeight.normal, // 主列表table高度
/* 二级页面相关 */
bottomBox: {
tabList: [], // 二级列表的标签
tabDetailList: [], // 多个详情
mainResizeShow: true, // dom高度改变时是否展示|隐藏
subResizeShow: true,
isFullScreen: false, // 全屏状态
showSubList: false, // 是否显示二级列表
targetTab: '', // 显示二级列表中的哪个页签
inTransform: false // 搜索框相关搜索条件下拉框是否在transform里
},
/* 工具参数 */
tools: {
loading: false, // 是否显示table加载动画
toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
tableHover: false, // 控制滚动条和top按钮同时出现
showTopBtn: false, // 显示To top按钮
showCustomTableTitle: false, // 自定义列弹框是否显示
customTableTitle: [] // 自定义列工具的数据
},
/* 批量删除相关 */
batchDeleteObjs: [],
/* 搜素相关 */
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [
{
id: 11,
name: this.$t('alert.silence.datacenter'),
type: 'input',
label: 'datacenter',
disabled: false
}, {
id: 12,
name: this.$t('alert.silence.project'),
type: 'input',
label: 'project',
disabled: false
}, {
id: 13,
name: this.$t('alert.silence.module'),
type: 'input',
label: 'module',
disabled: false
}, {
id: 14,
name: this.$t('alert.silence.endpoint'),
type: 'input',
label: 'endpoint',
disabled: false
}, {
id: 15,
name: this.$t('alert.silence.asset'),
type: 'input',
label: 'asset ',
disabled: false
}
]
},
searchLabel: {}, // 搜索参数
pageObj: {
pageNo: 1,
pageSize: this.$CONSTANTS.defaultPageSize,
total: 0
},
/* 表格相关 */
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: 'matchers',
prop: 'matchers',
show: true,
width: 600
}, {
label: 'Start time',
prop: 'startAt',
show: true,
width: 300
}, {
label: this.$t('config.terminallog.duration'),
prop: 'duration',
show: true
}, {
label: 'Reason',
prop: 'reason',
show: true
}, {
label: 'Update time',
prop: 'utime',
show: true
}, {
label: 'State',
prop: 'state',
show: true,
width: 120
}, {
label: this.$t('alert.config.option'),
prop: 'option',
show: true,
width: 120
}
],
tableData: [],
// 导出相关
importBox: { show: false, title: this.$t('overall.exportExcel') },
deleteBox: { show: false, ids: '', remark: '', state: 2 },
// 创建修改相关
blackSilence: {
id: '',
startAt: '',
endAt: '',
ruleId: '',
matcher: '',
type: 'asset',
linkId: '',
reason: ''
},
alertSilence: {
},
nowTime: ''
}
},
computed: {
getDuration () {
return function (record) {
if (record.endAt) {
return calcDurationByStringTimeB(record.startAt, record.endAt)
}
return calcDurationByStringTimeB(record.startAt, this.nowTime)
}
}
},
created () {
},
mounted () {
// 初始化表头
this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
: this.tableTitle
this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
this.initEvent()
this.getAlertSilence()
},
methods: {
initEvent () {
bus.$on('alert-rule-list-change', () => {
this.getAlertSilence()
})
bus.$on('dc-list-change', () => {
this.getAlertSilence()
})
bus.$on('alert-message-change', () => {
this.getAlertSilence()
})
},
getAlertSilence () {
if (!this.hasButton('rule_view')) {
this.$message.error(this.$t('tip.noAccess'))
return
}
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
this.$get('alert/silence', this.searchLabel).then(response => {
this.tools.loading = false
if (response.code == 200) {
this.tableData = response.data.list
this.pageObj.total = response.data.total
this.nowTime = this.utcTimeToTimezoneStr(response.time)
if (!this.scrollbarWrap) {
this.$nextTick(() => {
this.scrollbarWrap = this.$refs.alertSilenceTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
pageNo (val) {
this.pageObj.pageNo = val
this.getAlertSilence()
},
pageSize (val) {
this.pageObj.pageSize = val
localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
this.getAlertSilence()
},
search (searchObj) {
let orderBy = ''
if (this.searchLabel.orderBy) {
orderBy = this.searchLabel.orderBy
}
this.searchLabel = {}
this.pageObj.pageNo = 1
for (const item in searchObj) {
if (searchObj[item]) {
this.$set(this.searchLabel, 'type', item)
this.$set(this.searchLabel, 'query', searchObj[item])
}
}
if (orderBy) {
this.$set(this.searchLabel, 'orderBy', orderBy)
}
this.$refs.alertSilenceTable.bodyWrapper.scrollTop = 0
this.getAlertSilence()
},
// 数据排序
tableDataSort (item) {
let orderBy = ''
if (item.order === 'ascending') {
orderBy = item.prop
}
if (item.order === 'descending') {
orderBy = '-' + item.prop
}
this.$set(this.searchLabel, 'orderBy', orderBy)
this.getAlertSilence()
},
openDelMessageBox: function () {
// if (this.batchDeleteObjs.length < 1) return
},
showExportDialog () {
this.importBox.show = true
},
closeDialog () {
this.importBox.show = false
this.deleteBox.show = false
},
exportCur: function () {
const searchLabel = Object.assign({}, this.searchLabel)
this.$set(searchLabel, 'language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en')
this.exportExcel(searchLabel)
this.closeDialog()
},
exportAll: function () {
const temp = JSON.parse(JSON.stringify(this.searchLabel))
temp.pageSize = -1
this.$set(temp, 'language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en')
this.exportExcel(temp)
this.closeDialog()
},
addSilence () {
this.blackSilence.startAt = bus.timeFormate(bus.getOffsetTimezoneData(), 'yyyy-MM-dd hh:mm:ss')
this.blackSilence.endAt = bus.timeFormate(bus.getOffsetTimezoneData(1), 'yyyy-MM-dd hh:mm:ss')
this.alertSilence = JSON.parse(JSON.stringify(this.blackSilence))
this.rightBox.show = true
},
edit (row) {
this.$get('alert/silence/' + row.id).then(res => {
this.alertSilence = { ...res.data }
this.rightBox.show = true
})
},
del (row) {
if (this.prevent_opt.save) {
return
}
;
this.prevent_opt.save = true
this.$confirm(this.$t('tip.confirmDelete'), {
confirmButtonText: this.$t('tip.yes'),
cancelButtonText: this.$t('tip.no'),
type: 'warning'
}).then(() => {
this.$delete('alert/silence?ids=' + row.id).then(response => {
this.prevent_opt.save = false
if (response.code === 200) {
this.$message({ type: 'success', message: this.$t('tip.deleteSuccess') })
this.getAlertSilence()
} else {
this.$message.error(response.msg)
}
})
}).catch(() => {
this.prevent_opt.save = false
})
},
overtime (row) {
if (this.prevent_opt.save) {
return
}
;
this.prevent_opt.save = true
this.$confirm(this.$t('tip.confirmOvertime'), {
confirmButtonText: this.$t('tip.yes'),
cancelButtonText: this.$t('tip.no'),
type: 'warning'
}).then(() => {
this.$delete('alert/silence?ids=' + row.id).then(response => {
this.prevent_opt.save = false
if (response.code === 200) {
this.$message({ type: 'success', message: this.$t('tip.deleteSuccess') })
this.getAlertSilence()
} else {
this.$message.error(response.msg)
}
})
}).catch(() => {
this.prevent_opt.save = false
})
},
closeRightBox (refresh) {
this.rightBox.show = false
if (refresh) {
this.delFlag = true
this.getAlertSilence()
}
}
}
}
</script>
<style scoped lang="scss">
.content-right-options{
display: flex;
justify-content: start;
sapn:not(:first-child){
margin-left: 10px;
}
}
.nz-silence-tag-box{
width: 100%;
height: 100%;
.nz-silence-tag{
/*float: left;*/
/*margin-top: 5px;*/
}
}
.nz-silence-tag{
min-width: 80px;
margin-right: 5px;
border-radius: 4px;
display: inline-flex;
width: auto;
height: 20px;
line-height: 20px;
.nz-silence-tag-title{
color: #fff;
text-align: center;
padding: 0 5px;
}
.nz-silence-tag-content{
padding: 0 10px;
max-width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
}
}
.nz-silence-tag.blue{
border: 1px solid #3C92F1;
.nz-silence-tag-title{
background: #3C92F1;
}
}
.nz-silence-tag.rule-gray{
border: 1px solid #7F8696;
.nz-silence-tag-title{
background: #7F8696;
}
}
.silence-active{
background: #E3F2D9;
border-radius: 4px;
font-family: PingFangSC-Regular;
font-size: 14px;
color: #0AB000;
line-height: 14px;
font-weight: 400;
padding: 0 5px;
}
.silence-pending{
background: #FFECD9;
border-radius: 4px;
font-family: PingFangSC-Regular;
font-size: 14px;
color: #FA901C;
line-height: 20px;
font-weight: 400;
padding: 0 5px;
}
.silence-expired{
background: #9e9c98;
border-radius: 4px;
font-family: PingFangSC-Regular;
font-size: 14px;
color: #ffffff;
line-height: 14px;
font-weight: 400;
padding: 0 5px;
}
</style>

View File

@@ -0,0 +1,337 @@
<template>
<div>
<nz-data-list
ref="dataList"
:api="url"
:custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.agent"
:layout="['searchInput', 'elementSet']"
:search-msg="searchMsg">
<template v-slot:top-tool-right>
<button id="prom-add" v-has="'agent_add'" :title="$t('overall.createPrometheusServer')" class="top-tool-btn margin-r-10"
type="button" @click="add">
<i class="nz-icon-create-square nz-icon"></i>
</button>
<button id="load-agent" class="top-tool-btn margin-r-10" type="button" @click="toDownloadAgent">
<i class="nz-icon-download nz-icon"></i>
</button>
<delete-button id="promserver-list-batch-delete" v-has="'agent_delete'" :delete-objs="batchDeleteObjs" api="agent" @after="getTableData" @before="delFlag=true"></delete-button>
</template>
<template v-slot:default="slotProps">
<agent-table
ref="dataTable"
v-loading="slotProps.loading"
:api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight"
:table-data="tableData"
@del="del"
@edit="edit"
@orderBy="tableDataSort"
@reload="getTableData"
@selectionChange="selectionChange"
@showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"></agent-table>
</template>
<!-- 分页组件 -->
<template v-slot:pagination>
<Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
</template>
</nz-data-list>
<transition name="right-box">
<agent-box v-if="rightBox.show" :prom-server="object" @close="closeRightBox"></agent-box>
</transition>
<el-dialog :title="$t('config.agent.agent.title')" :visible.sync="showAgentDownload" append-to-body class="nz-dialog agent-dialog" width="620px" @close="closeDialog">
<div v-if="showAgentDownload" class="agent-box">
<el-form v-model="agentParam" class="right-box-form right-box-form-left" label-position = "top" label-width="120px" size="small" style="width: 100%">
<div class="right-box-sub-title">{{$t('config.agent.agent.download')}}</div>
<div style="margin-bottom: 20px;width: 100%"></div>
<el-form-item :label="$t('config.agent.agent.osType')" class="half-form-item" prop="osType">
<el-select v-model="agentParam.osType" class="right-box-row-with-btn" placeholder="">
<el-option v-for="item in osTypes" :key="item.name" :label="item.label" :value="item.name">
<span class="panel-dropdown-label-txt" >{{item.label}}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item class="half-form-item">
<button class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" type="button" @click="downloadAgent">{{$t('config.agent.agent.download')}}</button>
</el-form-item>
<div class="right-box-sub-title">{{$t('config.agent.agent.autoScript')}}</div>
<div style="margin-bottom: 20px;width: 100%"></div>
<el-form-item :label="$t('config.dc.dc')" class="half-form-item" prop="dc">
<el-select v-model="agentParam.dc" class="right-box-row-with-btn" placeholder="">
<el-option v-for="item in allDc" :key="item.id" :label="item.name" :value="item.id">
<span class="panel-dropdown-label-txt" >{{item.name}}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('config.agent.agent.type')" class="half-form-item" prop="type">
<el-select v-model="agentParam.type" class="right-box-row-with-btn" placeholder="">
<el-option v-for="item in agent2.theData" :key="item.value" :label="item.label" :value="item.value">
<span class="panel-dropdown-label-txt" >{{item.label}}</span>
</el-option>
</el-select>
</el-form-item>
</el-form>
<div v-if="loadFinish" class="download-url">
<el-input id="download-url-curl" v-model="curlUrl" :disabled="true">
<el-popover slot="suffix" v-model="curlVisible" :content="$t('tip.copySuccess')" placement="top" popper-class="small-pop" trigger="manual" @after-enter="popShow('curl')">
<i slot="reference" class="nz-icon nz-icon-override" @click="copyUrl('download-url-curl')"></i>
</el-popover>
</el-input>
</div>
<div v-if="loadFinish" class="download-url">
<el-input id="download-url-wget" v-model="wgetUrl" :disabled="true">
<el-popover slot="suffix" v-model="wgetVisible" :content="$t('tip.copySuccess')" placement="top" popper-class="small-pop" trigger="manual" @after-enter="popShow('wget')">
<i slot="reference" class="nz-icon nz-icon-override" @click="copyUrl('download-url-wget')"></i>
</el-popover>
</el-input>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import deleteButton from '@/components/common/deleteButton'
import agentBox from '@/components/common/rightBox/agentBox'
import { agent, agent2 } from '@/components/common/js/constants'
import nzDataList from '@/components/common/table/nzDataList'
import dataListMixin from '@/components/common/mixin/dataList'
import agentTable from '@/components/common/table/settings/agentTable'
import axios from 'axios'
export default {
name: 'agent',
components: {
nzDataList,
agentBox,
agentTable,
deleteButton
},
mixins: [dataListMixin],
computed: {
wgetUrl () {
return 'wget -qO- --header="Authorization:'+this.token+'" '+ this.ipAddr+'/agent/'+this.agentParam.dc+'/'+this.agentParam.type+'/install.sh | bash'
},
curlUrl () {
return 'curl -o- -H "Authorization:'+this.token+'" '+ this.ipAddr+'/agent/'+this.agentParam.dc+'/'+this.agentParam.type+'/install.sh | bash'
}
},
data () {
return {
url: 'agent',
tableId: 'promTable', // 需要分页的table的id用于记录每页数量
blankObject: {
id: '',
host: '',
port: 9090,
dc: { id: '', name: '', location: '' }
},
agent: agent,
agent2: agent2,
dcData: [],
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
id: 1,
name: 'ID',
type: 'input',
label: 'id',
disabled: false
}, {
id: 5,
name: this.$t('config.agent.dataCenter'),
type: 'dc',
label: 'dc',
disabled: false
}, {
id: 6,
name: this.$t('config.agent.type'),
type: 'select',
label: 'promType',
disabled: false
}, {
id: 8,
name: this.$t('project.endpoint.host'),
type: 'input',
label: 'host',
disabled: false
}, {
id: 9,
name: this.$t('project.endpoint.port'),
type: 'input',
label: 'port',
disabled: false
}]
},
promServerType: null,
showAgentDownload: false,
token: '',
ipAddr: '',
allDc: [],
loadFinish: false,
osTypes: [{
label: 'Centos',
name: 'centos'
},
{
label: 'Ubuntu',
name: 'ubuntu'
}],
agentParam: {
osType: 'centos',
dc: '',
type: 1
},
wgetVisible: false,
curlVisible: false
}
},
methods: {
toDownloadAgent: function () {
this.showAgentDownload = true
this.token = sessionStorage.getItem('nz-token')
axios.get('/healthy').then(response => {
const url = response.request.responseURL
this.ipAddr = url.split('/healthy')[0]
})
},
closeDialog: function () {
this.showAgentDownload = false
},
getAllDc () {
this.$get('dc?pageSize=-1').then(response => {
this.tools.loading = false
if (response.code === 200) {
this.allDc = response.data.list
this.loadFinish = true
this.agentParam.dc = this.allDc[0].id
}
})
},
copyUrl (id) {
const input = document.createElement('input')
const text = document.getElementById(id).value
document.body.appendChild(input)
input.setAttribute('value', text)
input.select()
if (document.execCommand('copy')) {
document.execCommand('copy')
}
document.body.removeChild(input)
if(id.indexOf('curl') != -1){
this.curlVisible = true
// let timeout = setTimeout(()=>{
// this.curlVisible = false;
// clearTimeout(timeout)
// },1000)
}else{
this.wgetVisible = true
// let timeout = setTimeout(()=>{
// this.wgetVisible = false;
// clearTimeout(timeout)
// },1000)
}
},
popShow:function(where){
const self = this
if(where == 'curl'){
let timeout = setTimeout(()=>{
self.curlVisible = false;
clearTimeout(timeout)
},1000)
}else{
let timeout = setTimeout(()=>{
self.wgetVisible = false;
clearTimeout(timeout)
},1000)
}
},
downloadAgent: function () {
axios.get('agent/download?os=' + this.agentParam.osType, { responseType: 'blob' }).then(data => {
let fileName = 'confagent'
const disposition = data.headers['content-disposition']
if (disposition) {
fileName = disposition.split(';')[1].split('filename=')[1]
}
// 由于ie不支持download属性故需要做兼容判断
if (navigator.appVersion.toString().indexOf('.NET') > 0) {
// ie独有的msSaveBlob属性data.data为Blob文件流
window.navigator.msSaveBlob(data.data, fileName)
} else {
// 以下流程即为文章开始的下载流程
const url = window.URL.createObjectURL(data.data)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.download = fileName
document.body.appendChild(link)
link.click()
window.URL.revokeObjectURL(link.href)
}
})
}
},
mounted () {
this.getAllDc()
}
}
</script>
<style scoped>
.agent-dialog .agent-box{
padding:10px;
}
.agent-box >.right-box-form>.el-form-item.half-form-item{
width: 220px;
}
.agent-box >.right-box-form>.el-form-item.half-form-item:nth-child(odd){
width: 220px;
}
.agent-box .download-url{
height: 40px;
position: relative;
margin-bottom: 10px;
}
.agent-box .download-url .url-copy{
position: absolute;
right: 10px;
top: 5px;
}
.agent-box .download-url .url-copy i{
font-size: 20px;
}
.agent-box .download-url pre code {
border: 1px solid #ddd;
border-radius: 0;
font-family: "Courier New", Monaco, Menlo, Consolas, monospace;
line-height: 40px;
padding: 5px 20px 5px 5px;
white-space: nowrap;
background-color: #F6F8FA;;
color: #333;
}
.agent-box .download-url code {
color: #333;
}
</style>
<style>
.download-url > .el-input.is-disabled .el-input__inner{
background-color: #F6F8FA;;
border-color: #E4E7ED;
color: #333;
cursor: text;
}
.download-url .el-input__suffix {
position: absolute;
top: 8px;
-webkit-transition: all .3s;
height: 100%;
color: #333;
text-align: center;
}
</style>

View File

@@ -1,127 +1,33 @@
<template> <template>
<div style="height: 100%"> <div>
<nz-data-list <nz-data-list
ref="dataList" ref="dataList"
:components="['searchInput', 'elementSet']" :api="url"
:layout="['searchInput', 'elementSet']"
:custom-table-title.sync="tools.customTableTitle" :custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.dc" :from="fromRoute.dc"
:search-msg="searchMsg" :search-msg="searchMsg">
:table-id="tableId"
:table-title="tableTitle">
<template v-slot:top-tool-right> <template v-slot:top-tool-right>
<button id="dc-add" v-has="'dc_toAdd'" :title="$t('overall.createDatacenter')" class="top-tool-btn margin-l-20" <button id="dc-add" v-has="'dc_add'" :title="$t('overall.createDatacenter')" class="top-tool-btn margin-r-10"
type="button" @click="add"> type="button" @click="add">
<i class="nz-icon-create-square nz-icon"></i> <i class="nz-icon-create-square nz-icon"></i>
</button> </button>
<delete-button id="account-list-batch-delete" v-has="'dc_delete'" :delete-objs="batchDeleteObjs" api="dc" @after="getTableData" @before="delFlag=true"></delete-button> <delete-button id="account-list-batch-delete" v-has="'dc_delete'" :delete-objs="batchDeleteObjs" api="dc" @after="getTableData" @before="delFlag=true"></delete-button>
</template> </template>
<template v-slot:default="slotProps"> <template v-slot:default="slotProps">
<el-table <dc-table
id="dc-list-table"
ref="dataTable" ref="dataTable"
v-loading="tools.loading" v-loading="slotProps.loading"
:data="tableData" :api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight" :height="mainTableHeight"
:cell-class-name="assetStatClassName" :table-data="tableData"
border @del="del"
@header-dragend="dragend" @edit="edit"
@sort-change="tableDataSort" @orderBy="tableDataSort"
@selection-change="(selection)=>{batchDeleteObjs=selection}" @reload="getTableData"
> @selectionChange="selectionChange"
<el-table-column @showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"></dc-table>
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:sortable="sortableShow(item.prop, fromRoute.dc)"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</span>
</template>
<template slot-scope="scope" :column="item">
<template v-if="item.prop === 'principal'">
<template v-if="scope.row.principal">
<template v-for="item in userData">
<template v-if="scope.row.principal == item.userId">{{item.username}}</template>
</template>
</template>
<template v-else>-</template>
</template>
<template v-else-if="item.prop === 'state'">
<el-switch
v-model="scope.row.state"
:disabled="!hasButton('dc_toEdit') || !hasButton('dc_toEdit')"
active-color="#ee9d3f"
active-value="ON"
inactive-value="OFF"
@change="(val)=>{statusChange(scope.row)}"
/>
</template>
<template v-else-if="item.prop === 'longitude'">
<template v-if="regNumTest(scope.row.longitude)">{{scope.row.longitude}}</template>
<template v-else>-</template>
</template>
<template v-else-if="item.prop === 'latitude'">
<template v-if="regNumTest(scope.row.latitude)">{{scope.row.latitude}}</template>
<template v-else>-</template>
</template>
<template v-else-if="item.prop === 'assetStat' && scope.row.assetStat">
<el-popover
:content="$t('overall.result.total') + '' + scope.row.assetStat.total + '' + $t('asset.inStock') + '' + scope.row.assetStat.inStock + '' + $t('asset.notInStock') + '' + scope.row.assetStat.outStock + '' + $t('asset.suspended') + '' + scope.row.assetStat.suspended"
placement="top"
trigger="hover">
<div slot="reference" class="dc-asset-states">
<span class="dc-asset-state dc-asset-state-total">{{scope.row.assetStat.total}}</span>
<span class="dc-asset-state dc-asset-state-in">{{scope.row.assetStat.inStock}}</span>
<span class="dc-asset-state dc-asset-state-out">{{scope.row.assetStat.outStock}}</span>
<span class="dc-asset-state dc-asset-state-suspended">{{scope.row.assetStat.suspended}}</span>
</div>
</el-popover>
</template >
<template v-else-if="item.prop === 'cabinetNum'">
<span class="link" @click="$refs.dataList.showBottomBox('cabinet', scope.row)">{{scope.row[item.prop]}}</span>
</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
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
<el-dropdown-item :command="['delete', scope.row, `dc?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
<!-- 回到table顶部的按钮 -->
<button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="dc-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
</template> </template>
<!-- 分页组件 --> <!-- 分页组件 -->
<template v-slot:pagination> <template v-slot:pagination>
@@ -135,7 +41,6 @@
<traffic-setting-box v-if="rightBox.trafficSetting.show" ref="trafficBox" :dc="object" @close="closeTrafficBox"></traffic-setting-box> <traffic-setting-box v-if="rightBox.trafficSetting.show" ref="trafficBox" :dc="object" @close="closeTrafficBox"></traffic-setting-box>
</transition> </transition>
<span v-if="dcDataRefresh" style="display: none"></span> <span v-if="dcDataRefresh" style="display: none"></span>
</div> </div>
</template> </template>
<script> <script>
@@ -144,21 +49,22 @@ import dcBox from '@/components/common/rightBox/dcBox' // dc弹框
import trafficSettingBox from '@/components/common/rightBox/trafficSetting/trafficSettingBox' import trafficSettingBox from '@/components/common/rightBox/trafficSetting/trafficSettingBox'
import deleteButton from '@/components/common/deleteButton' import deleteButton from '@/components/common/deleteButton'
import nzDataList from '@/components/common/table/nzDataList' import nzDataList from '@/components/common/table/nzDataList'
import tableMixin from '@/components/common/mixin/table' import dataListMixin from '@/components/common/mixin/dataList'
const regNum = /^[0-9]+.?[0-9]*/ import dcTable from '@/components/common/table/settings/dcTable'
export default { export default {
name: 'dc', name: 'dc',
components: { components: {
trafficSettingBox, trafficSettingBox,
dcBox, dcBox,
deleteButton, deleteButton,
nzDataList nzDataList,
dcTable
}, },
mixins: [tableMixin], mixins: [dataListMixin],
data () { data () {
return { return {
url: 'dc',
tableId: 'dcTable', // 需要分页的table的id用于记录每页数量 tableId: 'dcTable', // 需要分页的table的id用于记录每页数量
object: {},
blankObject: { blankObject: {
id: '', id: '',
name: '', name: '',
@@ -173,50 +79,6 @@ export default {
dc: { show: false }, dc: { show: false },
trafficSetting: { show: false } trafficSetting: { show: false }
}, },
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('overall.name'),
prop: 'name',
show: true
}, {
label: this.$t('asset.location'),
prop: 'location',
show: true
}, {
label: this.$t('config.dc.cabinetNum'),
prop: 'cabinetNum',
show: true
}, {
label: this.$t('config.dc.assets'),
prop: 'assetStat',
show: true
}, {
label: this.$t('asset.tel'),
prop: 'tel',
show: true
}, {
label: this.$t('asset.principal'),
prop: 'principal',
show: true
}, {
label: this.$t('config.dc.longitude'),
prop: 'longitude',
show: false
}, {
label: this.$t('config.dc.latitude'),
prop: 'latitude',
show: false
}, {
label: this.$t('config.dc.state'),
prop: 'state',
show: true
}
],
searchMsg: { // 给搜索框子组件传递的信息 searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true, zheze_none: true,
searchLabelList: [{ searchLabelList: [{
@@ -227,8 +89,8 @@ export default {
disabled: false disabled: false
}] }]
}, },
regNum: /^[0-9]+.?[0-9]*/,
tabShow: 1, // 控制显示一级页面和二级页面 1 dc 2cabinet tabShow: 1, // 控制显示一级页面和二级页面 1 dc 2cabinet
delFlag: false,
userData: [] userData: []
} }
}, },
@@ -249,10 +111,10 @@ export default {
}, },
edit (u) { edit (u) {
this.dc = JSON.parse(JSON.stringify(u)) this.dc = JSON.parse(JSON.stringify(u))
if (!regNum.test(this.dc.longitude)) { if (!this.regNum.test(this.dc.longitude)) {
this.dc.longitude = undefined this.dc.longitude = undefined
} }
if (!regNum.test(this.dc.latitude)) { if (!this.regNum.test(this.dc.latitude)) {
this.dc.latitude = undefined this.dc.latitude = undefined
} }
if (!this.dc.area) { if (!this.dc.area) {
@@ -297,28 +159,6 @@ export default {
this.getTableData() this.getTableData()
}) })
}, },
getTableData () {
if (!this.hasButton('dc_view')) {
this.$message.error(this.$t('tip.noAccess'))
return
}
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
this.$get('dc', this.searchLabel).then(response => {
this.tools.loading = false
if (response.code === 200) {
this.tableData = response.data.list
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
getUserData () { getUserData () {
return new Promise(resolve => { return new Promise(resolve => {
this.$get('sys/user', { pageSize: -1, pageNo: 1 }).then(response => { this.$get('sys/user', { pageSize: -1, pageNo: 1 }).then(response => {
@@ -330,7 +170,7 @@ export default {
}) })
}, },
regNumTest (val) { // 校验是否是数字 regNumTest (val) { // 校验是否是数字
return regNum.test(val) return this.regNum.test(val)
}, },
initEvent () { initEvent () {
bus.$on('dc-list-change', () => { bus.$on('dc-list-change', () => {

View File

@@ -1,27 +1,26 @@
<template> <template>
<div style="height: 100%"> <div>
<nz-data-list <nz-data-list
ref="dataList" ref="dataList"
:components="['searchInput', 'elementSet']" :api="url"
:layout="['searchInput', 'elementSet']"
:custom-table-title.sync="tools.customTableTitle" :custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.expressionTemplate" :from="fromRoute.expressionTemplate"
:search-msg="searchMsg" :search-msg="searchMsg">
:table-id="tableId"
:table-title="tableTitle">
<template v-slot:top-tool-right> <template v-slot:top-tool-right>
<export-excel <export-excel
id="expression-template-list" id="expression-template-list"
class="top-tool-export margin-l-20" v-has="'expressionTemplate_add'"
export-url="expression/tmpl/export" export-url="expression/tmpl/export"
import-url="expression/tmpl/import" import-url="expression/tmpl/import"
export-file-name="expression-template" export-file-name="expression-template"
:params="searchLabel" :params="searchLabel"
:permissions="{import: 'asset_import', export: 'asset_export'}" :permissions="{import: 'asset_import', export: 'asset_export'}"
@afterImport="getTableData" @afterImport="getTableData"
v-has="'expr_temp_save'" class="top-tool-export margin-r-10"
> >
<template slot="optionZone"> <template slot="optionZone">
<button id="expr-tmpl-list-export" v-has="'expr_temp_save'" :title="$t('overall.createTemplate')" class="top-tool-btn" <button id="expr-tmpl-list-export" v-has="'expressionTemplate_add'" :title="$t('overall.createTemplate')" class="top-tool-btn"
type="button" @click="add"> type="button" @click="add">
<i class="nz-icon nz-icon-create-square"></i> <i class="nz-icon nz-icon-create-square"></i>
</button> </button>
@@ -29,75 +28,30 @@
</export-excel> </export-excel>
<delete-button :delete-objs="batchDeleteObjs" @after="getTableData" <delete-button :delete-objs="batchDeleteObjs" @after="getTableData"
:api="'expression/tmpl'" v-has="'expr_temp_delete'" id="alert-msg-batch-delete"></delete-button> id="alert-msg-batch-delete" v-has="'expressionTemplate_delete'" :api="url"></delete-button></template>
</template>
<template v-slot:default="slotProps"> <template v-slot:default="slotProps">
<el-table <expr-tmpl-table
id="role-list-table"
ref="dataTable" ref="dataTable"
v-loading="tools.loading" v-loading="slotProps.loading"
:data="tableData" :api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight" :height="mainTableHeight"
border :table-data="tableData"
@header-dragend="dragend" @del="del"
@sort-change="tableDataSort" @edit="edit"
@selection-change="(selection)=>{batchDeleteObjs=selection}" @orderBy="tableDataSort"
> @reload="getTableData"
<el-table-column @selectionChange="selectionChange"
:resizable="false" @showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"></expr-tmpl-table>
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<span v-if="scope.row[item.prop]">{{scope.row[item.prop] || '-'}}</span>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
<el-dropdown-item :command="['copy', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-override"></i><span class="operation-dropdown-text">{{$t('config.exprTemp.copy')}}</span></el-dropdown-item>
<el-dropdown-item :command="['delete', scope.row, `sys/role?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
<!-- 回到table顶部的按钮 -->
<button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
</template> </template>
<!-- 分页组件 --> <!-- 分页组件 -->
<template v-slot:pagination> <template v-slot:pagination>
<Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination> <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
</template> </template>
</nz-data-list> </nz-data-list>
<transition name="right-box">
<expr-tmpl-box v-if="rightBox.show" :exprTemp="object" @close="closeRightBox"></expr-tmpl-box>
</transition>
<!--导出--> <!--导出-->
<div class="export-xlsx"> <div class="export-xlsx">
<el-dialog :visible.sync="importBox.show" :title="importBox.title" :modal-append-to-body='false' <el-dialog :visible.sync="importBox.show" :title="importBox.title" :modal-append-to-body='false'
@@ -112,34 +66,31 @@
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
<!--侧滑-->
<transition name="right-box">
<exprTempBox v-if="rightBox.show" ref="exprTempBox" :exprTemp="object"
@close="closeRightBox"></exprTempBox>
</transition>
</div> </div>
</template> </template>
<script> <script>
import bus from '@/libs/bus' import bus from '@/libs/bus'
import exportXLSX from '@/components/common/exportXLSX' import exportXLSX from '@/components/common/exportXLSX'
import exprTempBox from '@/components/common/rightBox/exprTempBox' import exprTmplBox from '@/components/common/rightBox/exprTmplBox'
import { calcDurationByStringTimeB } from '@/components/common/js/tools'
import deleteButton from '@/components/common/deleteButton' import deleteButton from '@/components/common/deleteButton'
import nzDataList from '@/components/common/table/nzDataList' import nzDataList from '@/components/common/table/nzDataList'
import tableMixin from '@/components/common/mixin/table' import dataListMixin from '@/components/common/mixin/dataList'
import exprTmplTable from '@/components/common/table/settings/exprTmplTable'
export default { export default {
name: 'exprTemp', name: 'exprTemp',
components: { components: {
deleteButton, deleteButton,
exprTempBox, exprTmplBox,
nzDataList, nzDataList,
exprTmplTable,
'export-excel': exportXLSX 'export-excel': exportXLSX
}, },
mixins: [tableMixin], mixins: [dataListMixin],
data () { data () {
return { return {
url: 'expression/tmpl',
tableId: 'exprTemp', tableId: 'exprTemp',
/* 搜素相关 */ /* 搜素相关 */
searchMsg: { // 给搜索框子组件传递的信息 searchMsg: { // 给搜索框子组件传递的信息
@@ -166,31 +117,6 @@ export default {
} }
] ]
}, },
/* 表格相关 */
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.exprTemp.name'),
prop: 'name',
show: true
}, {
label: this.$t('config.exprTemp.gname'),
prop: 'gname',
show: true
}, {
label: this.$t('config.exprTemp.expression'),
prop: 'expression',
show: true
}, {
label: this.$t('config.exprTemp.remark'),
prop: 'remark',
show: true
}
],
// 导出相关 // 导出相关
importBox: { show: false, title: this.$t('overall.exportExcel') }, importBox: { show: false, title: this.$t('overall.exportExcel') },
deleteBox: { show: false, ids: '', remark: '', state: 2 }, deleteBox: { show: false, ids: '', remark: '', state: 2 },
@@ -205,16 +131,6 @@ export default {
nowTime: '' nowTime: ''
} }
}, },
computed: {
getDuration () {
return function (record) {
if (record.endAt) {
return calcDurationByStringTimeB(record.startAt, record.endAt)
}
return calcDurationByStringTimeB(record.startAt, this.nowTime)
}
}
},
mounted () { mounted () {
this.initEvent() this.initEvent()
}, },
@@ -230,29 +146,6 @@ export default {
this.getTableData() this.getTableData()
}) })
}, },
getTableData () {
if (!this.hasButton('rule_view')) {
this.$message.error(this.$t('tip.noAccess'))
return
}
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
this.$get('expression/tmpl', this.searchLabel).then(response => {
this.tools.loading = false
if (response.code == 200) {
this.tableData = response.data.list
this.pageObj.total = response.data.total
this.nowTime = this.utcTimeToTimezoneStr(response.time)
if (!this.scrollbarWrap) {
this.$nextTick(() => {
this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
showExportDialog () { showExportDialog () {
this.importBox.show = true this.importBox.show = true
}, },

View File

@@ -3,122 +3,40 @@
<nz-data-list <nz-data-list
v-if="showTab === 'file'" v-if="showTab === 'file'"
ref="dataList" ref="dataList"
:components="['searchInput', 'elementSet']" :api="url"
:custom-table-title.sync="tools.customTableTitle" :custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.mib" :from="fromRoute.mib"
:search-msg="searchMsg" :layout="['searchInput', 'elementSet']"
:table-id="tableId" :search-msg="searchMsg">
:table-title="tableTitle"> <!-- <template v-slot:top-tool-left>
<template v-slot:top-tool-left>
<div id="module-type-1" class="nz-tab-item-box"> <div id="module-type-1" class="nz-tab-item-box">
<div class="nz-tab-item nz-tab-item-active">{{$t("config.mib.mibFiles")}}</div> <div class="nz-tab-item nz-tab-item-active">{{$t("config.mib.mibFiles")}}</div>
</div> </div>
<div id="module-type-2" v-has="'snmp_browser_view'" class="nz-tab-item-box" @click="showTab = 'browser'"> <div id="module-type-2" v-has="'snmp_browser_view'" class="nz-tab-item-box" @click="showTab = 'browser'">
<div class="nz-tab-item">{{$t("config.mib.mibBrowser")}}</div> <div class="nz-tab-item">{{$t("config.mib.mibBrowser")}}</div>
</div> </div>
</template> </template>-->
<template v-slot:top-tool-right> <template v-slot:top-tool-right>
<button id="mib-add" v-has="'snmp_file_toAdd'" :title="$t('overall.createMib')" class="top-tool-btn margin-l-20" type="button" @click="add"> <button id="mib-add" v-has="'snmp_mibFile_add'" :title="$t('overall.createMib')" class="top-tool-btn margin-r-10" type="button" @click="add">
<i class="nz-icon-create-square nz-icon"></i> <i class="nz-icon-create-square nz-icon"></i>
</button> </button>
<delete-button id="mib-list-batch-delete" v-has="'snmp_file_delete'" :delete-objs="batchDeleteObjs" api="mib" @after="getTableData" @before="delFlag=true"></delete-button> <delete-button id="mib-list-batch-delete" v-has="'snmp_mibFile_delete'" :api="url" :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true"></delete-button>
</template> </template>
<template v-slot:default="slotProps"> <template v-slot:default="slotProps">
<el-table <mib-table
id="role-list-table"
ref="dataTable" ref="dataTable"
v-loading="tools.loading" v-loading="slotProps.loading"
:data="tableData" :api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight" :height="mainTableHeight"
border :table-data="tableData"
@header-dragend="dragend" @del="del"
@sort-change="tableDataSort" @edit="edit"
@selection-change="(selection)=>{batchDeleteObjs=selection}" @orderBy="tableDataSort"
> @reload="getTableData"
<el-table-column @selectionChange="selectionChange"
:resizable="false" @showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"
align="center" ></mib-table>
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</span>
</template>
<template slot-scope="scope" :column="item">
<template v-if="item.prop == 'updateUser'" >{{scope.row[item.prop].name}}</template>
<template v-else-if="item.prop == 'fileName' && scope.row[item.prop]" >
<span class="link" @click="downloadMib(scope.row)">{{scope.row[item.prop]}}</span>
</template>
<template v-else-if="item.prop === 'modelsDetail' && scope.row['modelsDetail'] && scope.row['modelsDetail'].length >0" >
<div style="height: 100%">
<div style="height: 100%; overflow: auto;">
<div v-for="(n,i) in scope.row['modelsDetail']" :key="n.name+'-'+n.id+'-'+i" class="detail-item-content">
<el-popover placement="top" trigger="hover" >
<div>
<div>
<span>{{$t('overall.name')}}:</span>
<span>{{n.name}}</span>
</div>
<div>
<span>{{$t('config.mib.vendor')}}:</span>
<span>{{n.vendor}}</span>
</div>
<div>
<span>{{$t('config.mib.type')}}:</span>
<span>{{n.type}}</span>
</div>
</div>
<template slot="reference">
<div v-if="i < scope.row['modelsDetail'].length-1" class="detail-item-content">{{n.name}},</div>
<div v-else class="detail-item-content">{{n.name}}</div>
</template>
</el-popover>
</div>
</div>
</div>
</template>
<span v-else-if="item.prop === 'updateAt'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<template v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</template>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-has="'snmp_file_download'" :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
<el-dropdown-item :command="['download', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-download1"></i><span class="operation-dropdown-text">{{$t('overall.download')}}</span></el-dropdown-item>
<el-dropdown-item :command="['delete', scope.row, `mib?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
<!-- 回到table顶部的按钮 -->
<button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
</template> </template>
<!-- 分页组件 --> <!-- 分页组件 -->
<template v-slot:pagination> <template v-slot:pagination>
@@ -132,12 +50,12 @@
</div> </div>
</template> </template>
<script> <script>
import axios from 'axios'
import mibBrowser from './mibBrowser' import mibBrowser from './mibBrowser'
import mibBox from '@/components/common/rightBox/mibBox' import mibBox from '@/components/common/rightBox/mibBox'
import deleteButton from '@/components/common/deleteButton' import deleteButton from '@/components/common/deleteButton'
import nzDataList from '@/components/common/table/nzDataList' import nzDataList from '@/components/common/table/nzDataList'
import tableMixin from '@/components/common/mixin/table' import dataListMixin from '@/components/common/mixin/dataList'
import mibTable from '@/components/common/table/settings/mibTable'
export default { export default {
name: 'mib', name: 'mib',
@@ -145,14 +63,15 @@ export default {
mibBox, mibBox,
mibBrowser, mibBrowser,
deleteButton, deleteButton,
nzDataList nzDataList,
mibTable
}, },
mixins: [tableMixin], mixins: [dataListMixin],
data () { data () {
return { return {
url: 'mib',
showTab: 'file', // file/browser showTab: 'file', // file/browser
tableId: 'mibTable', // 需要分页的table的id用于记录每页数量 tableId: 'mibTable', // 需要分页的table的id用于记录每页数量
object: {},
blankObject: { blankObject: {
id: null, id: null,
name: '', name: '',
@@ -160,38 +79,6 @@ export default {
models: '', models: '',
file: null file: null
}, },
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('overall.name'),
prop: 'name',
show: true
}, {
label: this.$t('config.mib.fileName'),
prop: 'fileName',
show: true
}, {
label: this.$t('config.mib.models'),
prop: 'modelsDetail',
show: true
}, {
label: this.$t('config.mib.remark'),
prop: 'remark',
show: true
}, {
label: this.$t('config.mib.updateUser'),
prop: 'updateUser',
show: true
}, {
label: this.$t('config.mib.updateAt'),
prop: 'updateAt',
show: true
}
],
searchMsg: { // 给搜索框子组件传递的信息 searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true, zheze_none: true,
searchLabelList: [{ searchLabelList: [{
@@ -209,72 +96,6 @@ export default {
}] }]
} }
} }
},
methods: {
getTableData () {
if (!this.hasButton('snmp_file_view')) {
this.$message.error(this.$t('tip.noAccess'))
return
}
this.tableData = []
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
this.$get('mib', this.searchLabel).then(response => {
this.tools.loading = false
if (response.code === 200) {
this.tableData = response.data.list
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
downloadMib (mib) {
if (!this.hasButton('snmp_file_download')) {
return
}
axios.get('/mib/download?id=' + mib.id, { responseType: 'blob' }).then(data => {
let fileName = new Date().getTime() + '.txt'
const disposition = data.headers['content-disposition']
if (disposition) {
fileName = disposition.split(';')[1].split('filename=')[1]
}
// 由于ie不支持download属性故需要做兼容判断
if (navigator.appVersion.toString().indexOf('.NET') > 0) {
// ie独有的msSaveBlob属性data.data为Blob文件流
window.navigator.msSaveBlob(data.data, fileName)
} else {
// 以下流程即为文章开始的下载流程
const url = window.URL.createObjectURL(data.data)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.download = fileName
document.body.appendChild(link)
link.click()
window.URL.revokeObjectURL(link.href)
}
})
}
} }
} }
</script> </script>
<style >
.mib-table .el-divider--horizontal{
margin:2px 0 !important;
}
.mib-table td .cell .detail-item-content{
height: 20px;
line-height: 20px;
display: inline-block;
}
.mib-table.el-table td .cell{
height: 20px !important;
}
</style>

View File

@@ -1,61 +1,26 @@
<template> <template>
<div style="height: 100%"> <div>
<nz-data-list <nz-data-list
ref="dataList" ref="dataList"
:components="['searchInput', 'elementSet']" :api="url"
:layout="['searchInput', 'elementSet']"
:custom-table-title.sync="tools.customTableTitle" :custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.operationLog" :from="fromRoute.operationLog"
:search-msg="searchMsg" :search-msg="searchMsg">
:table-id="tableId"
:table-title="tableTitle">
<template v-slot:default="slotProps"> <template v-slot:default="slotProps">
<el-table <operation-log-table
id="role-list-table"
ref="dataTable" ref="dataTable"
v-loading="tools.loading" v-loading="slotProps.loading"
:data="tableData" :api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight" :height="mainTableHeight"
border :table-data="tableData"
@header-dragend="dragend" @del="del"
@sort-change="tableDataSort" @edit="edit"
@selection-change="(selection)=>{batchDeleteObjs=selection}" @orderBy="tableDataSort"
> @reload="getTableData"
<el-table-column @selectionChange="selectionChange"
:resizable="false" @showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"></operation-log-table>
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</span>
</template>
<template slot-scope="scope" :column="item">
<span v-if="item.prop === 'time'">
{{scope.row[item.prop]}} ms
</span>
<span v-else-if="item.prop === 'username'">{{formatUsername(scope.row)}}</span>
<span v-else-if="item.prop === 'createDate'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<span v-else>{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
</el-table>
<!-- 回到table顶部的按钮 -->
<button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
</template> </template>
<!-- 分页组件 --> <!-- 分页组件 -->
<template v-slot:pagination> <template v-slot:pagination>
@@ -66,79 +31,20 @@
</template> </template>
<script> <script>
import nzDataList from '@/components/common/table/nzDataList' import nzDataList from '@/components/common/table/nzDataList'
import tableMixin from '@/components/common/mixin/table' import dataListMixin from '@/components/common/mixin/dataList'
import operationLogTable from '@/components/common/table/settings/operationLogTable'
export default { export default {
name: 'oparetionlog', name: 'oparetionLog',
components: { components: {
nzDataList nzDataList,
operationLogTable
}, },
mixins: [tableMixin], mixins: [dataListMixin],
data () { data () {
return { return {
url: 'sys/log/list',
tableId: 'operationLogTable', // 需要分页的table的id用于记录每页数量 tableId: 'operationLogTable', // 需要分页的table的id用于记录每页数量
tableTitle: [
{
label: this.$t('config.operationlog.id'),
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.operationlog.username'),
prop: 'username',
show: true
},
{
label: this.$t('config.operationlog.ip'),
prop: 'ip',
show: true
},
{
label: this.$t('config.operationlog.operation'),
prop: 'operation',
show: true
},
{
label: this.$t('config.operationlog.type'),
prop: 'type',
show: true
},
{
label: this.$t('config.operationlog.state'),
prop: 'state',
show: true
},
// {
// label: this.$t('config.operationlog.userId'),
// prop: 'userId',
// show: false,
// },
{
label: this.$t('config.operationlog.operaId'),
prop: 'operaId',
show: false
},
{
label: this.$t('config.operationlog.createDate'),
prop: 'createDate',
show: true
},
{
label: this.$t('config.operationlog.time'),
prop: 'time',
show: false
},
{
label: this.$t('config.operationlog.params'),
prop: 'params',
show: false
},
{
label: this.$t('config.operationlog.response'),
prop: 'response',
show: false
}
],
searchMsg: { // 给搜索框子组件传递的信息 searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true, zheze_none: true,
searchLabelList: [ searchLabelList: [
@@ -164,45 +70,6 @@ export default {
] ]
} }
} }
},
methods: {
messageStyle (e) {
if (e.column.label === this.$t('config.operationlog.state')) {
if (e.row.state === 'success') {
return 'success'
} else {
return 'danger'
}
}
return ''
},
getTableData () {
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
this.$get('sys/log/list', this.searchLabel).then(response => {
this.tools.loading = false
if (response.code === 200) {
this.tableData = response.data.list
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
formatUsername (row) {
if (row.username) {
return row.username
} else if (row.operation === 'login' && !row.username) { // 如果是登录 且登录失败
return JSON.parse(row.params).username
} else {
return '-'
}
}
} }
} }
</script> </script>

View File

@@ -1,483 +0,0 @@
<template>
<div style="height: 100%">
<nz-data-list
ref="dataList"
:components="['searchInput', 'elementSet']"
:custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.promServer"
:search-msg="searchMsg"
:table-id="tableId"
:table-title="tableTitle">
<template v-slot:top-tool-right>
<button id="prom-add" v-has="'prom_toAdd'" :title="$t('overall.createPrometheusServer')" class="top-tool-btn margin-l-20"
type="button" @click="add">
<i class="nz-icon-create-square nz-icon"></i>
</button>
<button :title="$t('overall.createDatacenter')" @click="toDownloadAgent" type="button" id="load-agent" class="top-tool-btn margin-l-20">
<i class="nz-icon-download nz-icon"></i>
</button>
<delete-button id="promserver-list-batch-delete" v-has="'prom_delete'" :delete-objs="batchDeleteObjs" api="agent" @after="getTableData" @before="delFlag=true"></delete-button>
</template>
<template v-slot:default="slotProps">
<el-table ref="dataTable"
v-loading="tools.loading"
:data="tableData"
:height="mainTableHeight"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="(selection)=>{batchDeleteObjs=selection}"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="55">
</el-table-column>
<el-table-column v-for="(item, index) in tools.customTableTitle" v-if="item.show"
:key="`col-${index}`"
:label="item.label"
:prop="propTitle(item.prop, fromRoute.promServer)"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:sortable="sortableShow(item.prop, fromRoute.promServer)">
<template slot="header">
<span>
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</span>
</template>
<template slot-scope="scope" :column="item">
<span v-if="item.prop === 'idc'" >{{scope.row[item.prop]?scope.row[item.prop].name:'-'}}</span>
<span v-else-if="item.prop === 'type'">
{{findServerType(scope.row[item.prop]).text}}
</span>
<span v-else-if="item.prop === 'checkTime'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<span v-else-if="item.prop === 'status'">
<el-popover :content="$t('asset.assetStatPre')+(scope.row.checkTime?utcTimeToTimezoneStr(scope.row.checkTime):$t('asset.assetStatDown'))" placement="right" trigger="hover" width="200">
<div slot="reference" style="width: 20px">
<div :class="{'active-icon green':scope.row[item.prop] == '1','active-icon red':scope.row[item.prop] == '0' || scope.row[item.prop] == '-1' || scope.row[item.prop] == '-2'}"></div>
</div>
</el-popover>
</span>
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</span>
<template v-else>-</template>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
<el-dropdown-item :command="['delete', scope.row, `agent?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
<!-- 回到table顶部的按钮 -->
<button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="account-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
</template>
<!-- 分页组件 -->
<template v-slot:pagination>
<Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
</template>
</nz-data-list>
<transition name="right-box">
<prom-server-box v-if="rightBox.show" :prom-server="object" @close="closeRightBox"></prom-server-box>
</transition>
<el-dialog :visible.sync="showAgentDownload" width="620px" append-to-body class="nz-dialog agent-dialog" @close="closeDialog" :title="$t('config.promServer.agent.title')">
<div class="agent-box" v-if="showAgentDownload">
<el-form size="small" v-model="agentParam" class="right-box-form right-box-form-left" label-position = "top" label-width="120px" style="width: 100%">
<div class="right-box-sub-title">{{$t('config.promServer.agent.download')}}</div>
<div style="margin-bottom: 20px;width: 100%"></div>
<el-form-item :label="$t('config.promServer.agent.osType')" prop="osType" class="half-form-item">
<el-select class="right-box-row-with-btn" placeholder="" v-model="agentParam.osType">
<el-option :key="item.name" :label="item.label" :value="item.name" v-for="item in osTypes">
<span class="panel-dropdown-label-txt" >{{item.label}}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item class="half-form-item">
<button type="button" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" @click="downloadAgent">{{$t('config.promServer.agent.download')}}</button>
</el-form-item>
<div class="right-box-sub-title">{{$t('config.promServer.agent.autoScript')}}</div>
<div style="margin-bottom: 20px;width: 100%"></div>
<el-form-item :label="$t('config.dc.dc')" prop="dc" class="half-form-item">
<el-select class="right-box-row-with-btn" placeholder="" v-model="agentParam.dc">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in allDc">
<span class="panel-dropdown-label-txt" >{{item.name}}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('config.promServer.agent.type')" prop="type" class="half-form-item">
<el-select class="right-box-row-with-btn" placeholder="" v-model="agentParam.type">
<el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in $CONSTANTS.promServer2.theData">
<span class="panel-dropdown-label-txt" >{{item.label}}</span>
</el-option>
</el-select>
</el-form-item>
</el-form>
<div class="download-url" v-if="loadFinish">
<el-input id="download-url-curl" :disabled="true" v-model="curlUrl">
<el-popover :content="$t('tip.copySuccess')" placement="top" trigger="manual" v-model="curlVisible" popper-class="small-pop" slot="suffix" @after-enter="popShow('curl')">
<i slot="reference" class="nz-icon nz-icon-override" @click="copyUrl('download-url-curl')"></i>
</el-popover>
</el-input>
</div>
<div class="download-url" v-if="loadFinish">
<el-input id="download-url-wget" :disabled="true" v-model="wgetUrl">
<el-popover :content="$t('tip.copySuccess')" placement="top" trigger="manual" v-model="wgetVisible" popper-class="small-pop" slot="suffix" @after-enter="popShow('wget')">
<i slot="reference" class="nz-icon nz-icon-override" @click="copyUrl('download-url-wget')"></i>
</el-popover>
</el-input>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import deleteButton from '@/components/common/deleteButton'
import promServerBox from '@/components/common/rightBox/promServerBox'
import { promServer } from '@/components/common/js/constants'
import nzDataList from '@/components/common/table/nzDataList'
import tableMixin from '@/components/common/mixin/table'
import axios from 'axios'
import Vue from 'vue'
export default {
name: 'promServer',
components: {
nzDataList,
promServerBox,
deleteButton
},
mixins: [tableMixin],
computed:{
wgetUrl:function(){
return 'wget -qO- --header="Authorization:'+this.token+'" '+ this.ipAddr+'/agent/'+this.agentParam.dc+'/'+this.agentParam.type+'/install.sh | bash'
},
curlUrl:function(){
return 'curl -o- -H "Authorization:'+this.token+'" '+ this.ipAddr+'/agent/'+this.agentParam.dc+'/'+this.agentParam.type+'/install.sh | bash'
}
},
data () {
return {
tableId: 'promTable', // 需要分页的table的id用于记录每页数量
blankObject: {
id: '',
host: '',
port: 9090,
idc: { id: '', name: '', location: '' }
},
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.dc.dc'),
prop: 'idc',
show: true
}, {
label: 'Host',
prop: 'host',
show: true
}, {
label: 'Port',
prop: 'port',
show: true
}, {
label: this.$t('config.promServer.type'),
prop: 'type',
show: true
}, {
label: this.$t('asset.state'),
prop: 'status',
show: true
}, {
label: this.$t('config.promServer.checkTime'),
prop: 'checkTime',
show: false
}
],
tableData: [],
dcData: [],
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
id: 1,
name: 'ID',
type: 'input',
label: 'id',
disabled: false
}, {
id: 5,
name: this.$t('config.promServer.dataCenter'),
type: 'dc',
label: 'dc',
disabled: false
}, {
id: 6,
name: this.$t('config.promServer.type'),
type: 'select',
label: 'promType',
disabled: false
}, {
id: 8,
name: this.$t('project.endpoint.host'),
type: 'input',
label: 'host',
disabled: false
}, {
id: 9,
name: this.$t('project.endpoint.port'),
type: 'input',
label: 'port',
disabled: false
}]
},
promServerType: null,
showAgentDownload: false,
token: '',
ipAddr: '',
allDc: [],
loadFinish: false,
osTypes: [{
label: 'Centos',
name: 'centos'
},
{
label: 'Ubuntu',
name: 'ubuntu'
}],
agentParam: {
osType: 'centos',
dc: '',
type: 1
},
wgetVisible:false,
curlVisible:false,
}
},
methods: {
toDownloadAgent: function () {
this.showAgentDownload = true
this.token = sessionStorage.getItem('nz-token')
axios.get('/healthy').then(response=>{
let url = response.request.responseURL
this.ipAddr = url.split('/healthy')[0];
})
},
closeDialog: function () {
this.showAgentDownload = false
},
getAllDc: function () {
this.$get('idc?pageSize=-1').then(response => {
this.tools.loading = false
if (response.code === 200) {
this.allDc = response.data.list
this.loadFinish = true
this.agentParam.dc = this.allDc[0].id
}
})
},
copyUrl: function (id) {
const input = document.createElement('input')
const text = document.getElementById(id).value;
document.body.appendChild(input)
input.setAttribute('value', text)
input.select()
if (document.execCommand('copy')) {
document.execCommand('copy')
}
document.body.removeChild(input)
if(id.indexOf('curl') != -1){
this.curlVisible = true
console.log("open curl")
// let timeout = setTimeout(()=>{
// this.curlVisible = false;
// clearTimeout(timeout)
// },1000)
}else{
this.wgetVisible = true
// let timeout = setTimeout(()=>{
// this.wgetVisible = false;
// clearTimeout(timeout)
// },1000)
}
},
popShow:function(where){
const self = this
if(where == 'curl'){
let timeout = setTimeout(()=>{
self.curlVisible = false;
clearTimeout(timeout)
},1000)
}else{
let timeout = setTimeout(()=>{
self.wgetVisible = false;
clearTimeout(timeout)
},1000)
}
},
downloadAgent: function () {
axios.get('agent/download?os=' + this.agentParam.osType, { responseType: 'blob' }).then(data => {
let fileName = 'confagent'
const disposition = data.headers['content-disposition']
if (disposition) {
fileName = disposition.split(';')[1].split('filename=')[1]
}
// 由于ie不支持download属性故需要做兼容判断
if (navigator.appVersion.toString().indexOf('.NET') > 0) {
// ie独有的msSaveBlob属性data.data为Blob文件流
window.navigator.msSaveBlob(data.data, fileName)
} else {
// 以下流程即为文章开始的下载流程
const url = window.URL.createObjectURL(data.data)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.download = fileName
document.body.appendChild(link)
link.click()
window.URL.revokeObjectURL(link.href)
}
})
},
propShow:function(){
},
getTableData () {
if (!this.hasButton('prom_view')) {
this.$message.error(this.$t('tip.noAccess'))
return
}
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.loading = true
this.$get('agent', this.searchLabel).then(response => {
this.loading = false
if (response.code === 200) {
for (let i = 0; i < response.data.list.length; i++) {
for (let j = 0; j < this.dcData.length; j++) {
if (response.data.list[i].idcId == this.dcData[j].id) {
response.data.list[i].idc = this.dcData[j]
break
}
}
}
this.tableData = response.data.list
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
// 获取dc数据
getDcData () {
return new Promise(resolve => {
this.$get('idc', { pageSize: -1 }).then(response => {
if (response.code === 200) {
this.dcData = response.data.list
}
resolve()
})
})
},
findServerType (type) {
if (!this.promServerType) {
this.promServerType = []
promServer.theData.forEach(item => {
this.promServerType = this.promServerType.concat(item.children)
})
}
return this.promServerType.find(item => {
return item.value == type
})
}
},
mounted () {
// 初始化数据
Promise.all([this.getDcData()]).then(response => {
this.getTableData()
})
this.getAllDc()
}
}
</script>
<style scoped>
.agent-dialog .agent-box{
padding:10px;
}
.agent-box >.right-box-form>.el-form-item.half-form-item{
width: 220px;
}
.agent-box >.right-box-form>.el-form-item.half-form-item:nth-child(odd){
width: 220px;
}
.agent-box .download-url{
height: 40px;
position: relative;
margin-bottom: 10px;
}
.agent-box .download-url .url-copy{
position: absolute;
right: 10px;
top: 5px;
}
.agent-box .download-url .url-copy i{
font-size: 20px;
}
.agent-box .download-url pre code {
border: 1px solid #ddd;
border-radius: 0;
font-family: "Courier New", Monaco, Menlo, Consolas, monospace;
line-height: 40px;
padding: 5px 20px 5px 5px;
white-space: nowrap;
background-color: #F6F8FA;;
color: #333;
}
.agent-box .download-url code {
color: #333;
}
</style>
<style>
.download-url > .el-input.is-disabled .el-input__inner{
background-color: #F6F8FA;;
border-color: #E4E7ED;
color: #333;
cursor: text;
}
.download-url .el-input__suffix {
position: absolute;
top: 8px;
-webkit-transition: all .3s;
height: 100%;
color: #333;
text-align: center;
}
</style>

View File

@@ -8,11 +8,11 @@
:from="fromRoute.role" :from="fromRoute.role"
:search-msg="searchMsg"> :search-msg="searchMsg">
<template v-slot:top-tool-right> <template v-slot:top-tool-right>
<button id="roles-add" v-has="'role_toAdd'" :title="$t('overall.createRole')" class="top-tool-btn margin-l-20" <button id="roles-add" v-has="'role_add'" :title="$t('overall.createRole')" class="top-tool-btn margin-r-10"
type="button" @click="add"> type="button" @click="add">
<i class="nz-icon-create-square nz-icon"></i> <i class="nz-icon-create-square nz-icon"></i>
</button> </button>
<delete-button id="role-list-batch-delete" v-has="'role_delete'" :delete-objs="batchDeleteObjs" api="sys/role" @after="getTableData" @before="delFlag=true"></delete-button> <delete-button id="role-list-batch-delete" v-has="'role_delete'" :api="url" :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true"></delete-button>
</template> </template>
<template v-slot:default="slotProps"> <template v-slot:default="slotProps">
<role-table <role-table

View File

@@ -1,109 +1,27 @@
<template> <template>
<div style="height: 100%"> <div>
<nz-data-list <nz-data-list
ref="dataList" ref="dataList"
:components="['searchInput', 'elementSet']" :api="url"
:layout="['searchInput', 'elementSet']"
:custom-table-title.sync="tools.customTableTitle" :custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.terminalLog" :from="fromRoute.terminalLog"
:search-msg="searchMsg" :search-msg="searchMsg">
:table-id="tableId"
:table-title="tableTitle">
<template v-slot:default="slotProps"> <template v-slot:default="slotProps">
<el-table <terminal-log-table
id="terminal-log-list-table"
ref="dataTable" ref="dataTable"
v-loading="tools.loading" v-loading="slotProps.loading"
:data="tableData" :api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight" :height="mainTableHeight"
border :now-time="nowTime"
@header-dragend="dragend" :table-data="tableData"
@sort-change="tableDataSort" @del="del"
@selection-change="(selection)=>{batchDeleteObjs=selection}" @edit="edit"
> @orderBy="tableDataSort"
<el-table-column @reload="getTableData"
:resizable="false" @selectionChange="selectionChange"
align="center" @showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"></terminal-log-table>
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</span>
</template>
<template slot-scope="scope" :column="item">
<span v-if="item.prop === 'time'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<template v-else-if="item.prop === 'status'">
<span>{{getStatusText(scope.row.status)}}</span>
</template>
<template v-else-if="item.prop === 'uuid'">
<span>{{scope.row.uuid.substring(0, 8).toUpperCase()}}</span>
</template>
<template v-else-if="item.prop === 'remote'">
<span>{{getRemoteText(scope.row)}}</span>
</template>
<template v-else-if="item.prop === 'duration'">
<el-tooltip :disabled="!scope.row.status" effect="light" placement="right">
<div slot="content">
{{$t('config.terminallog.endTime')}}<br/>
{{scope.row.endTime}}
</div>
<span>{{getDuration(scope.row)}}</span>
</el-tooltip>
</template>
<template v-else-if="item.prop === 'authType'">
<span v-if="scope.row.authType == 1">{{$t('config.terminallog.password')}}</span>
<span v-else-if="scope.row.authType == 2">{{$t('config.terminallog.key')}}</span>
</template>
<span v-else>{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
<el-table-column
:resizable="false"
:width="operationWidth"
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
<template v-if="scope.row.status == 0">
<button :title="$t('config.terminallog.monitor.monitor')" class="table-operation-item" @click="$refs.dataList.showBottomBox('monitor', scope.row)"><i class="nz-icon nz-icon-JC"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['shutdown', scope.row]"><i class="nz-icon nz-icon-ZD"></i><span class="operation-dropdown-text">Kill</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<template v-else>
<button class="table-operation-item" @click="$refs.dataList.showBottomBox('cmd', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="['record', scope.row]"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('config.terminallog.record.record')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</div>
</el-table-column>
</el-table>
<!-- 回到table顶部的按钮 -->
<button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
</template> </template>
<!-- 分页组件 --> <!-- 分页组件 -->
<template v-slot:pagination> <template v-slot:pagination>
@@ -113,73 +31,21 @@
</div> </div>
</template> </template>
<script> <script>
import { terminalLog } from '@/components/common/js/constants'
import { calcDurationByStringTimeB } from '@/components/common/js/tools'
import nzDataList from '@/components/common/table/nzDataList' import nzDataList from '@/components/common/table/nzDataList'
import tableMixin from '@/components/common/mixin/table' import dataListMixin from '@/components/common/mixin/dataList'
import terminalLogTable from '@/components/common/table/settings/terminalLogTable'
export default { export default {
name: 'terminalLog', name: 'terminalLog',
components: { components: {
nzDataList nzDataList,
terminalLogTable
}, },
mixins: [tableMixin], mixins: [dataListMixin],
data () { data () {
return { return {
url: 'terminal/session',
tableId: 'terminalLogTable', // 需要分页的table的id用于记录每页数量 tableId: 'terminalLogTable', // 需要分页的table的id用于记录每页数量
tableTitle: [
{
label: this.$t('config.terminallog.id'),
prop: 'id',
show: true,
width: 80
}, {
label: 'Session ID',
prop: 'uuid',
show: true
}, {
label: 'Username',
prop: 'username',
show: true
},
{
label: this.$t('config.terminallog.source'),
prop: 'remoteAddr',
show: true
},
{
label: this.$t('config.terminallog.remote'),
prop: 'remote',
show: true
},
{
label: this.$t('config.terminallog.protocol'),
prop: 'protocol',
show: true
},
{
label: this.$t('config.terminallog.startTime'),
prop: 'startTime',
show: true
},
{
label: this.$t('config.terminallog.duration'),
prop: 'duration',
show: true
},
{
label: 'AuthType',
prop: 'authType',
show: false
},
{
label: this.$t('config.terminallog.status'), // killusername鼠标悬停形式
prop: 'status',
show: true,
width: 100
}
],
searchMsg: { // 给搜索框子组件传递的信息 searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true, zheze_none: true,
searchLabelList: [ searchLabelList: [
@@ -201,45 +67,14 @@ export default {
nowTime: '' nowTime: ''
} }
}, },
computed: {
getStatusText () {
return function (status) {
return terminalLog.status[status]
}
},
getRemoteText () {
return function (record) {
return `${record.loginUser}@${record.host}:${record.port}`
}
},
getDuration () {
return function (record) {
if (record.endTime) {
return calcDurationByStringTimeB(record.startTime, record.endTime)
}
return calcDurationByStringTimeB(record.startTime, this.nowTime)
}
}
},
methods: { methods: {
tableOperation ([command, row]) {
switch (command) {
case 'shutdown': {
this.shutdown(row)
break
}
default:
this.$refs.dataList.showBottomBox(command, row)
break
}
},
getTableData () { getTableData () {
const params = { const params = {
...this.searchLabel, ...this.searchLabel,
pageNo: this.pageObj.pageNo, pageNo: this.pageObj.pageNo,
pageSize: this.pageObj.pageSize pageSize: this.pageObj.pageSize
} }
this.$get('terminal/session', params).then(response => { this.$get(this.url, params).then(response => {
this.tools.loading = false this.tools.loading = false
if (response.code === 200) { if (response.code === 200) {
this.tableData = response.data.list this.tableData = response.data.list
@@ -247,7 +82,7 @@ export default {
this.pageObj.total = response.data.total this.pageObj.total = response.data.total
if (!this.scrollbarWrap) { if (!this.scrollbarWrap) {
this.$nextTick(() => { this.$nextTick(() => {
this.scrollbarWrap = this.$refs.dataTable.bodyWrapper this.scrollbarWrap = this.$refs.dataTable.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap) this.toTopBtnHandler(this.scrollbarWrap)
}) })
} }
@@ -270,22 +105,6 @@ export default {
} }
}) })
}) })
},
messageStyle (e) {
if (e.column.label == this.$t('config.terminallog.status')) {
if (e.row.status == '0') {
return 'success'
} else if (e.row.status == '1') {
return 'warning'
} else if (e.row.status == '2') {
return 'suspended'
} else if (e.row.status == '3') {
return 'danger'
} else if (e.row.status == '4') {
return 'danger'
}
}
return ''
} }
} }
} }

View File

@@ -8,11 +8,11 @@
:layout="['searchInput', 'elementSet']" :layout="['searchInput', 'elementSet']"
:search-msg="searchMsg"> :search-msg="searchMsg">
<template v-slot:top-tool-right> <template v-slot:top-tool-right>
<button id="account-add" v-has="'account_toAdd'" :title="$t('overall.createUser')" class="top-tool-btn margin-l-20" <button id="account-add" v-has="'user_add'" :title="$t('overall.createUser')" class="top-tool-btn margin-r-10"
type="button" @click="add"> type="button" @click="add">
<i class="nz-icon-create-square nz-icon"></i> <i class="nz-icon-create-square nz-icon"></i>
</button> </button>
<delete-button id="account-list-batch-delete" v-has="'account_delete'" :api="url" :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true"></delete-button> <delete-button id="account-list-batch-delete" v-has="'user_delete'" :api="url" :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true"></delete-button>
</template> </template>
<template v-slot="slotProps"> <template v-slot="slotProps">
<user-table <user-table
@@ -71,7 +71,6 @@ export default {
notifications: [] notifications: []
}, },
tableId: 'userTable', tableId: 'userTable',
queryPermission: 'account_view',
searchMsg: { // 给搜索框子组件传递的信息 searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true, zheze_none: true,
searchLabelList: [{ searchLabelList: [{

View File

@@ -59,7 +59,7 @@ export default new Router({
}, },
{ {
path: '/agent', path: '/agent',
component: resolve => require(['../components/page/config/promServer.vue'], resolve) component: resolve => require(['../components/page/config/agent.vue'], resolve)
}, },
{ {
path: '/assetType', path: '/assetType',
@@ -102,16 +102,16 @@ export default new Router({
component: resolve => require(['../components/page/config/system.vue'], resolve) component: resolve => require(['../components/page/config/system.vue'], resolve)
}, },
{ {
path: '/alertList', path: '/alertMessage',
component: resolve => require(['../components/page/alert/list.vue'], resolve) component: resolve => require(['../components/page/alert/alertMessage.vue'], resolve)
}, },
{ {
path: '/alertConfig', path: '/alertRule',
component: resolve => require(['../components/page/alert/config.vue'], resolve) component: resolve => require(['../components/page/alert/alertRule.vue'], resolve)
}, },
{ {
path: '/alertSilence', path: '/alertSilence',
component: resolve => require(['../components/page/alert/silence.vue'], resolve) component: resolve => require(['../components/page/alert/alertSilence.vue'], resolve)
}, },
{ {
path: '/exprtemp', path: '/exprtemp',