ConsulManager/vue-consul/src/views/node-exporter/self.vue

534 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="app-container">
<div class="filter-container">
<el-select v-model="listQuery.vendor" placeholder="机房/公司" clearable collapse-tags style="width: 150px" class="filter-item">
<el-option v-for="item in vendor_list" :key="item" :label="item" :value="item" />
</el-select>
<el-select v-model="listQuery.account" placeholder="租户/部门" clearable style="width: 150px" class="filter-item">
<el-option v-for="item in account_list" :key="item" :label="item" :value="item" />
</el-select>
<el-select v-model="listQuery.region" filterable placeholder="区域/项目" clearable style="width: 160px" class="filter-item">
<el-option v-for="item in region_list" :key="item" :label="item" :value="item" />
</el-select>
<el-select v-model="listQuery.group" filterable placeholder="分组/环境" clearable style="width: 100px" class="filter-item">
<el-option v-for="item in group_list" :key="item" :label="item" :value="item" />
</el-select>
<el-tooltip class="item" effect="light" content="点击清空查询条件" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-refresh" circle @click="handleReset" />
</el-tooltip>
<el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate">
新增
</el-button>
<el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">
导出
</el-button>
<el-button class="filter-item" type="danger" icon="el-icon-delete" @click="handleDelAll">
批量删除
</el-button>
<div style="float: right;">
<el-input v-model="iname" prefix-icon="el-icon-search" placeholder="请输入名称或实例进行筛选" clearable style="width:230px" class="filter-item" @input="inameFilter(iname)" />
</div>
</div>
<el-table
v-loading="listLoading"
:data="all_list.filter(data => !iname || (data.name.toLowerCase().includes(iname.toLowerCase()) || data.instance.toLowerCase().includes(iname.toLowerCase())))"
border
fit
highlight-current-row
style="width: 100%;"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" align="center" width="35" />
<el-table-column label="ID" align="center" width="40px">
<template slot-scope="scope">
<span>{{ scope.$index+1 }}</span>
</template>
</el-table-column>
<el-table-column prop="vendor" label="机房/公司" sortable align="center">
<template slot-scope="{row}">
<span>{{ row.vendor }}</span>
</template>
</el-table-column>
<el-table-column prop="account" label="租户/部门" sortable align="center">
<template slot-scope="{row}">
<span>{{ row.account }}</span>
</template>
</el-table-column>
<el-table-column prop="region" label="区域/项目" sortable align="center" show-overflow-tooltip>
<template slot-scope="{row}">
<span>{{ row.region }}</span>
</template>
</el-table-column>
<el-table-column prop="group" label="分组/环境" sortable align="center">
<template slot-scope="{row}">
<span>{{ row.group }}</span>
</template>
</el-table-column>
<el-table-column prop="name" label="名称" sortable align="center" show-overflow-tooltip>
<template slot-scope="{row}">
<span>{{ row.name }}</span>
</template>
</el-table-column>
<el-table-column prop="instance" label="实例" sortable align="center" width="160" show-overflow-tooltip>
<template slot-scope="{row}">
<span>{{ row.instance }}</span>
</template>
</el-table-column>
<el-table-column prop="os" label="系统" sortable align="center" width="80">
<template slot-scope="{row}">
<span>{{ row.os }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
<template slot-scope="{row}">
<el-button type="primary" size="mini" @click="handleUpdate(row)">
编辑
</el-button>
<el-button size="mini" type="danger" @click="handleDelete(row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="handleFilter" />
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="37%">
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="right" label-width="auto" style="width: 90%; margin-left: 20px;">
<el-form-item label="机房/公司" prop="vendor">
<el-autocomplete v-model="temp.vendor" :fetch-suggestions="Sugg_vendor" placeholder="优先选择" clearable class="filter-item" />
</el-form-item>
<el-form-item label="租户/部门" prop="account">
<el-autocomplete v-model="temp.account" :fetch-suggestions="Sugg_account" placeholder="优先选择" clearable class="filter-item" />
</el-form-item>
<el-form-item label="区域/项目" prop="region">
<el-autocomplete v-model="temp.region" :fetch-suggestions="Sugg_region" placeholder="优先选择" clearable class="filter-item" />
</el-form-item>
<el-form-item label="分组/环境" prop="group">
<el-autocomplete v-model="temp.group" :fetch-suggestions="Sugg_group" placeholder="优先选择" clearable class="filter-item" />
</el-form-item>
<el-form ref="dataForm" :inline="true" :rules="rules" :model="temp" class="demo-form-inline" label-position="right" label-width="50px">
<el-form-item label="名称" prop="name">
<el-input v-model="temp.name" placeholder="请输入" clearable />
</el-form-item>
<el-form-item label="系统" prop="os">
<el-select v-model="temp.os" placeholder="请选择" style="width: 130px;" @change="temp.port=osport[temp.os]">
<el-option label="linux" value="linux" />
<el-option label="windows" value="windows" />
</el-select>
</el-form-item>
<el-form-item label="IP" prop="ip">
<el-input v-model="temp.ip" placeholder="请输入" clearable />
</el-form-item>
<el-form-item label="端口" prop="port">
<el-input v-model="temp.port" placeholder="请输入" clearable style="width: 130px;" />
</el-form-item>
</el-form>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button v-if="dialogStatus==='create'" type="primary" @click="createAndNew">
确认并新增
</el-button>
<el-button @click="dialogFormVisible = false">
取消
</el-button>
<el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import waves from '@/directive/waves' // waves directive
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
import { getAllList, getAllInfo, addService, updateService, delService } from '@/api/selfnode'
export default {
name: 'ComplexTable',
components: { Pagination },
directives: { waves },
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
const validateInput = (rule, value, callback) => {
if (!this.checkSpecialKey(value)) {
callback(new Error('不能含有空格或 [ ]`~!#$^&*=|"{}\':;?'))
} else {
callback()
}
}
return {
all_list: [],
pall_list: [],
iname: '',
new_list: [],
total: 0,
listLoading: true,
listQuery: {
page: 1,
limit: 30,
vendor: '',
account: '',
region: '',
group: ''
},
value_vendor: [],
value_account: [],
value_region: [],
value_group: [],
multipleSelection: [],
del_dict: {},
osport: { linux: '9100', windows: '9182' },
temp: {
vendor: '',
account: '',
region: '',
group: '',
name: '',
os: '',
ip: '',
port: ''
},
dialogFormVisible: false,
dialogStatus: '',
textMap: {
update: '更新',
create: '创建'
},
rules: {
vendor: [{ required: true, message: '此为必填项', trigger: 'change' },
{ validator: validateInput, trigger: ['blur', 'change'] }],
account: [{ required: true, message: '此为必填项', trigger: 'change' },
{ validator: validateInput, trigger: ['blur', 'change'] }],
region: [{ required: true, message: '此为必填项', trigger: 'change' },
{ validator: validateInput, trigger: ['blur', 'change'] }],
group: [{ required: true, message: '此为必填项', trigger: 'change' },
{ validator: validateInput, trigger: ['blur', 'change'] }],
name: [{ required: true, message: '此为必填项', trigger: 'change' },
{ validator: validateInput, trigger: ['blur', 'change'] }],
ip: [{ required: true, message: '此为必填项', trigger: 'change' },
{ validator: validateInput, trigger: ['blur', 'change'] }],
port: [{ required: true, message: '此为必填项', trigger: 'change' },
{ validator: validateInput, trigger: ['blur', 'change'] }],
os: [{ required: true, message: '此为必填项', trigger: 'change' },
{ validator: validateInput, trigger: ['blur', 'change'] }]
},
downloadLoading: false
}
},
computed: {
cvendor() {
return this.listQuery.vendor
},
caccount() {
return this.listQuery.account
},
cregion() {
return this.listQuery.region
},
cgroup() {
return this.listQuery.group
}
},
watch: {
cvendor(new_vendor) {
this.fetchList(new_vendor, this.listQuery.account, this.listQuery.region, this.listQuery.group)
},
caccount(new_account) {
this.fetchList(this.listQuery.vendor, new_account, this.listQuery.region, this.listQuery.group)
},
cregion(new_region) {
this.fetchList(this.listQuery.vendor, this.listQuery.account, new_region, this.listQuery.group)
},
cgroup(new_group) {
this.fetchList(this.listQuery.vendor, this.listQuery.account, this.listQuery.region, new_group)
}
},
created() {
this.fetchData()
},
methods: {
inameFilter(iname) {
if (iname === '') {
this.handleFilter()
} else {
this.total = 0
this.all_list = this.pall_list
}
},
handleFilter() {
this.total = this.pall_list.length
this.all_list = this.pall_list.slice(0 + this.listQuery.limit * (this.listQuery.page - 1), this.listQuery.limit + this.listQuery.limit * (this.listQuery.page - 1))
},
handleSelectionChange(val) {
this.multipleSelection = val
},
checkSpecialKey(str) {
const specialKey = '[]`~!#$^&*=|{}\'":;? '
for (let i = 0; i < str.length; i++) {
if (specialKey.indexOf(str.substr(i, 1)) !== -1) {
return false
}
}
return true
},
fetchData() {
this.listLoading = true
getAllInfo().then(response => {
this.all_list = response.all_list
this.vendor_list = response.vendor_list
this.account_list = response.account_list
this.region_list = response.region_list
this.group_list = response.group_list
this.listLoading = false
this.xvendor = this.load_vendor()
this.xaccount = this.load_account()
this.xregion = this.load_region()
this.xgroup = this.load_group()
this.pall_list = response.all_list
this.handleFilter()
})
},
fetchList(vendor, account, region, group) {
this.listLoading = true
getAllList(vendor, account, region, group).then(response => {
this.all_list = response.all_list
this.listLoading = false
this.vendor_list = response.vendor_list
this.account_list = response.account_list
this.region_list = response.region_list
this.group_list = response.group_list
this.listQuery.page = 1
this.pall_list = response.all_list
this.handleFilter()
})
},
resetTemp() {
this.temp = {}
},
handleCreate() {
this.resetTemp()
var newone = {
vendor: this.listQuery.vendor,
account: this.listQuery.account,
region: this.listQuery.region,
group: this.listQuery.group,
os: 'linux',
port: '9100'
}
this.temp = Object.assign({}, this.temp, newone)
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
createData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
addService(this.temp).then(response => {
this.temp.instance = this.temp.ip + ':' + this.temp.port
this.all_list.unshift(this.temp)
this.dialogFormVisible = false
this.$message({
message: response.data,
type: 'success'
})
})
}
})
},
createAndNew() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
addService(this.temp).then(response => {
this.temp.instance = this.temp.ip + ':' + this.temp.port
this.all_list.unshift(this.temp)
this.dialogFormVisible = false
this.$message({
message: response.data,
type: 'success'
})
var newtemp = {
vendor: this.temp.vendor,
account: this.temp.account,
region: this.temp.region,
group: this.temp.group,
os: 'linux',
port: '9100'
}
this.resetTemp()
this.temp = Object.assign({}, this.temp, newtemp)
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
})
}
})
},
handleReset() {
this.listQuery.vendor = ''
this.listQuery.account = ''
this.listQuery.region = ''
this.listQuery.group = ''
},
handleUpdate(row) {
row.ip = row.instance.split(':')[0]
row.port = row.instance.split(':')[1]
this.temp = Object.assign({}, row) // copy obj
this.del_dict = row
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
updateData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
const up_dict = Object.assign({}, this.temp)
updateService(this.del_dict, up_dict).then(response => {
this.dialogFormVisible = false
this.$message({
message: response.data,
type: 'success'
})
up_dict.instance = up_dict.ip + ':' + up_dict.port
this.all_list.splice(this.all_list.indexOf(this.del_dict), 1, up_dict)
})
}
})
},
handleDelete(row) {
this.$confirm('此操作将删除【' + row.group + '' + row.region + '' + row.name + '】,是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delService(row).then(response => {
this.$message({
message: response.data,
type: 'success'
})
this.$delete(this.all_list, this.all_list.indexOf(row))
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
handleDelAll() {
this.$confirm('此操作将批量删除选中行,是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
for (let i = 0; i < this.multipleSelection.length; i++) {
delService(this.multipleSelection[i]).then(response => {
this.$message({
message: response.data,
type: 'success'
})
})
this.$delete(this.all_list, this.all_list.indexOf(this.multipleSelection[i]))
}
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['机房/公司', '租户/部门', '区域/项目', '分组/环境', '名称', '实例', '系统']
const filterVal = ['vendor', 'account', 'region', 'group', 'name', 'instance', 'os']
const data = this.formatJson(filterVal)
excel.export_json_to_excel({
header: tHeader,
data,
filename: 'selfnode-list'
})
this.downloadLoading = false
})
},
formatJson(filterVal) {
return this.all_list.map(v => filterVal.map(j => {
return v[j]
}))
},
Sugg_vendor(queryString, cb) {
var xvendor = this.xvendor
var results = queryString ? xvendor.filter(this.createFilter(queryString)) : xvendor
cb(results)
},
Sugg_account(queryString, cb) {
var xaccount = this.xaccount
var results = queryString ? xaccount.filter(this.createFilter(queryString)) : xaccount
cb(results)
},
Sugg_region(queryString, cb) {
var xregion = this.xregion
var results = queryString ? xregion.filter(this.createFilter(queryString)) : xregion
cb(results)
},
Sugg_group(queryString, cb) {
var xgroup = this.xgroup
var results = queryString ? xgroup.filter(this.createFilter(queryString)) : xgroup
cb(results)
},
createFilter(queryString) {
return (restaurant) => {
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
}
},
load_vendor() {
for (const x in this.vendor_list) {
this.value_vendor.push({ 'value': this.vendor_list[x] })
}
return this.value_vendor
},
load_account() {
for (const x in this.account_list) {
this.value_account.push({ 'value': this.account_list[x] })
}
return this.value_account
},
load_region() {
for (const x in this.region_list) {
this.value_region.push({ 'value': this.region_list[x] })
}
return this.value_region
},
load_group() {
for (const x in this.group_list) {
this.value_group.push({ 'value': this.group_list[x] })
}
return this.value_group
}
}
}
</script>