This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nezha-nezha-fronted/nezha-fronted/src/components/common/popBox/topToolMoreOptions.vue
chenjinsong ef664be5ef Merge remote-tracking branch 'origin/dev-3.1' into dev-3.1.1_theme
# Conflicts:
#	nezha-fronted/src/assets/css/common.scss
#	nezha-fronted/src/assets/css/common/tableCommon.scss
#	nezha-fronted/src/assets/stylus/main.scss
#	nezha-fronted/src/components/charts/chart-list.vue
#	nezha-fronted/src/components/charts/logs.vue
#	nezha-fronted/src/components/common/alert/alertLabel.vue
#	nezha-fronted/src/components/common/alert/alertRuleInfo.vue
#	nezha-fronted/src/components/common/bottomBox/bottomBox.vue
#	nezha-fronted/src/components/common/bottomBox/tabs/endpointQuery.vue
#	nezha-fronted/src/components/common/bottomBox/tabs/endpointQueryTab.vue
#	nezha-fronted/src/components/common/bottomBox/tabs/logBottomTab.vue
#	nezha-fronted/src/components/common/bottomBox/tabs/panelTabNew.vue
#	nezha-fronted/src/components/common/detailView/list/alertRule/alertRuleDetail.vue
#	nezha-fronted/src/components/common/detailView/list/asset/assetDetail.vue
#	nezha-fronted/src/components/common/detailView/list/dc/dcDetail.vue
#	nezha-fronted/src/components/common/detailView/list/endpoint/endpointDetail.vue
#	nezha-fronted/src/components/common/detailView/list/module/moduleDetail.vue
#	nezha-fronted/src/components/common/detailView/nzDetailView.vue
#	nezha-fronted/src/components/common/detailView/view/detailViewRight.vue
#	nezha-fronted/src/components/common/labelFilter/clickSearch.vue
#	nezha-fronted/src/components/common/multipleTime.vue
#	nezha-fronted/src/components/common/pickTime.vue
#	nezha-fronted/src/components/common/popBox/topToolMoreOptions.vue
#	nezha-fronted/src/components/common/project/L5/topoTooltip.vue
#	nezha-fronted/src/components/common/project/popData/Info.vue
#	nezha-fronted/src/components/common/rightBox/alertRuleBox.vue
#	nezha-fronted/src/components/common/table/alert/alertRuleTable.vue
#	nezha-fronted/src/components/common/table/alert/alertSilenceTable.vue
#	nezha-fronted/src/components/common/table/settings/userTable.vue
#	nezha-fronted/src/components/layout/header.vue
#	nezha-fronted/src/components/page/alert/alertMessage.vue
#	nezha-fronted/src/components/page/alert/nzAlertTag.vue
#	nezha-fronted/src/components/page/asset/components/operation.vue
#	nezha-fronted/src/components/page/config/mibBrowser.vue
#	nezha-fronted/src/components/page/dashboard/explore/exploreItem.vue
#	nezha-fronted/src/components/page/dashboard/explore/logTab.vue
#	nezha-fronted/src/components/page/dashboard/explore/promqlInput.vue
#	nezha-fronted/src/components/page/dashboard/overview/overview2.vue
#	nezha-fronted/src/components/page/dashboard/panel.vue
2021-11-01 18:24:01 +08:00

