Merge branch 'dev-3.3' of git.mesalab.cn:nezha/nezha-fronted into dev-3.3

This commit is contained in:
zyh
2022-06-01 15:26:22 +08:00
23 changed files with 323 additions and 69 deletions

View File

@@ -416,3 +416,9 @@ td .nz-icon-gear:before{
input, textarea {
font-family: Inter-Regular !important;
}
.message-next{
vertical-align: bottom;
float: unset;
font-size: 10px;
margin-left: 190px;
}

View File

@@ -119,7 +119,7 @@
}
}
.is-jump{
position: absolute;
position: absolute !important;
right: 5px;
top: 20px;
padding: 0;
@@ -217,3 +217,7 @@
.fz12{
font-size: 12px;
}
.el-skeleton__item{
background-color: $--explore-border-color-bottom !important;
background-image: unset !important;
}

View File

@@ -120,6 +120,28 @@
top: 40px;
left: 0px;
}
.el-checkbox-group{
display: flex;
justify-content: start;
align-items: center;
flex-wrap: wrap;
.el-checkbox-button{
display: flex;
justify-content: center;
align-items: center;
width: 90px;
height: 34px;
border: 1px solid $--border-color-light;
margin-right: -1px;
.el-checkbox-button__inner{
border: 0px;
display: block;
width: 100%;
height: 100%;
}
}
}
}
}
#DayOfMonth{
@@ -142,9 +164,13 @@
display: flex;
justify-content: center;
align-items: center;
width: 91px;
height: 36px;
width: 90px;
height: 35px;
border: 1px solid $--border-color-light;
margin-right: -1px;
margin-bottom: -1px;
.el-checkbox-button__inner{
border: 0px;
display: block;
width: 100%;
height: 100%;
@@ -164,4 +190,19 @@
.el-table--border th:first-child .cell {
padding-left: 20px !important;
}
.el-checkbox-button__inner{
background-color:$--background-color-empty;
}
.el-checkbox-button.is-checked .el-checkbox-button__inner {
color: #fff;
background-color: #FA901C;
border-color: #FA901C;
border: 1px solid #FA901C;
margin-right: -1px;
-webkit-box-shadow: -1px 0 0 0 #fcbc77;
box-shadow: -1px 0 0 0 #fcbc77;
}
.nz-icon-delete:before{
color: $--color-text-regular;
}
}

View File

@@ -225,7 +225,7 @@
}
.list-page.profile-right {
width: calc(100% - 370px);
padding: 0px 0px 7px 0px;
padding: 0;
pxbox-shadow: 0 1px 2px 0 rgba(0,0,0,0.06);
border-radius: 2px;
.nz-table2 {

View File

@@ -251,6 +251,7 @@
}
.right-content-box{
width: 380px;
color: $--color-text-primary;
}
.tools-header-right-content{
margin-left: 30px;
@@ -410,3 +411,11 @@
}
}
td.el-table__expanded-cell {
padding: 0 0 0 60px;
background-color: $--popover-background-color !important;
}
td.el-table__expanded-cell:hover {
padding: 0 0 0 60px;
background-color: $--background-color-base !important;
}

View File

@@ -253,7 +253,7 @@ $--right-box-sub-title-border-color: $--border-color-light;
$--tooltip-background-color: #222329;
$--tooltip-border-color: rgba(112,116,122,0.6);
/* 17.label*/
$--label-background-color: #18171D;
$--label-background-color: $--background-color-empty;
/*** themes/common.scss是与主题切换无关的变量 ***/
@import './src/common/var.scss';

View File

