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
2022-07-01 09:39:20 +08:00

543 lines
21 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="$t('overall.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-has="permissions.import" 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-has="permissions.export" 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" style="height: 200px">
<div class="export-box">
<span class="export-title">Records</span>
<el-radio-group v-model="importBox.record" size="small">
<el-radio-button :label="item.value" v-for="(item,index) in recordArr" :key="index" :disabled="item.value==='records'&&!deleteObjs.length">{{item.name}}</el-radio-button>
</el-radio-group>
</div>
<div class="export-box">
<span class="export-title">File format</span>
<el-radio-group v-model="importBox.format" size="small">
<el-radio-button :label="item.value" v-for="(item,index) in formatArr" :key="index">{{item.name}}</el-radio-button>
</el-radio-group>
</div>
</div>
<div slot="footer" class="footer">
<div class="el-message-box__btns">
<button :id="id+'-xlsx-import-export'" class="nz-btn nz-btn-size-normal nz-btn-style-normal-new" @click="exportData">
<span style="text-transform:Capitalize">{{$t('overall.exportExcel')}}</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>
<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 nz-btn-style-error" @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: ''
},
deleteObjs: Array,
exportBoxShow: {
type: Boolean, default: false
}
},
computed: {
language () { return this.$store.getters.getLanguage }
},
data () {
return {
importBox: { show: false, title: this.$t('overall.importExcel'), type: 1, record: 'all', format: 1 },
importFile: null,
importFileList: [],
importResult: null,
exportShow: false,
panelLock: true,
recordArr: [
{ name: this.$t('overall.allData'), value: 'all' },
{ name: this.$t('overall.selectRecords'), value: 'records' },
{ name: this.$t('overall.current'), value: 'current' }
],
formatArr: [
{ name: 'XLSX', value: 1 },
{ name: 'CSV', value: 2 },
{ name: 'JSON', value: 3 }
],
suffix: '.xlsx'
}
},
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'
} else if (this.importUrl.indexOf('/ipam/subnet') > -1) {
url = '/ipam/subnet/cancelImport'
} else if (this.importUrl.indexOf('/ipam/ip') > -1) {
url = '/ipam/ip/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
setTimeout(() => {
this.$nextTick(() => {
this.importResult = null
this.importFileList = []
this.importFile = null
this.importBox.value = 1
this.importBox.record = 'all'
this.importBox.format = 1
})
}, 200)
},
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'
} else if (this.importUrl.indexOf('ipam/subnet') > -1) {
url = '/ipam/subnet/template'
} else if (this.importUrl.indexOf('ipam/ip') > -1) {
url = '/ipam/ip/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'
params.format = this.importBox.format
delete params.statistics
this.exportExcel(this.exportUrl, params, this.exportFileName + '-' + this.getTimeString() + this.suffix)
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'
params.format = this.importBox.format
delete params.statistics
this.exportExcel(this.exportUrl, params, this.exportFileName + '-' + this.getTimeString() + this.suffix)
this.closeDialog()
},
exportRecords () {
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'
params.format = this.importBox.format
params.ids = this.deleteObjs.map(item => item.id).join(',')
delete params.statistics
this.exportExcel(this.exportUrl, params, this.exportFileName + '-' + this.getTimeString() + this.suffix)
this.closeDialog()
},
exportData () {
if (this.importBox.format == 1) {
this.suffix = '.xlsx'
} else if (this.importBox.format == 2) {
this.suffix = '.csv'
} else if (this.importBox.format == 3) {
this.suffix = '.json'
} else if (this.importBox.format == 4) {
this.suffix = '.pdf'
this.$emit('export', 'PDF')
return
} else if (this.importBox.format == 5) {
this.suffix = '.html'
this.$emit('export', 'Html')
return
}
if (this.importBox.record === 'all') {
this.exportAll()
} else if (this.importBox.record === 'current') {
this.exportCur()
} else if (this.importBox.record === 'records') {
this.exportRecords()
}
},
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 = '580px'
// if (this.exportBoxShow) {
// this.formatArr = [
// { name: 'XLSX', value: 1 },
// { name: 'CSV', value: 2 },
// { name: 'JSON', value: 3 },
// { name: 'PDF', value: 4 },
// { name: 'Html', value: 5 }]
// } else {
// this.formatArr = [{ name: 'XLSX', value: 1 },
// { name: 'CSV', value: 2 },
// { name: 'JSON', value: 3 }]
// }
}
},
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>