426 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dropdown trigger="click" :size="size">
<button id="more" :class="triggerButtonClass" title="more...">
<i class="nz-icon nz-icon-more2"></i>
</button>
<el-dropdown-menu slot="dropdown" class="right-box-select-top right-public-box-dropdown-top">
<el-dropdown-item v-if="showLock">
<div @click="panelLock=!panelLock" id="panel-lock"><i :class="{'nz-icon nz-icon-lock':panelLock,'nz-icon nz-icon-unlock':!panelLock}"></i>{{panelLock ? $t("overall.locked") : $t("overall.unlocked")}}</div>
</el-dropdown-item>
<!-- importexport之前的内容 -->
<slot name="before"></slot>
<el-dropdown-item v-if="importUrl">
<div id="chart-import" @click="showImportBox(1)"><i class="nz-icon nz-icon-upload"></i>{{$t('overall.importExcel')}}</div>
</el-dropdown-item>
<el-dropdown-item v-if="exportUrl">
<div id="chart-export"@click="showImportBox(2)"><i class="nz-icon nz-icon-download1"></i>{{$t('overall.exportExcel')}}</div>
</el-dropdown-item>
<!-- importexport之后的内容 -->
<slot name="after"></slot>
</el-dropdown-menu>
<el-dialog :close-on-click-modal="importBox.type!=3" destroy-on-close :show-close="true" :title="importBox.title" :visible.sync="importBox.show" :width="importBox.width" append-to-body class="nz-dialog" @close="closeDialog">
<div v-if="importBox.type == 1">
<div class="upload-body">
<el-upload :id="id+'-xlsx-input-file'" ref="uploadExcel" :auto-upload="false" :file-list="importFileList" :on-change="importChange" accept=".xlsx,.xls" action="" class="upload-demo" drag>
<div slot="tip" class="el-upload__tip" >{{$t('overall.importTip')}}</div>
<i class="nz-icon nz-icon-upload"></i>
<div class="el-upload__text">{{$t('overall.dragFileTip')}}{{$t('overall.or')}}&nbsp;<em>{{$t('overall.clickUpload')}}</em></div>
</el-upload>
</div>
<div slot="footer" class="footer">
<div class="el-message-box__btns" style="text-align: right;">
<button :id="id+'-xlsx-import-template'" class="el-button el-button--default el-button--small" @click="downloadTemplate">
<span>{{$t('overall.template')}}</span>
</button>
<button :id="id+'-xlsx-import-add'" :class="{'nz-btn-disabled':prevent_opt.import}" :disabled="prevent_opt.import" class="nz-btn el-button el-button--default el-button--small" @click="importExcel">
<span>{{$t('overall.importExcel')}}</span>
</button>
<button :id="id+'-xlsx-import-esc'" class="el-button el-button--default el-button--small" @click="closeDialog">
<span>{{$t('overall.cancel')}}</span>
</button>
</div>
</div>
</div>
<div v-if="importBox.type == 2">
<div class="upload-body">
<button :id="id+'-xlsx-export-current'" class="el-button el-button--default el-button--small" @click="exportCur">
<span>{{$t('overall.exportCur')}}</span>
</button>
<button :id="id+'-xlsx-export-all'" class="el-button el-button--default el-button--small" @click="exportAll">
<span>{{$t('overall.exportAll')}}</span>
</button>
</div>
<div slot="footer" class="footer">
</div>
</div>
<div v-if="importBox.type==3">
<div class="upload-body result-body">
<div v-if="importResult&&importResult.failNum">
<div class="result-title-top">
<div class="">
<i class="nz-icon nz-icon-import-success"/>
<span>{{$t('overall.result.successNum',{successNum:importResult.successNum})}}</span><br/>
</div>
<div class="">
<i class="nz-icon nz-icon-import-failed"/>
<span>{{$t('overall.result.failedNum',{failedNum:importResult.failNum,total:importResult.totalNum})}}</span>
</div>
</div>
<div>
<div v-if="importResult&&importResult.failDetail" class="result-detail">
<div style="height: 100%; overflow: auto">
<template v-for="(item, index) in importResult.failDetail">
<div :key="index" class="import-result-block">
<div class="import-result-item">
<div class="line-num">{{$t('overall.result.line',[item.lineNo])}}</div>
<div class="line-content" :title="item.errorMsg">{{item.errorMsg}}</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
<div v-else class="result-success-box">
<div>
<i class="nz-icon nz-icon-import-success"/>
</div>
<div class="result-success-txt">{{$t('overall.result.successfully')}}</div>
<div class="result-success-txt">
{{$t('overall.result.imported')}}
<span style="color: #333333" v-if="importResult">{{importResult.successNum}}</span>
{{$t('overall.result.records')}}
</div>
</div>
</div>
<div slot="footer" class="footer">
<div class="el-message-box__btns">
<button :id="id+'-xlsx-import-rollback'" class="nz-btn nz-btn-size-normal-new nz-btn-style-error-new" @click="rollbackImport">
<span>{{$t('overall.rollbackImport')}}</span>
</button>
<button :id="id+'-xlsx-import-close'" class="nz-btn el-button el-button--default el-button--small" @click="closeDialog">
<span>{{$t('overall.close')}}</span>
</button>
</div>
</div>
</div>
</el-dialog>
</el-dropdown>
</template>
<script>
import axios from 'axios'
let timeout
export default {
name: 'topToolMoreOptions',
props: {
size: {
type: String,
default: 'medium'
},
exportUrl: { type: String, default: '' },
params: { type: Object },
params2: { type: Object },
exportFileName: { type: String },
importUrl: { type: String, default: '' }, // 为空时不显示导入按钮
link: { type: Object }, // 为空时不显示导出按钮
permissions: { type: Object },
showCur: { type: Boolean, default: true },
id: { type: String, default: 'export' },
triggerButtonClass: { // 触发下拉事件的按钮的class
type: String,
default: 'top-tool-btn'
},
showLock: {
type: Boolean, default: false
},
paramsType: {
type: String,
default: ''
}
},
data () {
return {
importBox: { show: false, title: this.$t('overall.importExcel'), type: 1 },
importFile: null,
importFileList: [],
importResult: null,
exportShow: false,
panelLock: true,
language: localStorage.getItem('nz-language')
}
},
mounted () {
// this.getParamsType()
},
methods: {
importChange (file, fileList) {
if (fileList.length > 0) {
this.importFileList = [fileList[fileList.length - 1]]
}
this.importFile = this.importFileList[0]
this.validateFile()
},
validateFile () {
},
rollbackImport () {
let url
if (this.importUrl.indexOf('/asset/model') > -1) {
url = '/asset/model/cancelImport'
} else if (this.importUrl.indexOf('asset') > -1) {
url = '/asset/asset/cancelImport'
} else if (this.importUrl.indexOf('endpoint') > -1) {
url = '/monitor/endpoint/cancelImport'
} else if (this.importUrl.indexOf('module') > -1) {
url = '/monitor/module/cancelImport'
} else if (this.importUrl.indexOf('rule') > -1) {
url = '/alert/rule/cancelImport'
} else if (this.importUrl.indexOf('panel') > -1) {
url = 'visual/panel/cancelImport'
} else if (this.importUrl.indexOf('tmpl') > -1) {
url = '/expression/tmpl/cancelImport'
} else if (this.importUrl.indexOf('dc/cabinet') > -1) {
url = '/dc/cabinet/cancelImport'
} else if (this.importUrl.indexOf('dc') > -1) {
url = '/dc/cancelImport'
}
this.$delete(url + '?seq=' + this.importResult.seq).then(response => {
if (response.code == 200) {
const linkId = this.link ? this.link.id : ''
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.$emit('afterImport', linkId)
} else {
this.$message.error(response.msg)
}
this.closeDialog()
})
},
importExcel () {
if (this.importFile && this.importFile.raw) {
this.prevent_opt.import = true
const form = new FormData()
form.append('excelFile', this.importFile.raw)
if (this.paramsType) {
form.append('type', this.paramsType)
if (this.paramsType === 'asset' || this.paramsType === 'endpoint') {
form.append('linkId', this.link ? this.link.id : '')
}
}
if (this.importUrl.indexOf('dc/cabinet') > -1) {
form.append('dcIds', this.params.dcIds)
}
form.append('language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en')
this.$post(this.importUrl, form, { 'Content-Type': 'multipart/form-data' }).then(response => {
if (response.code == 200 && response.msg == 'success') {
this.importResult = response.data
const linkId = this.link ? this.link.id : ''
this.$emit('afterImport', linkId)
this.importBox.type = 3
this.importBox.width = '600px'
} else {
this.$message.error(response.msg)
}
this.prevent_opt.import = false
})
} else {
this.$message.error(this.$t('tip.noImportFile'))
}
},
exportMenuHandler (show) {
if (show) {
clearTimeout(timeout)
this.exportShow = true
} else {
timeout = setTimeout(() => {
this.exportShow = false
}, 700)
}
},
closeDialog () {
this.importBox.show = false
this.$nextTick(() => {
this.importResult = null
this.importFileList = []
this.importFile = null
})
},
downloadTemplate () {
const language = localStorage.getItem('nz-language') || 'en' // 初始未选择默认 en 英文
const fileName = this.exportFileName + '-' + this.$t('overall.template') + '-' + this.getTimeString() + '.xlsx'
let url = null
const param = { language: language }
if (this.importUrl.indexOf('/asset/model') > -1) {
url = '/asset/model/template'
} else if (this.importUrl.indexOf('asset') > -1) {
url = '/asset/asset/template'
param.type = 'asset'
} else if (this.importUrl.indexOf('panel') > -1) {
url = 'visual/panel/template'
param.type = this.paramsType
} else if (this.importUrl.indexOf('endpoint') > -1) {
url = '/monitor/endpoint/template'
param.type = 'endpoint'
} else if (this.importUrl.indexOf('module') > -1) {
url = '/monitor/module/template'
param.type = 'module'
} else if (this.importUrl.indexOf('tmpl') > -1) {
url = '/expression/tmpl/template'
} else if (this.importUrl.indexOf('alert') > -1) {
url = '/alert/rule/template'
} else if (this.importUrl.indexOf('dc/cabinet') > -1) {
url = '/dc/cabinet/template'
} else if (this.importUrl.indexOf('dc') > -1) {
url = '/dc/template'
}
if (!url) {
console.error('no interface support')
}
this.exportExcel(url, param, fileName)
},
formatJson (filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => v[j]))
},
exportCur () {
const params = JSON.parse(JSON.stringify(this.params))
if (this.params2) {
Object.keys(this.params2).forEach(key => {
if (params[key]) {
if (params[key].prototype.toString.call(val) === '[object Object]') {
Object.assign(params[key], this.params2[key])
} else if (params[key].prototype.toString.call(val) === '[object Array]') {
params[key].concat(this.params2[key])
}
} else {
params[key] = this.params2[key]
}
})
}
if (this.exportUrl.indexOf('panel') > -1) {
if (this.paramsType !== 'template') {
params.pageSize = -1
}
delete params.start_time
delete params.end_time
delete params.id
delete params.searchName
}
params.language = localStorage.getItem('nz-language') || 'en'
this.exportExcel(this.exportUrl, params, this.exportFileName + '-' + this.getTimeString() + '.xlsx')
this.closeDialog()
},
exportAll () {
const params = JSON.parse(JSON.stringify(this.params))
if (this.params2) {
Object.keys(this.params2).forEach(key => {
if (params[key]) {
if (params[key].prototype.toString.call(val) === '[object Object]') {
Object.assign(params[key], this.params2[key])
} else if (params[key].prototype.toString.call(val) === '[object Array]') {
params[key].concat(this.params2[key])
}
} else {
params[key] = this.params2[key]
}
})
}
params.pageSize = -1
if (this.exportUrl.indexOf('panel') > -1) {
delete params.start_time
delete params.end_time
delete params.id
delete params.searchName
}
if (this.importUrl.indexOf('panel') > -1) {
delete params.panelId
}
// if (this.importUrl.indexOf('endpoint') > -1){
// delete params.moduleId
// }
params.language = localStorage.getItem('nz-language') || 'en'
this.exportExcel(this.exportUrl, params, this.exportFileName + '-' + this.getTimeString() + '.xlsx')
this.closeDialog()
},
exportExcel (url, params, fileName) {
if (this.paramsType) {
params.type = this.paramsType
}
if (params.from == 'asset') {
delete params.type
delete params.from
}
axios.get(url, { responseType: 'blob', params: params }).then(res => {
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标签移除
}
}, error => {
const $self = this
const reader = new FileReader()
reader.onload = function (event) {
const responseText = reader.result
const exception = JSON.parse(responseText)
if (exception.message) {
$self.$message.error(exception.message)
} else {
console.error(error)
}
}
reader.readAsText(error.response.data)
})
},
showImportBox (type) {
this.importBox.show = true
this.importBox.type = type
if (type == 2 && (!this.showCur)) {
this.exportCur()
return
}
if (type == 1) { // import
this.importBox.title = this.$t('overall.importExcel')
this.importBox.width = '600px'
} else if (type == 2) { // export
this.importBox.title = this.$t('overall.exportExcel')
this.importBox.width = '300px'
}
},
getTimeString () {
const split = '-'
const date = new Date()
const year = date.getFullYear()
const month = this.formatNum(date.getMonth() + 1)
const day = this.formatNum(date.getDate())
const hours = this.formatNum(date.getHours())
const minutes = this.formatNum(date.getMinutes())
const seconds = this.formatNum(date.getSeconds())
return year + split + month + split + day + ' ' + hours + split + minutes + split + seconds
},
formatNum (num) {
return num > 9 ? num : '0' + num
}
},
watch: {
panelLock: {
immediate: true,
handler (n) {
this.$emit('panelLockChange', n)
}
}
}
}
</script>