@@ -158,11 +158,19 @@ export default {
minValue = valueSorted.length ? valueSorted[0][1] : 0
maxValue = valueSorted.length ? valueSorted[valueSorted.length - 1][1] : 0
const unit = chartDataFormat.getUnit(chartUnit)
minValue = minValue > 0 ? 0 : minValue
if (!isNaN(maxValue)) {
maxValue = Number(maxValue)
} else {
maxValue = 0
}
if (maxValue < 0) {
maxValue = Math.abs(maxValue)
}
if (Math.abs(minValue) > Math.abs(maxValue)) {
maxValue = Math.abs(minValue)
}
maxValue = maxValue - minValue
maxValue = chartDataFormat.formatDatas(maxValue, unit.type, 'ceil', unit.ascii) // 取最大值后 需要对其进行取整
let oldValue = maxValue
let dot = 0
@@ -185,6 +193,7 @@ export default {
return { minTime, maxTime, minValue, maxValue, copies, unit, dot }
},
xAxisLabelFormatter (minTime, maxTime) {
let self = this
return function (val, index) {
const value = val * 1000
let offset = localStorage.getItem('nz-sys-timezone')
@@ -192,7 +201,7 @@ export default {
offset = Number.parseInt(offset)
const localOffset = new Date().getTimezoneOffset() * 60 * 1000 * -1 // 默认 一分钟显示时区偏移的结果
if (window.dataJson) {
offset = new Date().getTimezoneOffset()* -1/60
offset = new Date().getTimezoneOffset() * -1 / 60
}
const tData = new Date(value - localOffset + offset * 60 * 60 * 1000)
let hour = tData.getHours()
@@ -203,12 +212,23 @@ export default {
const diffSec = (maxTime - minTime)
const secOneDay = 24 * 60 * 60// 1天的秒数
const secOneMonth = secOneDay * 30// 30天的秒数
const dateFormatStr = self.timeFormatMain.split(' ')[0]
let str = ''
const month = tData.getMonth() + 1
const day = tData.getDate()
if (dateFormatStr === 'DD/MM/YYYY') {
str += [day, month].join('/')
} else if (dateFormatStr === 'MM/DD/YYYY') {
str += [month, day].join('/')
} else {
str += [month, day].join('-')
}
if (diffSec <= secOneDay) { // 同一天
return [hour, minute].join(':')
} else if (diffSec < secOneMonth) { // 大于1天小于30天
return [tData.getMonth() + 1, tData.getDate()].join('/') + '\n' + [hour, minute].join(':')
return str + '\n' + [hour, minute].join(':')
} else { // 大于等于30天
return [tData.getMonth() + 1, tData.getDate()].join('/')
return str
}
} else {
return [tData.getFullYear(), tData.getMonth() + 1, tData.getDate()].join('/') + '\n' +

View File

@@ -226,9 +226,21 @@ export default {
const chartUnit = chartInfo.unit ? chartInfo.unit : 2
const unit = chartDataFormat.getUnit(chartUnit)
minValue = minValue > 0 ? 0 : minValue
if (maxValue < 0) {
maxValue = Math.abs(maxValue)
}
if (Math.abs(minValue) > Math.abs(maxValue)) {
maxValue = Math.abs(minValue)
}
maxValue = maxValue - minValue
maxValue = chartDataFormat.formatDatas(maxValue, unit.type, 'ceil', unit.ascii)
let oldValue = maxValue
if (maxValue < 0) {
oldValue = Math.abs(maxValue)
}
if (minValue < 0) {
oldValue = Math.abs(maxValue - minValue)
}
let dot = 0
if (maxValue == 1) {
dot++

View File

@@ -2071,6 +2071,17 @@ export default {
const chartUnit = chartInfo.unit ? chartInfo.unit : 2
const unit = chartDataFormat.getUnit(chartUnit)
minValue = minValue > 0 ? 0 : minValue
if (!isNaN(maxValue)) {
maxValue = Number(maxValue)
} else {
maxValue = 0
}
if (maxValue < 0) {
maxValue = Math.abs(maxValue)
}
if (Math.abs(minValue) > Math.abs(maxValue)) {
maxValue = Math.abs(minValue)
}
maxValue = maxValue - minValue
maxValue = chartDataFormat.formatDatas(maxValue, unit.type, 'ceil', unit.ascii)
let oldValue = maxValue

View File

@@ -52,7 +52,7 @@
<div class="list-item-sub" v-if="item.sub">
{{ item.sub }}
</div>
<div class="is-jump" v-my-loading:circle3.scaleMin.icon="jumpLoading">
<div class="is-jump" v-my-loading:circle3.scaleMin.icon="true">
<i class="nz-icon nz-icon-huiche"></i>
</div>
</li>

View File

@@ -156,7 +156,7 @@ export const asset = {
},
editTypeOptions: [
{ value: 1, label: i18n.t('overall.account') },
{ value: 2, label: 'Label' },
{ value: 2, label: i18n.t('overall.labels') },
{ value: 3, label: i18n.t('asset.state') },
{ value: 4, label: i18n.t('asset.snmpCredential') }
],

View File

@@ -1,7 +1,11 @@
export default {
data () {
return {
isEdit: false
isEdit: false,
messageParams: {
route: '',
params: {}
}
}
},
mounted () {
@@ -11,6 +15,31 @@ export default {
}
}
},
methods: {
messageShow (msg, route, params, showNext = false) {
this.messageParams.route = route
this.messageParams.params = params
this.$message({
duration: 2000,
dangerouslyUseHTMLString: true,
type: 'success',
message: `<div>${msg} <span id="assetAdd" class="message-next ${showNext ? '' : 'hidden'}">Next</span></div>`,
onClose: () => {
const assetAdd = document.getElementById('assetAdd')
assetAdd.removeEventListener('click', this.saveNext)
}
})
const assetAdd = document.getElementById('assetAdd')
assetAdd.addEventListener('click', this.saveNext)
},
saveNext () {
console.log(this.assetId)
this.$router.push({
path: this.messageParams.route,
query: this.messageParams.params
})
}
},
destroyed () {
window.onbeforeunload = null
}

View File

@@ -283,45 +283,51 @@ export default {
selectedData: [],
searchLabel: {},
searchMsg: { // 给搜索框子组件传递的信息
searchLabelList: [
{
id: 1,
name: 'ID',
type: 'input',
label: 'id',
disabled: false
}, {
id: 20,
name: this.$t('asset.sn'),
type: 'input',
label: 'sn',
disabled: false
}, {
id: 21,
name: this.$t('webshell.host'),
type: 'input',
label: 'manageIp',
disabled: false
}, {
id: 22,
name: this.$t('asset.state'),
type: 'select',
label: 'assetState',
disabled: false
}, {
id: 23,
name: this.$t('asset.pingStatus'),
type: 'select',
label: 'pingStatus',
disabled: false
}, {
id: 23,
name: this.$t('asset.cabinet'),
type: 'input',
label: 'cabinetName',
disabled: false
}
]
searchLabelList: [{
id: 'ids',
name: 'ID',
type: 'input',
label: 'ids',
disabled: false
}, {
name: this.$t('overall.name'),
type: 'input',
label: 'name',
id: 'name',
disabled: false
}, {
name: 'SN',
type: 'input',
label: 'sn',
id: 'sn',
disabled: false
}, {
name: this.$t('dashboard.overview.dataCenter.dataCenter'),
type: 'dc',
label: 'dcIds',
readonly: true,
disabled: false
}, {
name: 'IP',
type: 'input',
label: 'manageIp',
id: 'manageIp',
disabled: false
}, {
name: this.$t('asset.state'),
type: 'assetState',
label: 'stateIds',
id: 'stateIds',
readonly: true,
disabled: false
}, {
name: this.$t('asset.type'),
type: 'assetType',
label: 'assetType',
id: 'typeIds',
readonly: true,
disabled: false
}]
},
tableTitle: [
{

View File

@@ -433,7 +433,8 @@ export default {
})
}
}
}
},
assetId: ''
}
},
watch: {
@@ -686,6 +687,8 @@ export default {
})
},
save () {
const self = this
// console.log(123123132, self, 'params.id')
if (this.prevent_opt.save) { return }
this.prevent_opt.save = true
@@ -740,7 +743,7 @@ export default {
this.$put(this.url, params).then(res => {
this.prevent_opt.save = false
if (res.code === 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.messageShow(this.$t('tip.saveSuccess'), '/endpoint', { assetId: res.data.id }, false)
this.esc(true)
} else {
this.$message.error(res.msg)
@@ -750,7 +753,7 @@ export default {
this.$post(this.url, params).then(res => {
this.prevent_opt.save = false
if (res.code === 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.messageShow(this.$t('tip.saveSuccess'), '/endpoint', { assetId: res.data.id }, false)
this.esc(true)
} else {
this.$message.error(res.msg)
@@ -763,7 +766,6 @@ export default {
}
})
},
getStateData () {
return new Promise(resolve => {
this.$get('asset/stateConf?pageSize=-1').then(response => {

View File

@@ -1107,7 +1107,7 @@ export default {
this.editEndpoint.moduleId = ''
this.editEndpoint.name = ''
this.editEndpoint.assetName = ''
this.editEndpoint.assetId = ''
// this.editEndpoint.assetId = ''
this.$refs.sp.remove()
this.$refs.moduleForm.clearValidate('moduleId')
}
@@ -1479,7 +1479,9 @@ export default {
}
},
mounted () {
setTimeout(() => {
this.editEndpoint.assetId = this.module.assetId + ''
}, 500)
},
created () {
this.getProjectList()

View File

@@ -100,6 +100,16 @@
<li v-for="(item,key) in assetStateSelect" :key="key" :class="search_select_style_num==key?'search-style-ind':''" @click="selectObject(val, item, $event)">{{$t(item.name)}}</li>
</ul>
</div>
<div v-if="val.type === 'assetType'" :style="'top:' + selectDom.top +'; left:'+selectDom.left" class="select_info_list">
<el-scrollbar v-if="assetTypeTree.length > 8" class="el-scrollbar-small" style="height: 240px;">
<ul>
<li v-for="(item,key) in assetTypeTree" :key="key" :class="search_select_style_num==key?'search-style-ind':''" @click="selectObject(val, item, $event)">{{$t(item.name)}}</li>
</ul>
</el-scrollbar>
<ul v-else>
<li v-for="(item,key) in assetTypeTree" :key="key" :class="search_select_style_num==key?'search-style-ind':''" @click="selectObject(val, item, $event)">{{$t(item.name)}}</li>
</ul>
</div>
<div v-if="val.type === 'brand'" :style="'top:' + selectDom.top +'; left:'+selectDom.left" class="select_info_list">
<el-scrollbar v-if="brandSelect.length > 8" class="el-scrollbar-small" style="height: 240px;">
<ul>
@@ -316,7 +326,8 @@ export default {
selectInfo: false,
disabaled: true,
downBool: false,
where: this.$route.path
where: this.$route.path,
assetTypeTree: []
}
},
watch: {
@@ -509,6 +520,10 @@ export default {
val.val = selectItem.name
val.valnum = selectItem.id
val.valString = ''
} else if (val.type == 'assetType' && selectItem.searchType == 'assetType') {
val.val = selectItem.name
val.valnum = selectItem.id
val.valString = ''
} else if (val.type === 'brand' && selectItem.searchType === 'brand') {
val.val = selectItem.name
val.valnum = selectItem.id
@@ -613,6 +628,16 @@ export default {
}
})
},
getAssetTypeData () {
this.$get('asset/typeConf/tree').then(response => {
if (response.code === 200) {
this.assetTypeTree = response.data.list
this.assetTypeTree.forEach((item, index) => {
this.$set(item, 'searchType', 'assetType')
})
}
})
},
getBrandData () {
this.$get('asset/brand', { pageNo: 1, pageSize: -1 }).then(response => {
if (response.code === 200) {
@@ -869,6 +894,8 @@ export default {
objectInfo.type = val.valnum
} else if (val.label === 'assetState') {
objectInfo.state = val.valnum
} else if (val.label === 'assetType') {
objectInfo.typeIds = val.valnum
} else if (val.label === 'credentialType') {
objectInfo.types = val.valnum
} else if (val.label === 'promState') {
@@ -902,8 +929,11 @@ export default {
objectInfo.moduleId = val.valnum
} else if (val.type === 'project') {
objectInfo.projectIds = val.valnum
} else if (val.type === 'assetState') {
objectInfo.stateIds = val.valnum
} else if (val.label === 'assetState') {
console.log(val)
objectInfo.state = val.valnum
} else if (val.label === 'assetType') {
objectInfo.typeIds = val.valnum
} else if (val.type === 'brand') {
objectInfo.brandIds = val.valnum
} else if (val.type === 'group') {
@@ -1467,6 +1497,7 @@ export default {
setTimeout(() => {
if (this.$route.path === '/asset' || this.targetTab === 'asset') {
this.getAssetStateData()
this.getAssetTypeData()
}
if (this.$route.path === '/agent' || this.$route.path === '/ipam') {
this.getDcData()

View File

@@ -41,7 +41,7 @@
{{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 === 'ts'">{{scope.row[item.prop]?utcTimeToTimezoneStr(scope.row[item.prop]):'-'}}</span>
<span v-else-if="item.prop === 'ts'">{{scope.row[item.prop]?timeFormate(computeTimezoneTime(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: 60px">
@@ -87,6 +87,7 @@
</template>
<script>
import bus from '@/libs/bus'
import table from '@/components/common/mixin/table'
import { agent } from '@/components/common/js/constants'
export default {
@@ -168,6 +169,9 @@ export default {
return this.promServerType.find(item => {
return item.value == type
})
},
computeTimezoneTime (time) {
return bus.computeTimezoneTime(time)
}
}
}

View File

@@ -42,6 +42,16 @@
@click="saveChart">
{{$t('dashboard.metric.saveChart')}}
</button>
<button v-else
id="explore-save-chart-logs"
v-has="'main_add'"
:class="{'nz-btn-disabled btn-disabled-cursor-not-allowed' : saveDisabled}"
:disabled="saveDisabled"
class="top-tool-btn top-tool-btn--text"
type="button"
@click="saveChartLogs">
{{$t('dashboard.metric.saveChart')}}
</button>
</div>
</div>
<div id="explore-promql-box" class="top-tools" style="padding-top: 0; flex-wrap: wrap">
@@ -88,7 +98,7 @@
<template v-if="showMetrics">
<el-collapse-item name="1" :title="$t('explore.graph')" class="el-collapse-item__height">
<div class="chart-room">
<chart ref="exploreChart" :unit="chartUnit"></chart>
<chart ref="exploreChart" :unit="chartUnit" :timeRange="filterTime"></chart>
</div>
</el-collapse-item>
<el-collapse-item class="el-collapse-item__height" name="2" title="Table">
@@ -158,7 +168,7 @@
<template v-else>
<el-collapse-item v-if="showTab.indexOf('1') > -1" name="1" :title="$t('explore.graph')" class="el-collapse-item__height">
<div class="chart-room">
<chart ref="logChart" :unit="chartUnit" v-my-loading="chartLoading"></chart>
<chart ref="logChart" :unit="chartUnit" v-my-loading="chartLoading" :timeRange="filterTime"></chart>
</div>
</el-collapse-item>
<el-collapse-item v-if="showTab.indexOf('2') > -1" name="2" title="Logs">
@@ -981,6 +991,43 @@ export default {
this.chartData = chart
this.rightBox.show = true
},
saveChartLogs () {
const chart = {
id: '',
name: '',
panelName: '',
span: 4,
height: 4,
unit: 2,
groupId: -1,
updateBy: 1,
updateAt: '2022-05-18 07:51:45',
type: 'log',
weight: 6,
param: { limit: 100 },
pid: null,
buildIn: 0,
seq: null,
x: 0,
y: 1.93,
elements: [],
children: null,
chartNums: null,
asset: null,
varType: null,
varId: null,
varName: null,
datasource: 'logs',
enable: { thresholds: false, legend: true, valueMapping: false },
sync: 0,
remark: ''
}
this.expressions.forEach((exp, index) => {
chart.elements.push({ expression: exp, legend: '', type: 'expert', id: '', name: 'A' })
})
this.chartData = chart
this.rightBox.show = true
},
createSuccess (panel) { // 添加chart成功
this.$confirm(this.$t('dashboard.metric.goPanelTip'), this.$t('tip.saveSuccess'), {
confirmButtonText: this.$t('tip.yes'),

View File

@@ -41,7 +41,8 @@ export default {
yAxisFormatter: Function,
map: {},
axisTooltip: { type: String }, // x/y
minusTime: {} // 用于比较图表时的时间差值
minusTime: {}, // 用于比较图表时的时间差值
timeRange: {}
},
data () {
return {
@@ -387,8 +388,22 @@ export default {
const day = tData.getDate() > 9 ? tData.getDate() : '0' + tData.getDate()
const hour = tData.getHours() > 9 ? tData.getHours() : '0' + tData.getHours()
const minute = tData.getMinutes() > 9 ? tData.getMinutes() : '0' + tData.getMinutes()
return [month, day].join('-') + '\n' +
[hour, minute].join(':')
const dateFormatStr = this.timeFormatMain.split(' ')[0]
const diffSec = (this.timezoneToUtcTime(this.timeRange[1]) - this.timezoneToUtcTime(this.timeRange[0]))
const secOneDay = 24 * 60 * 60 * 1000// 1天的毫秒数
let str = ''
if (dateFormatStr === 'DD/MM/YYYY') {
str += [day, month].join('/')
} else if (dateFormatStr === 'MM/DD/YYYY') {
str += [month, day].join('/')
} else {
str += [month, day].join('-')
}
if (diffSec <= secOneDay) { // 同一天
return [hour, minute].join(':')
} else { // 大于1天小于30天
return str + '\n' + [hour, minute].join(':')
}
},
defaultToolBoxFormatter (params) {
if (params.name === 'stack') {
@@ -544,6 +559,17 @@ export default {
const chartUnit = chartInfo.unit ? chartInfo.unit : 2
const unit = chartDataFormat.getUnit(chartUnit)
minValue = minValue > 0 ? 0 : minValue
if (!isNaN(maxValue)) {
maxValue = Number(maxValue)
} else {
maxValue = 0
}
if (maxValue < 0) {
maxValue = Math.abs(maxValue)
}
if (Math.abs(minValue) > Math.abs(maxValue)) {
maxValue = Math.abs(minValue)
}
maxValue = maxValue - minValue
maxValue = chartDataFormat.formatDatas(maxValue, unit.type, 'ceil', unit.ascii)
let oldValue = maxValue

View File

@@ -578,7 +578,6 @@ export default {
this.$get('visual/panel/chart?panelId=' + params.panelId + '&groupId=0' + '&pageSize=-1').then(response => {
if (response.code === 200) {
this.chartListLoading = false
// response = chartData
this.dataList = response.data.list.map(item => {
return {
...item,

View File

@@ -875,6 +875,13 @@ export default {
this.initQueryFromPath(searchKeys)
},
mounted () {
if (this.$route.query && this.$route.query.assetId) {
this.object = {
...this.newObject(),
assetId: JSON.stringify(this.$route.query.assetId),
}
this.rightBox.show = true
}
if (localStorage.getItem('endpointProjectId')) {
this.selectValue.projectIds = [Number(localStorage.getItem('endpointProjectId'))]
// this.$refs.clickSearch.selectValueOut.projectIds = [localStorage.getItem('endpointProjectId')]

View File

@@ -208,7 +208,6 @@ export default {
}
if (event.path[0].className === 'ti-input') {
const tiInputBox = document.getElementsByClassName('ti-new-tag-input')[0]
console.log(tiInputBox)
tiInputBox.focus()
}
})

View File

@@ -95,7 +95,7 @@
<span>{{$t('ping.progress')}}:<span class="margin-l-10 margin-r-30">{{process}}%</span></span>
</div>
<el-button class="nz-btn nz-btn-size-normal nz-btn-style-normal" v-if="!isStart" @click="startTask">
{{$t('ping.trance')}}
{{$t('ping.trace')}}
</el-button>
<el-button class="nz-btn nz-btn-size-normal nz-btn-style-normal" v-else @click="clearTask">
{{$t('config.terminallog.stop')}}
@@ -209,7 +209,6 @@ export default {
}
if (event.path[0].className === 'ti-input') {
const tiInputBox = document.getElementsByClassName('ti-new-tag-input')[0]
console.log(tiInputBox)
tiInputBox.focus()
}
})