feat:创建module弹窗根据接口修改(60%)

This commit is contained in:
zhangyu
2021-04-13 19:06:34 +08:00
parent e21320fc32
commit e3729418cb
12 changed files with 662 additions and 370 deletions

View File

@@ -1129,6 +1129,7 @@ const cn = {
defaultEndpointSet: '默认的Endpoint设置', defaultEndpointSet: '默认的Endpoint设置',
relation: '模块关联的Endpoint将默认配置以下端口/路径/参数' relation: '模块关联的Endpoint将默认配置以下端口/路径/参数'
}, },
type: '类型',
version: '版本', version: '版本',
walk: 'Walk', walk: 'Walk',
maxRepetitions: '最大迭代次数', maxRepetitions: '最大迭代次数',
@@ -1139,6 +1140,7 @@ const cn = {
authProtocol: '认证协议', authProtocol: '认证协议',
privProtocol: '隐私协议', privProtocol: '隐私协议',
contextName: '内容名称', contextName: '内容名称',
alerts: 'Alerts',
privPassword: '隐私密码' privPassword: '隐私密码'
}, },
endpoint: { endpoint: {
@@ -1163,7 +1165,20 @@ const cn = {
stateInfo_230010: 'Prometheus服务可用', stateInfo_230010: 'Prometheus服务可用',
stateInfo_230011: 'Endpoint 连接错误', stateInfo_230011: 'Endpoint 连接错误',
alerts: '告警', alerts: '告警',
labels: '标签' labels: '标签',
pattern: 'Name pattern',
credentials: '资格证书',
scrape_interval: '时间间隔',
scrape_interval_placeholder: '默认全局时间间隔',
scrape_timeout: '超时时间',
scrape_timeout_placeholder: '默认全局超时时间',
type: '类型',
bearer_token: 'Token',
username: '用户名',
password: '密码',
authTypeNull: '无',
authTypeWord: '用户名密码',
authTypeToken: 'Token',
}, },
metrics: { metrics: {
metrics: '指标', metrics: '指标',

View File

@@ -1132,6 +1132,7 @@ const en = {
createModule: 'New module', // "新增组件" createModule: 'New module', // "新增组件"
version: 'Version', version: 'Version',
walk: 'Walk', walk: 'Walk',
type: 'Type',
maxRepetitions: 'Max repetitions', maxRepetitions: 'Max repetitions',
retries: 'Retries', retries: 'Retries',
timeout: 'Timeout', timeout: 'Timeout',
@@ -1141,6 +1142,7 @@ const en = {
privProtocol: 'Priv protocol', privProtocol: 'Priv protocol',
contextName: 'Context name', contextName: 'Context name',
privPassword: 'Priv password', privPassword: 'Priv password',
alerts: 'Alerts',
tip: { tip: {
defaultEndpointSet: 'Default endpoint settings', // "默认的Endpoint设置" defaultEndpointSet: 'Default endpoint settings', // "默认的Endpoint设置"
relation: 'Module associated Endpoint will configure the following ports/paths/parameters by default'// "组件关联的Endpoint将默认配置以下端口/路径/参数" relation: 'Module associated Endpoint will configure the following ports/paths/parameters by default'// "组件关联的Endpoint将默认配置以下端口/路径/参数"
@@ -1168,7 +1170,20 @@ const en = {
stateInfo_230010: 'Promserver can be used', stateInfo_230010: 'Promserver can be used',
stateInfo_230011: 'Endpoint connection refused', stateInfo_230011: 'Endpoint connection refused',
alerts: 'Alerts', alerts: 'Alerts',
labels: 'Labels' labels: 'Labels',
pattern: 'Name pattern',
credentials: 'Credentials',
scrape_interval: 'Scrape interval',
scrape_interval_placeholder: 'default global scrape interval',
scrape_timeout: 'Scrape timeout',
scrape_timeout_placeholder: 'default global scrape timeout',
type: 'Type',
bearer_token: 'Token',
username: 'Username',
password: 'Password',
authTypeNull: 'None',
authTypeWord: 'Username and password',
authTypeToken: 'Token',
}, },
metrics: { metrics: {
metrics: 'Metrics', // "指标" metrics: 'Metrics', // "指标"

View File

@@ -22,6 +22,7 @@
:default-checked-keys="currentWalk" :default-checked-keys="currentWalk"
> >
<div slot-scope="data" :class="getClass(data.data.objectID)" class="walk-tree-item"> <div slot-scope="data" :class="getClass(data.data.objectID)" class="walk-tree-item">
<span>
<span v-if="!data.data.type"><i class="nz-icon nz-icon-reading"></i></span> <span v-if="!data.data.type"><i class="nz-icon nz-icon-reading"></i></span>
<span v-else> <span v-else>
<i v-if="data.data.type.toUpperCase() === 'IDENTIFIER'" class="el-icon-folder-opened"></i> <i v-if="data.data.type.toUpperCase() === 'IDENTIFIER'" class="el-icon-folder-opened"></i>
@@ -33,7 +34,8 @@
<i class="nz-icon nz-icon-info-normal metric-tip-icon"></i> <i class="nz-icon nz-icon-info-normal metric-tip-icon"></i>
</span> </span>
</span> </span>
{{data.name}} </span>
{{data.data.name}}
</div> </div>
</el-tree> </el-tree>
</div> </div>
@@ -64,6 +66,9 @@ export default {
computed: { computed: {
getClass () { getClass () {
return (value) => { return (value) => {
if (!value) {
return ''
}
return this.currentWalk.indexOf(value) == -1 ? '' : 'walk-active' return this.currentWalk.indexOf(value) == -1 ? '' : 'walk-active'
} }
}, },
@@ -98,7 +103,8 @@ export default {
show () { show () {
this.popBox.show = true this.popBox.show = true
}, },
hideDetail () { hideDetail (data,num) {
console.log(data,num)
this.tempWalk.detailShow = false this.tempWalk.detailShow = false
}, },
showDetail (data, e) { showDetail (data, e) {

View File

@@ -113,7 +113,11 @@
<div style="width: 100%;display: flex;justify-content: space-between" v-if="!editTopologyFlag&&!fromOverView"> <div style="width: 100%;display: flex;justify-content: space-between" v-if="!editTopologyFlag&&!fromOverView">
<div>{{topologyInfo.name}}</div> <div>{{topologyInfo.name}}</div>
<span class="edit-topologyLine" style="padding-top: 5px" v-show="!editTopologyFlag&&!fromPrev&&!fromOverView"> <span class="edit-topologyLine" style="padding-top: 5px" v-show="!editTopologyFlag&&!fromPrev&&!fromOverView">
<button @click="changeScreen" class="nz-btn nz-btn-size-normal nz-btn-style-light float-right"
style="border-right: 1px solid rgba(162,162,162,0.50);margin-right: 12px;margin-top: -2px" type="button"
>
<i class="nz-icon" :class="topoScreen?'nz-icon-exit-full-screen':'nz-icon-full-screen'"></i>
</button>
<button @click="editTopology" class="nz-btn nz-btn-size-normal nz-btn-style-light float-right" <button @click="editTopology" class="nz-btn nz-btn-size-normal nz-btn-style-light float-right"
style="border-right: 1px solid rgba(162,162,162,0.50);margin-right: 12px;margin-top: -2px" type="button" style="border-right: 1px solid rgba(162,162,162,0.50);margin-right: 12px;margin-top: -2px" type="button"
> >
@@ -128,12 +132,7 @@
:showTimePicker="false" :showTimePicker="false"
ref="pickTime"> ref="pickTime">
</pick-time> </pick-time>
<button @click="changeScreen" class="nz-btn nz-btn-size-normal nz-btn-style-light float-right"
style="border-right: 1px solid rgba(162,162,162,0.50);margin-right: 12px;margin-top: -2px" type="button"
:class="topoScreen?'':''"
>
<i class="nz-icon nz-icon-edit" :title="$t('project.topology.edit')"></i>
</button>
</span> </span>
</div> </div>
</div> </div>
@@ -758,7 +757,7 @@ export default {
if (this.fromPrev) { if (this.fromPrev) {
resolve(this.topoPrevDataS) resolve(this.topoPrevDataS)
} }
this.$get('/project/topo', { projectId: this.obj.id }).then(res => { this.$get('monitor/project/topo', { projectId: this.obj.id }).then(res => {
let data = res.data.topo let data = res.data.topo
if (!res.data.topo || !data.pens) { if (!res.data.topo || !data.pens) {
data = { data = {
@@ -806,9 +805,17 @@ export default {
item.image = this.iconArray.find(item1 => item1.id == item.data.imageId).image item.image = this.iconArray.find(item1 => item1.id == item.data.imageId).image
} }
if (item.type === 0) { if (item.type === 0) {
promiseArr.push(this.$get('/module/stat', { id: item.data.moduleId })) // promiseArr.push(this.$get('/monitor/module/stat', { id: item.data.moduleId }))
item.data.state = {}
item.data.state.asset = false
item.data.state.endpoint = false
item.data.state.alert = false
} else { } else {
promiseArr.push({ type: 1 }) // promiseArr.push({ type: 1 })
item.data.state = {}
item.data.state.asset = false
item.data.state.endpoint = false
item.data.state.alert = false
} }
}) })
@@ -1547,11 +1554,11 @@ export default {
form.append('name', this.file.name.substring(0, this.file.name.lastIndexOf('.'))) form.append('name', this.file.name.substring(0, this.file.name.lastIndexOf('.')))
} }
form.append('unit', this.uploadPic.unit) form.append('unit', this.uploadPic.unit)
this.$post('/project/topo/icon', form, { 'Content-Type': 'multipart/form-data' }).then(res => { this.$post('monitor/project/topo/icon', form, { 'Content-Type': 'multipart/form-data' }).then(res => {
if (res.code == 200) { if (res.code == 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') }) this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.uploadPicShow = false this.uploadPicShow = false
this.dealImg(`/project/topo/icon/${res.data.id}`).then((data) => { this.dealImg(`monitor/project/topo/icon/${res.data.id}`).then((data) => {
const group = this.tools.find(tool => tool.group === this.uploadPic.unit) const group = this.tools.find(tool => tool.group === this.uploadPic.unit)
if (group) { if (group) {
group.children.push({ group.children.push({
@@ -1587,7 +1594,7 @@ export default {
}, },
delImg (item) { delImg (item) {
this.$delete('/project/topo/icon?ids=' + item.data.imageId).then(res => { this.$delete('monitor/project/topo/icon?ids=' + item.data.imageId).then(res => {
if (res.code == 200) { if (res.code == 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') }) this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
this.addNodeInit() this.addNodeInit()
@@ -1599,7 +1606,7 @@ export default {
addNodeInit (imgidList) { addNodeInit (imgidList) {
if (!this.fromOverView) { if (!this.fromOverView) {
this.$get('/project/topo/icon').then(res => { this.$get('monitor/project/topo/icon').then(res => {
this.imgageLoading = true this.imgageLoading = true
// this.tools[1].children=[]; // this.tools[1].children=[];
const imgArr = [] const imgArr = []
@@ -1607,7 +1614,7 @@ export default {
res.data.list.forEach((item, index) => { res.data.list.forEach((item, index) => {
item.imageName = item.name item.imageName = item.name
delete item.name delete item.name
promiseArr.push(this.dealImg(`/project/topo/icon/${item.id}`)) promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}`))
imgArr.push({ ...item }) imgArr.push({ ...item })
}) })
Promise.all(promiseArr).then((res2) => { Promise.all(promiseArr).then((res2) => {
@@ -1651,7 +1658,7 @@ export default {
const promiseArr = [] const promiseArr = []
imgidList.forEach((item, index) => { imgidList.forEach((item, index) => {
if (item.data.imageId) { if (item.data.imageId) {
promiseArr.push(this.dealImg(`/project/topo/icon/${item.data.imageId}`)) promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.data.imageId}`))
} else { } else {
promiseArr.push('') promiseArr.push('')
} }
@@ -1832,7 +1839,7 @@ export default {
if (this.penToolTipScale == getTopology(this.topologyIndex).data.scale) { if (this.penToolTipScale == getTopology(this.topologyIndex).data.scale) {
getTopology(this.topologyIndex).data.scale = this.oldScale getTopology(this.topologyIndex).data.scale = this.oldScale
} }
this.$put('/project/topo', { topo: JSON.stringify(topologyData), projectId: this.projectInfo.id }).then(res => { this.$put('monitor/project/topo', { topo: JSON.stringify(topologyData), projectId: this.projectInfo.id }).then(res => {
this.prevent_opt.save = false this.prevent_opt.save = false
if (res.code === 200) { if (res.code === 200) {
this.$message({ this.$message({

View File

@@ -797,7 +797,7 @@
if (this.fromPrev) { if (this.fromPrev) {
resolve(this.topoPrevDataS) resolve(this.topoPrevDataS)
} }
this.$get('/project/topo', { projectId: this.obj.id }).then(res => { this.$get('monitor/project/topo', { projectId: this.obj.id }).then(res => {
let data = res.data.topo let data = res.data.topo
if (!res.data.topo || !data.pens) { if (!res.data.topo || !data.pens) {
data = { data = {
@@ -1587,11 +1587,11 @@
form.append('name', this.file.name.substring(0, this.file.name.lastIndexOf('.'))) form.append('name', this.file.name.substring(0, this.file.name.lastIndexOf('.')))
} }
form.append('unit', this.uploadPic.unit) form.append('unit', this.uploadPic.unit)
this.$post('/project/topo/icon', form, { 'Content-Type': 'multipart/form-data' }).then(res => { this.$post('monitor/project/topo/icon', form, { 'Content-Type': 'multipart/form-data' }).then(res => {
if (res.code == 200) { if (res.code == 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') }) this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.uploadPicShow = false this.uploadPicShow = false
this.dealImg(`/project/topo/icon/${res.data.id}`).then((data) => { this.dealImg(`monitor/project/topo/icon/${res.data.id}`).then((data) => {
const group = this.tools.find(tool => tool.group === this.uploadPic.unit) const group = this.tools.find(tool => tool.group === this.uploadPic.unit)
if (group) { if (group) {
group.children.push({ group.children.push({
@@ -1627,7 +1627,7 @@
}, },
delImg (item) { delImg (item) {
this.$delete('/project/topo/icon?ids=' + item.data.imageId).then(res => { this.$delete('monitor/project/topo/icon?ids=' + item.data.imageId).then(res => {
if (res.code == 200) { if (res.code == 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') }) this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
this.addNodeInit() this.addNodeInit()
@@ -1639,7 +1639,7 @@
addNodeInit (imgidList) { addNodeInit (imgidList) {
if (!this.fromOverView) { if (!this.fromOverView) {
this.$get('/project/topo/icon').then(res => { this.$get('monitor/project/topo/icon').then(res => {
this.imgageLoading = true this.imgageLoading = true
// this.tools[1].children=[]; // this.tools[1].children=[];
const imgArr = [] const imgArr = []
@@ -1647,7 +1647,7 @@
res.data.list.forEach((item, index) => { res.data.list.forEach((item, index) => {
item.imageName = item.name item.imageName = item.name
delete item.name delete item.name
promiseArr.push(this.dealImg(`/project/topo/icon/${item.id}`)) promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}`))
imgArr.push({ ...item }) imgArr.push({ ...item })
}) })
Promise.all(promiseArr).then((res2) => { Promise.all(promiseArr).then((res2) => {
@@ -1691,7 +1691,7 @@
const promiseArr = [] const promiseArr = []
imgidList.forEach((item, index) => { imgidList.forEach((item, index) => {
if (item.data.imageId) { if (item.data.imageId) {
promiseArr.push(this.dealImg(`/project/topo/icon/${item.data.imageId}`)) promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.data.imageId}`))
} else { } else {
promiseArr.push('') promiseArr.push('')
} }
@@ -1872,7 +1872,7 @@
if (this.penToolTipScale == getTopology(this.topologyIndex).data.scale) { if (this.penToolTipScale == getTopology(this.topologyIndex).data.scale) {
getTopology(this.topologyIndex).data.scale = this.oldScale getTopology(this.topologyIndex).data.scale = this.oldScale
} }
this.$put('/project/topo', { topo: JSON.stringify(topologyData), projectId: this.projectInfo.id }).then(res => { this.$put('monitor/project/topo', { topo: JSON.stringify(topologyData), projectId: this.projectInfo.id }).then(res => {
this.prevent_opt.save = false this.prevent_opt.save = false
if (res.code === 200) { if (res.code === 200) {
this.$message({ this.$message({

View File

@@ -16,27 +16,40 @@
<!-- begin--表单--> <!-- begin--表单-->
<div class="right-box-form-box" ref="scrollbar"> <div class="right-box-form-box" ref="scrollbar">
<el-form class="right-box-form right-box-form-left" :model="editModule" label-position = "top" label-width="120px" :rules="rules" ref="moduleForm"> <el-form class="right-box-form right-box-form-left" :model="editModule" label-position = "top" label-width="120px" :rules="rules" ref="moduleForm">
<el-form-item :label='$t("project.project.project")' prop="project"> <!--name-->
<el-select value-key="id" popper-class="config-dropdown" v-model="editModule.project" placeholder="" size="small" id="module-box-input-project">
<el-option :id="'module-project-'+item.id" v-for="item in projectList" :key="item.id" :label="item.name" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item :label='$t("project.module.moduleName")' prop="name" label-width="125px"> <el-form-item :label='$t("project.module.moduleName")' prop="name" label-width="125px">
<el-input placeholder="" maxlength="64" show-word-limit v-model="editModule.name" size="small" id="module-box-input-name"></el-input> <el-input placeholder="" maxlength="64" show-word-limit v-model="editModule.name" size="small" id="module-box-input-name"></el-input>
</el-form-item> </el-form-item>
<!--project-->
<el-form-item :label='$t("project.project.project")' prop="projectId">
<el-select value-key="id" popper-class="config-dropdown" v-model="editModule.projectId" placeholder="" size="small" id="module-box-input-project">
<el-option :id="'module-project-'+item.id" v-for="item in projectList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<!--remark-->
<el-form-item :label='$t("project.module.description")' prop="remark">
<el-input
type="textarea"
placeholder=""
maxlength="1024"
v-model="editModule.remark"
size="small"
:autosize="{ minRows: 1, maxRows: 6}"
class="not-fixed-height no-resize"
id="module-box-input-remark"></el-input>
</el-form-item>
<div class="nz-tab module-box-type" style="margin-bottom: 15px;"> <!--type-->
<div class="nz-tab-item-box" @click="changeType('http')" id="module-type-1"> <el-form-item :label='$t("project.endpoint.type")' prop="type">
<div class="nz-tab-item" :class="{'nz-tab-item-active' : editModule.type.toLowerCase() == 'http', 'unclickable': editModule.id}">HTTP</div> <el-select value-key="id" popper-class="config-dropdown" v-model="editModule.type" placeholder="" size="small" id="module-box-input-type" :disabled="!!editModule.id" @change="changeAuthType">
</div> <el-option :id="'module-type-'+item.id" v-for="item in typetList" :key="item.value" :label="item.name" :value="item.value"></el-option>
<div @click="changeType('snmp')" class="nz-tab-item-box" id="module-type-2"> </el-select>
<div class="nz-tab-item" :class="{'nz-tab-item-active' : editModule.type.toLowerCase() == 'snmp', 'unclickable': editModule.id}">SNMP</div> </el-form-item>
</div>
</div>
<!-- snmp表单 --> <!-- snmp表单 -->
<span class="snmp-form" v-if="editModule.type && editModule.type == 'snmp'"> <span class="snmp-form" v-if="editModule.type && editModule.type == 'snmp'">
<div class="right-box-sub-title">SNMP settings</div> <div class="right-box-sub-title">SNMP settings
</div>
<div class="right-box-line"></div> <div class="right-box-line"></div>
<el-row> <el-row>
@@ -67,207 +80,69 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<!--credentials-->
<el-row> <el-form-item :label='$t("project.endpoint.credentials")' prop="credentials">
<el-col :span="6"> <el-select value-key="id" popper-class="config-dropdown" v-model="editModule.configs.snmpCredentialsId" placeholder="" size="small" id="module-box-input-credentials">
<div class="sub-label">{{$t('project.module.version')}}</div> <el-option :id="'module-type-'+item.id" v-for="item in credentialList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-col> </el-select>
<el-col :span="24">
<el-form-item prop="version">
<el-radio-group v-model.number="editModule.version" size="small" id="module-box-input-version">
<el-radio-button :label="2"></el-radio-button>
<el-radio-button :label="3"></el-radio-button>
</el-radio-group>
</el-form-item> </el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<div class="sub-label">{{$t('project.module.maxRepetitions')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="max_repetitions">
<el-input v-model.number="editModule.max_repetitions" size="small" id="module-box-input-max_repetitions"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<div class="sub-label">{{$t('project.module.retries')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="retries">
<el-input v-model.number="editModule.retries" size="small" id="module-box-input-retries"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<div class="sub-label">{{$t('project.module.timeout')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="timeout">
<el-input v-model.number="editModule.timeout" size="small" id="module-box-input-timeout">
<template slot="append">second</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<div class="right-box-sub-title">Auth</div>
<div class="right-box-line"></div>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<div class="sub-label sub-label-required">{{$t('project.module.community')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="community">
<el-input v-model.trim="editModule.community" maxlength="64" show-word-limit size="small" id="module-box-input-community"></el-input>
</el-form-item>
</el-col>
</el-row>
<!--SNMP V3 setting-->
<template v-if="editModule.version == 3">
<el-row>
<el-col :span="6">
<div class="sub-label sub-label-required">{{$t('login.username')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="username">
<el-input v-model.trim="editModule.username" maxlength="64" show-word-limit size="small" id="module-box-input-username"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<div class="sub-label">{{$t('project.module.securityLevel')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="security_level">
<el-radio-group size="small" v-model="editModule.security_level" id="module-box-input-security_level">
<el-radio-button label="noAuthNoPriv"></el-radio-button>
<el-radio-button label="authNoPriv"></el-radio-button>
<el-radio-button label="authPriv"></el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="editModule.security_level == 'authNoPriv' || editModule.security_level == 'authPriv'">
<el-col :span="6">
<div class="sub-label sub-label-required">{{$t('login.password')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="password">
<el-input v-model.trim="editModule.password" type="password" show-password maxlength="64" show-word-limit size="small" id="module-box-input-password"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row class="same-label-width" v-if="editModule.security_level == 'authNoPriv' || editModule.security_level == 'authPriv'">
<el-col :span="6">
<div class="sub-label">{{$t('project.module.authProtocol')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="auth_protocol">
<el-radio-group v-model="editModule.auth_protocol" size="small" id="module-box-input-auth_protocol">
<el-radio-button label="MD5"></el-radio-button>
<el-radio-button label="SHA"></el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row class="same-label-width" v-if="editModule.security_level == 'authPriv'">
<el-col :span="6">
<div class="sub-label">{{$t('project.module.privProtocol')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="priv_protocol">
<el-radio-group v-model="editModule.priv_protocol" size="small" id="module-box-input-priv_protocol">
<el-radio-button label="DES"></el-radio-button>
<el-radio-button label="AES"></el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="editModule.security_level == 'authPriv'">
<el-col :span="6">
<div class="sub-label sub-label-required">{{$t('project.module.privPassword')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="priv_password">
<el-input v-model.trim="editModule.priv_password" type="password" show-password maxlength="64" show-word-limit size="small" id="module-box-input-priv_password"></el-input>
</el-form-item>
</el-col>
</el-row>
</template>
<el-row v-if="editModule.version == 3">
<el-col :span="6">
<div class="sub-label">{{$t('project.module.contextName')}}</div>
</el-col>
<el-col :span="24">
<el-form-item prop="context_name">
<el-input v-model.trim="editModule.context_name" maxlength="64" show-word-limit size="small" id="module-box-input-context_name"></el-input>
</el-form-item>
</el-col>
</el-row>
</span> </span>
<div class="right-box-form-tip" :style="{'margin-bottom': '15px','margin-left':editModule.type.toLowerCase()=='snmp'?'15px':'0'}"> <!--Enpoint template-->
<div class="right-box-sub-title">Enpoint template
<el-tooltip placement="top" effect="light">
<div slot="content">
{{$t('project.module.tip.defaultEndpointSet')}} {{$t('project.module.tip.defaultEndpointSet')}}
<div></div> <div></div>
{{$t('project.module.tip.relation')}} {{$t('project.module.tip.relation')}}
</div> </div>
<i class="nz-icon nz-icon-info-normal"></i>
</el-tooltip>
</div>
<div class="right-box-line"></div>
<el-form-item :label='$t("project.endpoint.port")' prop="port" > <el-tabs v-model="activeName">
<el-tab-pane label="Basic" name="Basic">
<!--path-->
<el-form-item :label='$t("project.endpoint.path")' prop="configs.metrics_path" class="half-form-item">
<el-input placeholder="" v-model="editModule.configs.metrics_path" size="small" id="module-box-input-path"></el-input>
</el-form-item>
<!--port-->
<el-form-item :label='$t("project.endpoint.port")' prop="port" class="half-form-item">
<el-input placeholder="" v-model.number="editModule.port" size="small" id="module-box-input-port"></el-input> <el-input placeholder="" v-model.number="editModule.port" size="small" id="module-box-input-port"></el-input>
</el-form-item> </el-form-item>
<!--name pattern-->
<el-form-item v-if="editModule.type && editModule.type.toLowerCase() == 'http'" :label='$t("project.endpoint.path")' prop="path"> <el-form-item :label='$t("project.endpoint.pattern")' prop="pattern" class="half-form-item">
<el-input placeholder="" v-model="editModule.path" size="small" id="module-box-input-path"></el-input> <!-- <el-input placeholder="" v-model=""></el-input>-->
<el-autocomplete
class="inline-input"
size="small"
id="module-box-input-pattern"
v-model="editModule.endpointNameTmpl"
:fetch-suggestions="querySearch"
placeholder="请输入内容"
></el-autocomplete>
</el-form-item> </el-form-item>
<!--host-->
<el-form-item :label="$t('project.endpoint.param')" class="right-box-form-param label-position" v-if="editModule.type.toLowerCase() == 'http'"> <el-form-item :label='$t("project.endpoint.host")' prop="host" class="half-form-item">
<el-input placeholder="" v-model.number="editModule.configs.host" size="small" id="module-box-input-host"></el-input>
<div style="text-align: right;margin-bottom: 5px">
<button style="display: none;">第一个button会出现意料之外的hover样式找不到原因只好加个不可见的button规避问题</button>
<!--<button id="module-clear-all" type="button" @click="clearAllParam" class="nz-btn nz-btn-size-normal nz-btn-style-light">-->
<!--<span><i class="nz-icon nz-icon-delete"></i></span>-->
<!--</button>-->
<span id="module-add-param" type="button" @click="addParam" class="right-box-form-add">
<span><i style="font-size: 16px;" class="nz-icon nz-icon-create-square"></i></span>
</span>
</div>
<div class="param-box param-box-module">
<div style="height: 100%; overflow: auto;" id="module-box-params">
<div v-for="(item, index) in editModule.paramObj" :key="index" class="param-box-row">
<el-form-item class="param-box-row-key" :rules="{required: true, message: $t('validate.required'), trigger: 'blur'}" :prop="'paramObj.' + index + '.key'">
<el-input placeholder="key" size="mini" v-model="item.key" ></el-input>
</el-form-item> </el-form-item>
<span class="param-box-row-eq">=</span> <transition name="el-zoom-in-top">
<el-form-item class="param-box-row-value" :rules="{required: true, message: $t('validate.required'), trigger: 'blur'}" :prop="'paramObj.' + index + '.value'"> <div v-show="showAllBasicOption" >
<el-input placeholder="value" size="mini" v-model="item.value"></el-input> <!--scrape_interval-->
<el-form-item :label='$t("project.endpoint.scrape_interval")' prop="scrape_interval" class="half-form-item">
<el-input :placeholder='$t("project.endpoint.scrape_interval_placeholder")' v-model.number="editModule.configs.scrape_interval" size="small" id="module-box-input-scrape_interval"></el-input>
</el-form-item> </el-form-item>
<span class="param-box-row-symbol" :id="'moduel-remove-param-'+index" @click="removeParam(index)"><i class="nz-icon nz-icon-shanchu1" style="color:#666;"></i></span> <!--scrape_timeout-->
</div> <el-form-item :label='$t("project.endpoint.scrape_timeout")' prop="scrape_timeout" class="half-form-item">
</div> <el-input :placeholder='$t("project.endpoint.scrape_timeout_placeholder")' v-model.number="editModule.configs.scrape_timeout" size="small" id="module-box-input-scrape_timeout"></el-input>
</div>
</el-form-item> </el-form-item>
</div>
</transition>
<div style="text-align: center"><i class="nz-icon nz-icon-drop-down need-rotate" :class="showAllBasicOption?'is-active':''" @click="showAllBasicOption=!showAllBasicOption"></i></div>
</el-tab-pane>
<el-tab-pane label="Labels" name="Labels">
<el-form-item :label="$t('project.endpoint.labels')" class="right-box-form-param label-position"> <el-form-item :label="$t('project.endpoint.labels')" class="right-box-form-param label-position">
<div style="text-align: right;margin-bottom: 5px"> <div style="text-align: right;margin-bottom: 5px">
@@ -282,7 +157,7 @@
<div class="param-box param-box-module"> <div class="param-box param-box-module">
<div ref="labelBoxScrollbar" style="height: 100%; overflow: auto;" id="module-box-labels"> <div ref="labelBoxScrollbar" style="height: 100%; overflow: auto;" id="module-box-labels">
<div v-for="(item, index) in editModule.labelModule" :key="index" class="param-box-row"> <div v-for="(item, index) in editModule.configs.labelModule" :key="index" class="param-box-row">
<el-form-item class="param-box-row-key" :rules="[{required: true, message: $t('validate.required'), trigger: 'blur'},{ pattern: /[a-zA-Z_:][a-zA-Z0-9_:]*/, message: $t('validate.key') ,trigger: 'blur'}]" :prop="'labelModule.' + index + '.key'"> <el-form-item class="param-box-row-key" :rules="[{required: true, message: $t('validate.required'), trigger: 'blur'},{ pattern: /[a-zA-Z_:][a-zA-Z0-9_:]*/, message: $t('validate.key') ,trigger: 'blur'}]" :prop="'labelModule.' + index + '.key'">
<el-input placeholder="key" size="mini" v-model="item.key"></el-input> <el-input placeholder="key" size="mini" v-model="item.key"></el-input>
</el-form-item> </el-form-item>
@@ -295,11 +170,68 @@
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
</el-tab-pane>
<el-tab-pane label="Parameter" name="Parameter">
<el-form-item :label="$t('project.endpoint.param')" class="right-box-form-param label-position">
<el-form-item :label='$t("project.module.description")' prop="remark"> <div style="text-align: right;margin-bottom: 5px">
<el-input type="textarea" placeholder="" maxlength="1024" show-word-limit v-model="editModule.remark" size="small" id="module-box-input-project"></el-input> <button style="display: none;">第一个button会出现意料之外的hover样式找不到原因只好加个不可见的button规避问题</button>
<!--<button id="module-clear-all" type="button" @click="clearAllParam" class="nz-btn nz-btn-size-normal nz-btn-style-light">-->
<!--<span><i class="nz-icon nz-icon-delete"></i></span>-->
<!--</button>-->
<span id="module-add-param" type="button" @click="addParam" class="right-box-form-add">
<span><i style="font-size: 16px;" class="nz-icon nz-icon-create-square"></i></span>
</span>
</div>
<div class="param-box param-box-module">
<div style="height: 100%; overflow: auto;" id="module-box-params">
<div v-for="(item, index) in editModule.configs.paramObj" :key="index" class="param-box-row">
<el-form-item class="param-box-row-key" :rules="{required: true, message: $t('validate.required'), trigger: 'blur'}" :prop="'paramObj.' + index + '.key'">
<el-input placeholder="key" size="mini" v-model="item.key" ></el-input>
</el-form-item>
<span class="param-box-row-eq">=</span>
<el-form-item class="param-box-row-value" :rules="{required: true, message: $t('validate.required'), trigger: 'blur'}" :prop="'paramObj.' + index + '.value'">
<el-input placeholder="value" size="mini" v-model="item.value"></el-input>
</el-form-item>
<span class="param-box-row-symbol" :id="'moduel-remove-param-'+index" @click="removeParam(index)"><i class="nz-icon nz-icon-shanchu1" style="color:#666;"></i></span>
</div>
</div>
</div>
</el-form-item>
</el-tab-pane>
<el-tab-pane label="Auth" name="Auth" v-if="editModule.type !== 'snmp'">
<!--authtype-->
<el-form-item :label='$t("project.endpoint.type")' prop="authtype">
<el-select @change="changeAuthType" value-key="id" popper-class="config-dropdown" v-model="authType" placeholder="" size="small" id="module-box-input-auth-type">
<el-option :id="'module-type-'+item.id" v-for="item in authTypeList" :key="item.value" :label="item.name" :value="item.value"></el-option>
</el-select>
</el-form-item> </el-form-item>
<!--authtype 1-->
<el-form-item :label='$t("project.endpoint.username")' prop="authtype" v-if="authType === 1" class="half-form-item">
<el-input placeholder='' v-model.number="editModule.configs.basic_auth.username" size="small" id="module-box-input-uername"></el-input>
</el-form-item>
<el-form-item :label='$t("project.endpoint.password")' prop="authtype" v-if="authType === 1" class="half-form-item">
<el-input placeholder='' v-model.number="editModule.configs.basic_auth.password" size="small" id="module-box-input-password"></el-input>
</el-form-item>
<!--authtype 2-->
<el-form-item :label='$t("project.endpoint.bearer_token")' prop="authtype" v-if="authType === 2">
<el-input placeholder='' v-model.number="editModule.configs.bearer_token" size="small" id="module-box-input-bearer_token"></el-input>
</el-form-item>
</el-tab-pane>
</el-tabs>
<div>
asd
</div>
<div class="right-box-form-tip" :style="{'margin-bottom': '15px','margin-left':editModule.type.toLowerCase()=='snmp'?'15px':'0'}">
</div>
</el-form> </el-form>
</div> </div>
@@ -331,14 +263,21 @@ export default {
data () { data () {
return { return {
walkData: [], walkData: [],
activeName: 'Basic',
expandedWalkData: [], expandedWalkData: [],
radio: 'password',
editModule: {}, editModule: {},
restaurants: [
{ value: '{{module.name}}-{{asset.name}}' },
{ value: '{{module.name}}-{{asset.manageIp}}' }
],
showAllBasicOption: false,
rules: { rules: {
name: [ name: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ validator: noSpecialChar, trigger: 'change' } { validator: noSpecialChar, trigger: 'change' }
], ],
project: [ projectId: [
{ required: true, message: this.$t('validate.required'), trigger: 'change' } { required: true, message: this.$t('validate.required'), trigger: 'change' }
], ],
walk: [ walk: [
@@ -366,7 +305,24 @@ export default {
{ validator: nzNumber, trigger: 'blur' } { validator: nzNumber, trigger: 'blur' }
] ]
}, },
projectList: [] projectList: [],
credentialList: [],
typetList: [
{
value: 'http',
name: 'HTTP'
},
{
value: 'snmp',
name: 'SNMP'
}
],
authType: 0,
authTypeList: [
{ name: this.$t('project.endpoint.authTypeNull'), value: 0 },
{ name: this.$t('project.endpoint.authTypeWord'), value: 1 },
{ name: this.$t('project.endpoint.authTypeToken'), value: 2 }
]
} }
}, },
methods: { methods: {
@@ -437,11 +393,13 @@ export default {
this.$get('mib/tree', { pageSize: -1, pageNo: 1 }).then(response => { this.$get('mib/tree', { pageSize: -1, pageNo: 1 }).then(response => {
if (response.code === 200) { if (response.code === 200) {
const obj = JSON.parse(response.data) const obj = JSON.parse(response.data)
console.log(obj)
this.walkData = [] this.walkData = []
for (const item in obj) { for (const item in obj) {
setAttr(obj[item], 'detailShow', false) setAttr(obj[item], 'detailShow', false)
this.walkData.push({ name: item, detailShow: false, subTree: obj[item] }) this.walkData.push({ name: item, detailShow: false, subTree: obj[item] })
} }
console.log(this.walkData)
} }
}) })
function setAttr (tree, name, value) { function setAttr (tree, name, value) {
@@ -478,79 +436,26 @@ export default {
this.editModule.port = 161 this.editModule.port = 161
} }
}, },
// 转化snmpParam属性
parseSnmpParam (module) {
const snmpObj = { // 下划线命名是因为业务需求
walk: module.walk,
version: module.version, // 2/3
max_repetitions: module.max_repetitions ? module.max_repetitions : 25,
retries: module.retries ? module.retries : 3,
timeout: module.timeout ? module.timeout + 's' : '10s', // s
auth: {
community: module.community
}
}
if (module.version == 3) {
snmpObj.auth.username = module.username
snmpObj.auth.security_level = module.security_level
snmpObj.auth.context_name = module.context_name
}
if (module.security_level == 'authNoPriv' || module.security_level == 'authPriv') {
snmpObj.auth.password = module.password
snmpObj.auth.auth_protocol = module.auth_protocol
if (module.security_level != 'authNoPriv') {
snmpObj.auth.priv_password = module.priv_password
snmpObj.auth.priv_protocol = module.priv_protocol
}
}
module.snmpParam = JSON.stringify(snmpObj)
},
// 回显时解析snmpParam
reparseSnmpParam (module) {
if (!module.snmpParam) {
return
}
const snmpObj = JSON.parse(module.snmpParam)
module.walk = snmpObj.walk
module.version = snmpObj.version
module.max_repetitions = snmpObj.max_repetitions
module.retries = snmpObj.retries
module.timeout = parseInt(snmpObj.timeout.replace('s', ''))
module.community = snmpObj.auth.community
if (snmpObj.version == 3) {
module.username = snmpObj.auth.username
module.security_level = snmpObj.auth.security_level
module.context_name = snmpObj.auth.context_name
}
if (snmpObj.auth.security_level == 'authNoPriv' || snmpObj.auth.security_level == 'authPriv') {
module.password = snmpObj.auth.password
module.auth_protocol = snmpObj.auth.auth_protocol
if (snmpObj.auth.security_level != 'authNoPriv') {
module.priv_password = snmpObj.auth.priv_password
module.priv_protocol = snmpObj.auth.priv_protocol
}
}
},
/* 保存 */ /* 保存 */
save () { save () {
if (this.editModule.type.toLowerCase() == 'snmp') { this.editModule.configs.param = this.paramToJson(this.editModule.configs.paramObj)
this.editModule.paramObj = []// 处理snmp可能会带有param的问题 this.editModule.configs.labels = this.labelsToJson(this.editModule.configs.labelModule)
const params = { ...this.editModule }
params.configs.walk = params.walk
params.configs.prot = params.prot
params.configs = JSON.stringify(params.configs)
if (this.authType === 2 && !this.editModule.configs.bearer_token) {
this.$message.error("'token' is required")
} else if (this.authType === 1 && !(this.editModule.configs.basic_auth.username && this.editModule.configs.basic_auth.password)) {
this.$message.error("'username' and 'password' is required")
} else {
this.authType = 0
} }
this.editModule.param = this.paramToJson(this.editModule.paramObj)
this.editModule.labels = this.labelsToJson(this.editModule.labelModule)
this.$refs.moduleForm.validate((valid) => { this.$refs.moduleForm.validate((valid) => {
if (valid) { if (valid) {
this.prevent_opt.save = true this.prevent_opt.save = true
if (this.editModule.type.toLowerCase() == 'snmp') {
this.parseSnmpParam(this.editModule)
} else {
if (this.editModule.snmpParam) {
this.editModule.snmpParam = ''
}
}
this.editModule.projectId = this.editModule.project.id
if (this.editModule.id) { if (this.editModule.id) {
this.$put('module', this.editModule).then(response => { this.$put('monitor/module', params).then(response => {
if (response.code === 200) { if (response.code === 200) {
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') }) this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
this.$store.commit('setReloadFacade') this.$store.commit('setReloadFacade')
@@ -561,7 +466,7 @@ export default {
this.prevent_opt.save = false this.prevent_opt.save = false
}) })
} else { } else {
this.$post('module', this.editModule).then(response => { this.$post('monitor/module', params).then(response => {
if (response.code === 200) { if (response.code === 200) {
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') }) this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
this.$store.commit('setReloadFacade') this.$store.commit('setReloadFacade')
@@ -584,7 +489,7 @@ export default {
cancelButtonText: this.$t('tip.no'), cancelButtonText: this.$t('tip.no'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$delete('module?ids=' + this.editModule.id).then(response => { this.$delete('monitor/module?ids=' + this.editModule.id).then(response => {
if (response.code === 200) { if (response.code === 200) {
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.deleteSuccess') }) this.$message({ duration: 1000, type: 'success', message: this.$t('tip.deleteSuccess') })
this.$store.commit('setReloadFacade') this.$store.commit('setReloadFacade')
@@ -598,33 +503,40 @@ export default {
/* 获取project列表 */ /* 获取project列表 */
getProjectList () { getProjectList () {
this.$get('project', { pageSize: -1, pageNo: 1 }).then(response => { this.$get('monitor/project', { pageSize: -1, pageNo: 1 }).then(response => {
if (response.code === 200) { if (response.code === 200) {
this.projectList = response.data.list this.projectList = response.data.list
} }
}) })
}, },
// get snmp
getCredential () {
this.$get('/snmp/credential', { pageSize: -1, pageNo: 1 }).then(response => {
if (response.code === 200) {
this.credentialList = response.data.list
}
})
},
// 清除param // 清除param
clearAllParam () { clearAllParam () {
this.editModule.paramObj = [] this.editModule.configs.paramObj = []
}, },
// 新增param // 新增param
addParam () { addParam () {
this.editModule.paramObj.push({ key: '', value: '' }) this.editModule.configs.paramObj.push({ key: '', value: '' })
}, },
// 移除单个param // 移除单个param
removeParam (index) { removeParam (index) {
this.editModule.paramObj.splice(index, 1) this.editModule.configs.paramObj.splice(index, 1)
}, },
// 新增label // 新增label
addLabel () { addLabel () {
this.editModule.labelModule.push({ key: '', value: '' }) this.editModule.configs.labelModule.push({ key: '', value: '' })
}, },
// 移除单个Label // 移除单个Label
removeLabel (index) { removeLabel (index) {
this.editModule.labelModule.splice(index, 1) this.editModule.configs.labelModule.splice(index, 1)
}, },
// 将param转为json字符串格式 // 将param转为json字符串格式
paramToJson (param) { paramToJson (param) {
@@ -651,6 +563,25 @@ export default {
} else { } else {
return jsonString return jsonString
} }
},
// 输入建议
querySearch (queryString, cb) {
const restaurants = this.restaurants
const results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
// 调用 callback 返回建议列表的数据
cb(results)
},
createFilter (queryString) {
return (restaurant) => {
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
}
},
changeAuthType () {
this.editModule.configs.bearer_token = ''
this.editModule.configs.basic_auth = {
username: '',
password: ''
}
} }
}, },
mounted () { mounted () {
@@ -658,6 +589,7 @@ export default {
}, },
created () { created () {
this.getProjectList() this.getProjectList()
this.getCredential()
}, },
computed: { computed: {
mibName () { mibName () {
@@ -672,16 +604,30 @@ export default {
deep: true, deep: true,
handler (n, o) { handler (n, o) {
this.editModule = JSON.parse(JSON.stringify(n)) this.editModule = JSON.parse(JSON.stringify(n))
if (n.id) { this.activeName = 'Basic'
this.reparseSnmpParam(this.editModule)
if (this.editModule.configs.bearer_token) {
this.authType = 2
} else if (this.editModule.configs.basic_auth.username) {
this.authType = 1
} else { } else {
this.authType = 0
}
if (n.type && n.type.toLowerCase() == 'snmp') { if (n.type && n.type.toLowerCase() == 'snmp') {
this.$refs.selectWalk.show() this.$refs.selectWalk.show()
for (let i = 0; i < this.editModule.walk.length; i++) { for (let i = 0; i < this.editModule.walk.length; i++) {
this.expandedWalkData.push(this.editModule.walk[i].substring(0, this.editModule.walk[i].lastIndexOf('.'))) this.expandedWalkData.push(this.editModule.configs.walk[i].substring(0, this.editModule.configs.walk[i].lastIndexOf('.')))
}
} }
} }
// if (n.id) {
// } else {
// if (n.type && n.type.toLowerCase() == 'snmp') {
// this.$refs.selectWalk.show()
// for (let i = 0; i < this.editModule.walk.length; i++) {
// this.expandedWalkData.push(this.editModule.walk[i].substring(0, this.editModule.walk[i].lastIndexOf('.')))
// }
// }
// }
} }
} }
} }
@@ -733,6 +679,40 @@ export default {
color: #999999; color: #999999;
line-height: 21px; line-height: 21px;
} }
.half-form-item {
width: calc(50% - 30px);
display: inline-block;
padding: 0 18px 0 8px;
}
/deep/ .el-tabs__item{
width: 90px;
padding: 0;
text-align: center;
}
/deep/ .el-tabs__item.is-active{
color: #FA901C
}
/deep/ .el-tabs__active-bar{
background-color: #FA901C
}
/deep/ .el-radio-group{
width: 100%;
}
/deep/ .el-radio{
width: 100%;
}
/deep/ .el-autocomplete{
width: 100%;
}
.need-rotate.nz-icon-drop-down{
display: inline-block;
transition: transform .3s;
}
.need-rotate.nz-icon-drop-down.is-active{
transform: rotate(
-180deg
);
}
</style> </style>
<style> <style>
.sub-label { .sub-label {

View File

@@ -0,0 +1,137 @@
<template>
<el-table
id="userTable"
ref="dataTable"
:data="tableData"
:height="height"
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 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 === 'name'">
{{scope.row[item.prop]}}
</template>
<template v-else-if="item.prop === 'type'">
{{scope.row[item.prop]}}
</template>
<template v-else-if="item.prop === 'project'">
{{scope.row[item.prop].name}}
</template>
<template v-else-if="item.prop === 'endpointNum'">
{{scope.row[item.prop]}}
</template>
<template v-else-if="item.prop === 'alertNum'">
{{scope.row[item.prop]}}
</template>
<span v-else>{{scope.row[item.prop] ? 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">
<button class="table-operation-item" @click="showBottomBox( 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]"><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, `sys/user?ids=${scope.row.id}`]" :disabled="scope.row.id === 1"><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: 'userTable',
mixins: [table],
data () {
return {
tableTitle: [ // 原始table列
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('project.module.moduleName'),
prop: 'name',
show: true,
width: 150
}, {
label: this.$t('project.module.type'),
prop: 'type',
show: true,
width: 150
}, {
label: this.$t('project.project.project'),
prop: 'project',
show: true,
width: 150
},
{
label: this.$t('project.endpoint.endpoint'),
prop: 'endpointNum',
show: true,
width: 150
},{
label: this.$t('project.module.alerts'),
prop: 'alertNum',
show: true,
width: 150
},
{
label: this.$t('overall.remark'),
prop: 'remark',
show: true,
minWidth: 150
}
]
}
},
methods: {
showBottomBox (project) {
this.$store.commit('currentProjectChange', project)
},
},
computed: {
isCurrentUser () {
return function (username) {
return localStorage.getItem('nz-username') === username
}
}
}
}
</script>

View File

@@ -432,7 +432,7 @@ export default {
this.topologyLoading = false this.topologyLoading = false
} }
res.data.list.forEach((item) => { res.data.list.forEach((item) => {
axiosAll.push(axios.get(`/project/topo?projectId=${item.id}`)) axiosAll.push(axios.get(`monitor/project/topo?projectId=${item.id}`))
}) })
axios.all(axiosAll).then(res2 => { axios.all(axiosAll).then(res2 => {
res2 = res2.map((item, index) => { res2 = res2.map((item, index) => {
@@ -460,7 +460,7 @@ export default {
this.$get('/module/stat', { id: item.id }).then(res => { this.$get('/module/stat', { id: item.id }).then(res => {
item.state = res.data item.state = res.data
}) })
promiseArr.push(this.dealImg(`/project/topo/icon/${item.iconId}`)) promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.iconId}`))
}) })
Promise.all(promiseArr).then(res => { Promise.all(promiseArr).then(res => {
arr.forEach((item, index) => { arr.forEach((item, index) => {

View File

@@ -0,0 +1,125 @@
<template>
<div class="module-list">
<nz-data-list
ref="dataList"
:api="url"
:custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.user"
:layout="['searchInput', 'elementSet']"
:search-msg="searchMsg">
<template v-slot:top-tool-right>
<button id="account-add" v-has="'monitor_module_add'" :title="$t('overall.createUser')" class="top-tool-btn margin-l-20"
type="button" @click="add">
<i class="nz-icon-create-square nz-icon"></i>
</button>
<delete-button id="account-list-batch-delete" v-has="'monitor_module_delete'" :api="url" :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true"></delete-button>
</template>
<template v-slot="slotProps">
<module-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"
@showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"></module-table>
</template>
<template v-slot:pagination>
<div class="module-page">
<Pagination ref="Pagination" :page-obj="pageObj" :table-id="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
</div>
</template>
</nz-data-list>
<transition name="right-box">
<moduleBox v-if="rightBox.show" :module="object" @close="closeRightBox"></moduleBox>
</transition>
</div>
</template>
<script>
import deleteButton from '@/components/common/deleteButton'
import moduleBox from '@/components/common/rightBox/moduleBox'
import nzDataList from '@/components/common/table/nzDataList'
import dataListMixin from '@/components/common/mixin/dataList'
import moduleTable from '@/components/common/table/settings/moduleTable'
export default {
name: 'moduleList',
components: {
nzDataList,
moduleBox,
deleteButton,
moduleTable
},
mixins: [dataListMixin],
data () {
return {
url: 'monitor/module',
blankObject: {
id: '',
projectId: '',
name: '',
endpointNameTmpl: '{{module.name}}-{{asset.name}}',
endpointHostTmpl: '',
type: 'http',
port: 9100,
configs: {
scrape_interval: '',
scrape_timeout: '',
metrics_path: '',
basic_auth: {
username: '',
password: ''
},
bearer_token: '',
labels: '',
params: '',
paramObj: [],
labelModule: [],
walk: [],
host: '{{asset.manageIp}}',
port: '',
snmpCredentialsId: 'public'
},
walk: []
}, // 新增/编辑的module
tableId: 'moduleTable',
queryPermission: 'account_view',
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
id: 10,
name: 'module name',
type: 'input',
label: 'name',
disabled: false
},
{
id: 10,
name: 'module id',
type: 'input',
label: 'id',
disabled: false
}]
},
roles: []
}
},
methods: {
edit (u) {
this.object = JSON.parse(JSON.stringify(u))
this.object.configs = JSON.parse(this.object.configs)
this.object.walk = JSON.parse(this.object.configs.walk)
this.object.port = JSON.parse(this.object.configs.port)
this.rightBox.show = true
},
},
computed: {
},
mounted () {
}
}
</script>

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="main-list"> <div class="main-list">
<projectList :class="showList?'projectList':'hide'" /> <projectList :class="showList?'projectList':'hide'" />
<projectTopo class="projectTopo"/> <projectTopo :class="showList?'projectTopo':'projectTopo ml10'" />
</div> </div>
</template> </template>
@@ -45,5 +45,8 @@ export default {
.hide{ .hide{
display: none; display: none;
} }
.ml10{
margin-left: 10px;
}
} }
</style> </style>

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="'project_toAdd'" :title="$t('overall.createUser')" class="top-tool-btn margin-l-20" <button id="account-add" v-has="'project_add'" :title="$t('overall.createUser')" class="top-tool-btn margin-l-20"
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="'project_delete'" :api="url" :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true"></delete-button>
</template> </template>
<template v-slot="slotProps"> <template v-slot="slotProps">
<project-table <project-table
@@ -47,7 +47,7 @@ import dataListMixin from '@/components/common/mixin/dataList'
import projectTable from '@/components/common/table/settings/projectTable' import projectTable from '@/components/common/table/settings/projectTable'
export default { export default {
name: 'user', name: 'projectList',
components: { components: {
nzDataList, nzDataList,
projectBox, projectBox,

View File

@@ -37,6 +37,10 @@ export default new Router({
path: '/monitor/project', path: '/monitor/project',
component: resolve => require(['../components/page/monitor/project/index.vue'], resolve) component: resolve => require(['../components/page/monitor/project/index.vue'], resolve)
}, },
{
path: '/monitor/module',
component: resolve => require(['../components/page/monitor/module/moduleList.vue'], resolve)
},
{ {
path: '/asset', path: '/asset',
component: resolve => require(['../components/page/asset/asset.vue'], resolve) component: resolve => require(['../components/page/asset/asset.vue'], resolve)