feat: asset相关先提交一部分,公共样式

This commit is contained in:
chenjinsong
2021-04-22 12:25:23 +08:00
parent 16599d1fe2
commit 978049999e
19 changed files with 2093 additions and 975 deletions

View File

@@ -0,0 +1,186 @@
.right-box, .right-sub-box {
display: flex;
flex-direction: column;
position: fixed;
right: 0;
top: 50px;
padding: 0;
height: calc(100% - 50px);
width: 700px;
box-shadow: 0 0 5px #ccc;
background-color: white;
z-index: 410;
.el-date-editor {
.el-input__inner {
padding-left: 32px;
}
}
}
.right-box__header {
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
padding: 0 20px;
border-bottom: 1px solid $--right-box-border-color;
box-sizing: border-box;
.header__title {
font-size: 16px;
font-weight: bold;
color: #333;
}
.header__operation {
i {
color: #999;
font-size: 14px;
}
}
}
.right-box__container {
height: calc(100% - 130px);
padding: 0 30px;
overflow-x: hidden;
overflow-y: auto;
.el-input__inner {
padding: 0 10px;
border-radius: $--primary-border-radius;
border: 1px solid $--right-box-border-color;
}
.el-form {
padding-top: 20px;
.el-form-item {
margin-bottom: 16px;
.el-form-item__label {
padding-bottom: 6px;
font-size: 14px;
line-height: 16px;
color: #666;
}
.el-input__inner:hover {
border-color: darken($--right-box-border-color, 10%);
}
.el-input__inner:focus {
border-color: darken($--right-box-border-color, 20%);
}
}
.el-form-item.is-error .el-input__inner, .el-form-item.is-error .el-input__inner:focus, .el-form-item.is-error .el-textarea__inner, .el-form-item.is-error .el-textarea__inner:focus, .el-message-box__input input.invalid, .el-message-box__input input.invalid:focus {
border-color: #F56C6C
}
.form__sub-title {
padding: 0 10px;
margin-bottom: 20px;
line-height: 32px;
font-size: 14px;
font-weight: bold;
color: #555;
background-color: #F6F6F6;
}
/* 虚线框类型的form-item */
.form__dotted-item {
padding: 10px 10px 6px 10px;
margin-bottom: 10px;
border: 1px dashed $--primary-border-color;
border-radius: $--primary-border-radius;
.el-form-item {
margin-bottom: 0;
.el-form-item__label {
width: 100%;
}
.form__labels-label {
display: flex;
justify-content: space-between;
}
}
}
.form__create-btn {
margin-bottom: 20px;
width: 300px;
height: 28px;
border: 1px solid var(--theme-color-light-71);
border-radius: $--primary-border-radius;
background-color: var(--theme-color-light-98);
i {
color: var(--theme-color);
}
}
.form__flex-container {
display: flex;
justify-content: center;
align-items: center;
}
}
}
.right-box__footer {
display: flex;
align-items: center;
justify-content: center;
height: 70px;
box-shadow: -3px 0 8px -3px rgba(205,205,205,0.77);
.footer__btn {
margin: 0 15px;
height: 30px;
min-width: 74px;
padding: 0 15px;
color: white;
background-color: var(--theme-color);
border: none;
border-radius: 4px;
outline: none;
box-sizing: border-box;
font-size: 14px;
cursor: pointer;
transition: background-color linear .2s, color linear .1s;
}
.footer__btn:hover:not(.footer__btn--disabled) {
background-color: var(--theme-color-light-20);
}
.footer__btn--light {
background-color: white;
border: 1px solid $--primary-border-color;
color: #333;
}
.footer__btn.footer__btn--light:hover:not(.footer__btn--disabled) {
background-color: white;
border-color: var(--theme-color-light-50);
color: var(--theme-color);
}
.footer__btn--disabled {
opacity: .6;
cursor: default;
}
}
/* 隐藏label新增按钮处级联选择器的input */
.hide-casc-input {
position: relative;
.hide-input {
position: absolute;
top: 0;
width: 300px;
opacity: 0;
}
}
.label__multi-text {
display: flex;
justify-content: space-between;
}
.right-box__select {
width: 100%;
}
.right-box-select-dropdown {
width: 625px;
}

View File

@@ -1,11 +1,24 @@
:root { :root {
--theme-color: #FA901C; // 默认主题色 --theme-color: #FA901C; // 默认主题色下方深化、浅化的色值默认值是写死的用户自定义修改主题色后由js计算新值
--theme-color-dark-10: #E18219; // 默认主题色 深10%
--theme-color-light-10: #FA9B33; // 默认主题色 浅10%
--theme-color-light-20: #FBA649; // 默认主题色 浅20%
--theme-color-light-30: #FBB160; // 默认主题色 浅30%
--theme-color-light-40: #FBBC77; // 默认主题色 浅40%
--theme-color-light-50: #FCC88D; // 默认主题色 浅50%
--theme-color-light-60: #FCD4A4; // 默认主题色 浅60%
--theme-color-light-71: #FFDFBD; // 默认主题色 浅71%
--theme-color-light-80: #FFEAD2; // 默认主题色 浅80%
--theme-color-light-90: #FFF5E8; // 默认主题色 浅90%
--theme-color-light-98: #FFFCF8; // 默认主题色 浅98%
} }
$--theme-color: var(--theme-color); // 主题色 $--theme-color: var(--theme-color); // 主题色
$--primary-border-color: #DEDEDE; $--primary-border-color: #DEDEDE;
$--primary-border-radius: 2px; $--primary-border-radius: 2px;
$--right-box-border-color: #E7EAED;
/* 按钮 */ /* 按钮 */
$--button-border-radius: $--primary-border-radius; // 按钮圆角 $--button-border-radius: $--primary-border-radius; // 按钮圆角

View File

@@ -964,32 +964,31 @@ li{
/* end--右侧内容*/ /* end--右侧内容*/
/* begin--右侧弹框*/ /* begin--右侧弹框*/
.right-box, .right-sub-box { /*.right-box, */.right-sub-box {
position: fixed; position: fixed;
top: 50px; top: 50px;
right: 0; right: 0;
z-index: 410; z-index: 410;
box-shadow: 0 0 15px #ccc; box-shadow: 0 0 15px #ccc;
background-color: white; background-color: white;
padding: 0 0 0 15px;
height: calc(100% - 50px); height: calc(100% - 50px);
} }
/*此处自定义弹框尺寸,不同功能可能需要的尺寸不一样,需自行添加*/ /*此处自定义弹框尺寸,不同功能可能需要的尺寸不一样,需自行添加*/
.right-box-menu ,.right-box-role ,.right-box-account, .right-box-prom, .right-box-alert-config, .right-box-project, .right-box-module, .right-box-cabinet, /*.right-box-menu ,.right-box-role ,.right-box-account, .right-box-prom, .right-box-alert-config, .right-box-project, .right-box-module, .right-box-cabinet,
.right-box-edit-endpoint, .right-box-panel, .right-box-dc, .right-box-model, .right-box-mib, .right-box-asset, .right-box-add-chart, .right-box-asset-type, .right-box-edit-endpoint, .right-box-panel, .right-box-dc, .right-box-model, .right-box-mib, .right-box-asset, .right-box-add-chart, .right-box-asset-type,
.right-box-asset-state , .right-box-credential{ .right-box-asset-state , .right-box-credential{
width: 850px; width: 850px;
} }*/
.right-box-chart .el-input__inner, .right-box-chart input { .right-box-chart .el-input__inner, .right-box-chart input {
background-color: white; background-color: white;
} }
.right-box-add-endpoint { /*.right-box-add-endpoint {
width: 850px; width: 850px;
} }
.right-box-add-endpoint.right-box-add-endpoint-snmp { .right-box-add-endpoint.right-box-add-endpoint-snmp {
width: 850px; width: 850px;
} }*/
.snmp-form { .snmp-form {
.el-form-item__content { .el-form-item__content {
margin-left: 10px !important; margin-left: 10px !important;
@@ -1016,12 +1015,6 @@ li{
top: 21px; top: 21px;
transform: translateX(-50%); transform: translateX(-50%);
} }
.right-box .el-input__inner {
background-color: white;
}
.right-box .el-form-item__label {
line-height: 30px;
}
.right-box-line { .right-box-line {
margin-bottom: 18px; margin-bottom: 18px;
background-color: #DCDFE6; background-color: #DCDFE6;

View File

@@ -78,7 +78,54 @@ export const asset = {
{ value: 1, label: i18n.t('asset.inStock') }, { value: 1, label: i18n.t('asset.inStock') },
{ value: 2, label: i18n.t('asset.notInStock') }, { value: 2, label: i18n.t('asset.notInStock') },
{ value: 3, label: i18n.t('asset.suspended') } { value: 3, label: i18n.t('asset.suspended') }
] ],
authProtocolOptions: [
{ value: 0, label: 'Non' },
{ value: 1, label: 'SSH' },
{ value: 2, label: 'TELNET' }
],
authProtocolData: {
non: 0,
ssh: 1,
telnet: 2
},
authTypeOptions: [
{ value: 1, label: 'Username' },
{ value: 2, label: 'Key' }
],
authTypeData: {
username: 1,
key: 2
},
editTypeOptions: [
{ value: 1, label: i18n.t('overall.account') },
{ value: 2, label: 'Label' },
{ value: 3, label: i18n.t('asset.state') },
{ value: 4, label: i18n.t('asset.snmpCredential') }
],
editTypeData: {
account: 1,
label: 2,
state: 3,
snmpCredential: 4
},
labelTypeData: {
TEXT: 'TEXT',
MULTITEXT: 'MULTITEXT',
TEXTAREA: 'TEXTAREA',
RADIO: 'RADIO',
CHECKBOX: 'CHECKBOX',
SELECT: 'SELECT',
INTEGER: 'INTEGER',
DOUBLE: 'DOUBLE',
DATETIME: 'DATETIME',
EMAIL: 'EMAIL'
},
labelSubTypeData: {
date: 'date',
time: 'time',
dateTime: 'dateTime'
}
} }
export const alertMessage = { export const alertMessage = {
@@ -170,6 +217,7 @@ export const fromRoute = {
asset: 'asset', asset: 'asset',
assetType: 'assetType', assetType: 'assetType',
assetState: 'assetState', assetState: 'assetState',
assetLabel: 'assetLabel',
expressionTemplate: 'expressionTemplate', expressionTemplate: 'expressionTemplate',
user: 'user', user: 'user',
agent: 'agent', agent: 'agent',

View File

@@ -23,7 +23,7 @@ export default {
} }
}, },
methods: { methods: {
tableOperation ([command, row]) { tableOperation ([command, row, param]) {
switch (command) { switch (command) {
case 'edit': { case 'edit': {
this.$emit('edit', row) this.$emit('edit', row)
@@ -37,6 +37,14 @@ export default {
this.$emit('showBottomBox', 'record', row) this.$emit('showBottomBox', 'record', row)
break break
} }
case 'cli': {
this.$emit('cli', row)
break
}
case 'copy': {
this.$emit('copy', row)
break
}
default: default:
break break
} }

View File

@@ -0,0 +1,318 @@
<template>
<div class="nz-transfer">
<div :style="calcStyle" class="nz-transfer__box nz-transfer__box--left">
<div class="box__header">
<search-input
ref="searchInput"
:placeholder="$t('overall.placeHolder')"
:search-msg="searchMsg"
:show-history="false"
:show-search="false"
style="width:100%"
@search="search"
></search-input>
</div>
<div class="box__table">
<el-table
v-loading="loading"
:data="selectableData"
:row-class-name="setRowShow"
height="100%"
size="small"
@selection-change="selectableSelectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="36">
</el-table-column>
<el-table-column
:label="$t('overall.name')"
>
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<el-table-column
:label="$t('asset.host')"
>
<template slot-scope="scope">{{scope.row.manageIp}}</template>
</el-table-column>
</el-table>
</div>
<div class="box__footer">
<el-pagination
:current-page.sync="selectablePage.pageNo"
:page-size="selectablePage.pageSize"
:total="selectablePage.total"
layout="prev, slot, next"
small
>
<template>
<el-input ref="jumpInput" v-model="selectablePage.pageNo" class="jump-input" @change="selectableChange" @keyup.enter.native="selectableChange"/>
<span class="jump-pages">/&nbsp{{selectablePage.pages}}</span>
</template>
</el-pagination>
<button :class="{'top-tool-btn--disabled': selectableSelection.length === 0}"
class="top-tool-btn"
type="button"
@click="leftToRight">
<i class="nz-icon nz-icon-arrow-right"></i>
</button>
</div>
</div>
<div :style="calcStyle" class="nz-transfer__box nz-transfer__box--right">
<div class="box__header">
<slot name="title"></slot>
<slot></slot>
</div>
<div class="box__table">
<el-table
:data="selectedData"
height="100%"
size="small"
@selection-change="selectedSelectionChange"
>
<el-table-column
:resizable="false"
align="center"
type="selection"
width="36">
</el-table-column>
<el-table-column
:label="$t('overall.name')"
>
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<el-table-column
:label="$t('asset.host')"
>
<template slot-scope="scope">{{scope.row.host}}</template>
</el-table-column>
</el-table>
</div>
<div class="box__footer">
<button :class="{'top-tool-btn--disabled': selectedSelection.length === 0}"
:disabled="selectedSelection.length === 0"
class="top-tool-btn"
type="button"
@click="rightToLeft">
<i class="nz-icon nz-icon-arrow-left"></i>
</button>
<!-- <el-pagination
:current-page.sync="selectedPage.pageNo"
:page-size="selectedPage.pageSize"
:total="selectedPage.total"
layout="prev, slot, next"
small
>
<template>
<el-input ref="jumpInput" class="jump-input" v-model="selectedPage.pageNo" @change="selectedChange" @keyup.enter.native="selectedChange"/>
<span class="jump-pages">/&nbsp{{selectedPage.pages}}</span>
</template>
</el-pagination>-->
</div>
</div>
</div>
</template>
<script>
export default {
name: 'nzTransfer',
props: {
height: {
type: String,
default: '430'
},
tableData: { // 左侧待选
type: Array
},
searchMsg: {
type: Object
},
pageObj: {
type: Object
}
},
data () {
return {
selectedData: [], // 右侧已选
searchLabel: {},
loading: false,
selectablePage: {},
selectedPage: {
pageSize: 10,
pageNo: 1,
total: 0,
pages: 0
},
selectableSelection: [],
selectedSelection: []
}
},
computed: {
selectableData () {
return this.tableData.filter(d => {
return !this.selectedData.find(s => d.id === s.id)
})
},
calcStyle () {
const style = {}
let height
if (parseInt(this.height)) {
height = `${this.height}px`
} else {
height = this.height
}
style.height = height
return style
}
},
methods: {
search (searchLabel) {
this.searchLabel = { ...searchLabel }
this.$emit('search', this.searchLabel, this.selectablePage)
},
selectableChange (current) { // 左侧table翻页
this.selectablePage.pageNo = current
this.$emit('search', this.searchLabel, this.selectablePage)
},
selectedChange (current) { // 右侧table翻页
},
selectableSelectionChange (val) { // 左侧选项变化
this.selectableSelection = val
},
selectedSelectionChange (val) { // 右侧选项变化
this.selectedSelection = val
},
leftToRight () {
this.$emit('leftToRight', this.selectableSelection)
this.selectedData.splice(0, 0, ...this.selectableSelection)
},
rightToLeft () {
this.$emit('rightToLeft', this.selectedSelection)
this.selectedData = this.selectedData.filter(d => !this.selectedSelection.find(s => d.id === s.id))
console.info(this.selectableSelection)
console.info(this.selectedData)
},
startLoading () {
this.loading = true
},
endLoading () {
this.loading = false
},
setRowShow ({ row }) {
if (this.tableData.some(d => d.hide && row.id === d.id)) {
return 'hide-row'
}
return ''
}
},
watch: {
pageObj: {
immediate: true,
deep: true,
handler (n) {
this.selectablePage = { ...n }
}
}
}
}
</script>
<style lang="scss">
@import '@/assets/css/common/tableCommon.scss';
.nz-transfer {
display: flex;
justify-content: space-between;
.nz-transfer__box {
width: calc(50% - 7.5px);
border: 1px solid $--right-box-border-color;
border-radius: $--primary-border-radius;
.box__header {
display: flex;
align-items: center;
padding: 0 10px;
height: 52px;
color: #666;
box-sizing: border-box;
border-bottom: 1px solid $--right-box-border-color;
input {
background-color: transparent !important;
}
}
.box__table {
height: calc(100% - 94px);
border-bottom: 1px solid $--right-box-border-color;
.el-table--border::after, .el-table--group::after, .el-table::before {
height: 0;
}
.el-table__row {
td {
border-color: $--right-box-border-color;
&:first-of-type .cell {
text-overflow: unset;
}
}
}
}
.box__footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 8px 1px;
height: 42px;
box-sizing: border-box;
.jump-input {
width: 40px;
.el-input__inner {
padding: 0 5px;
height: 24px;
line-height: 24px;
}
}
.jump-pages {
padding-left: 9px;
font-size: 14px;
color: #333;
}
.top-tool-btn {
height: 28px;
width: 28px;
line-height: 28px;
}
.el-pagination {
display: flex;
align-items: center;
padding: 0;
.btn-prev, .btn-next {
border: none;
background-color: transparent !important;
}
.btn-prev {
margin: 0 5px;
}
.btn-next {
margin: 0;
}
}
}
}
}
.hide-row {
display: none !important;
}
</style>

View File

@@ -1,5 +1,5 @@
<template> <template>
<el-popover :placement="placement" popper-class="nz-pop nz-pop-select-panel" ref="selectAssetTypePopBox" transition="slide" v-model="popBox.show" width="820"> <el-popover ref="selectAssetTypePopBox" v-model="popBox.show" :placement="placement" :width="width" popper-class="nz-pop nz-pop-select-panel" transition="slide">
<div> <div>
<div class="pop-item-wider"> <div class="pop-item-wider">
@@ -37,13 +37,14 @@ export default {
props: { props: {
placement: { type: String }, placement: { type: String },
assetTypeData: { type: Array }, assetTypeData: { type: Array },
showParent: { type: Object } showType: { type: Object },
width: { type: String, default: '625' }
}, },
mounted () { mounted () {
this.$refs.assetTypeTree.setCurrentKey(this.assetType) this.$refs.assetTypeTree.setCurrentKey(this.assetType)
}, },
watch: { watch: {
showParent: { showType: {
immediate: true, immediate: true,
handler (n) { handler (n) {
if (n) { if (n) {

View File

@@ -0,0 +1,407 @@
<template>
<div v-clickoutside="{obj: editData, func: esc}" class="right-box right-box-asset-batch">
<div class="right-box__header">
<div class="header__title">{{$t('asset.batchEditAsset')}}</div>
<div class="header__operation">
<span><i class="nz-icon nz-icon-close"></i></span>
</div>
</div>
<div class="right-box__container">
<div class="container__form">
<!-- Edit type -->
<el-form ref="assetEditForm" :model="editData" :rules="rules" label-position="top" label-width="120px">
<el-form-item :label="$t('overall.name')" prop="editType">
<el-select v-model="editData.editType" class="right-box__select" popper-class="right-box-select-dropdown prevent-clickoutside" size="small" value-key="value">
<el-option v-for="type in assetConstants.editTypeOptions" :key="type.value" :label="type.label" :value="type.value"/>
</el-select>
</el-form-item>
<!-- 第一级Edit type = account -->
<template v-if="editData.editType === assetConstants.editTypeData.account">
<el-form-item :label="$t('asset.authProtocol')" prop="authProtocol">
<el-select v-model="editData.authProtocol" class="right-box__select" popper-class="right-box-select-dropdown prevent-clickoutside" size="small" value-key="value">
<el-option v-for="type in assetConstants.authProtocolOptions" :key="type.value" :label="type.label" :value="type.value"/>
</el-select>
</el-form-item>
<!-- 第二级Protocol type = SSH -->
<template v-if="editData.authProtocol === assetConstants.authProtocolData.ssh">
<div class="form__sub-title">{{$t('asset.sshAccount')}}</div>
<el-form-item :label="$t('asset.authType')" prop="authType">
<el-select v-model="editData.authType" class="right-box__select" popper-class="right-box-select-dropdown prevent-clickoutside" size="small" value-key="value">
<el-option v-for="type in assetConstants.authTypeOptions" :key="type.value" :label="type.label" :value="type.value"/>
</el-select>
</el-form-item>
<!-- 第三级Auth type = username | key -->
<el-form-item :label="$t('asset.username')" prop="authUsername">
<el-input v-model="editData.authUsername" size="small"/>
</el-form-item>
<template v-if="editData.authType === assetConstants.authTypeData.key">
<!-- Key支持私钥 -->
<el-form-item :label="$t('asset.privateKey')" prop="authPriKey">
<el-input v-model="editData.authPriKey" size="small"/>
</el-form-item>
</template>
<el-form-item :label="$t('asset.password')" prop="authPin">
<el-input v-model="editData.authPin" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.port')" prop="authProtocolPort">
<el-input v-model="editData.authProtocolPort" size="small"/>
</el-form-item>
</template>
<!-- 第二级Protocol type = TELNET -->
<template v-if="editData.authProtocol === assetConstants.authProtocolData.telnet">
<div class="form__sub-title">TELNET</div>
<el-form-item :label="$t('asset.username')" prop="authUsername">
<el-input v-model="editData.authUsername" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.password')" prop="authPin">
<el-input v-model="editData.authPin" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.usernamePrompt')" prop="authUserTip">
<el-input v-model="editData.authUserTip" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.passwordPrompt')" prop="authPinTip">
<el-input v-model="editData.authPinTip" size="small"/>
</el-form-item>
</template>
</template>
<!-- 第一级Edit type = label -->
<template v-if="editData.editType === assetConstants.editTypeData.label">
<div class="form__sub-title">{{$t('overall.labels')}}</div>
<div v-for="(label, i) in editData.fields" :key="i" class="form__dotted-item">
<el-form-item :prop="'fields.' + i + '.value'">
<template v-slot:label>
<div class="form__labels-label">
<span>{{label.name}}</span>
<div>
<el-checkbox v-model="label.action" :false-label="0" :label="$t('overall.delete')" :true-label="1" size="small" style="padding-right: 20px;"></el-checkbox>
<span v-if="label.type.toUpperCase() === assetConstants.labelTypeData.MULTITEXT" @click="addMultiTextRow(label)"><i class="nz-icon nz-icon-create-square"></i></span>
<span @click="removeLabel(label)"><i class="nz-icon nz-icon-minus"></i></span>
</div>
</div>
</template>
<template v-if="label.action !== 1">
<template v-if="label.type.toUpperCase() === assetConstants.labelTypeData.TEXT">
<el-input v-model="label.value" size="small"/>
</template>
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.MULTITEXT">
<div v-for="(value, i) in label.value" :key="i" class="label__multi-text">
<el-input v-model="label.value[i]" size="small"/>
<span><i class="nz-icon nz-icon-minus"></i></span>
</div>
</template>
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.TEXTAREA">
<el-input v-model="label.value" :maxlength="4096" size="small" type="textarea"/>
</template>
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.RADIO">
<el-radio v-for="item in JSON.parse(label.param).items" :key="item.name" v-model="label.value" :label="item.name">{{item.name}}</el-radio>
</template>
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.CHECKBOX">
<el-checkbox-group v-model="label.value">
<el-checkbox v-for="item in JSON.parse(label.param).items" :key="item.name" :label="item.name" :value="item.name"></el-checkbox>
</el-checkbox-group>
</template>
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.SELECT">
<el-select v-model="label.value" class="right-box__select" popper-class="right-box-select-dropdown prevent-clickoutside" size="small">
<el-option v-for="item in JSON.parse(label.param).items" :key="item.name" :label="item.name" :value="item.name"></el-option>
</el-select>
</template>
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.INTEGER">
<el-input v-model="label.value" oninput="value=value.replace(/[^\d]/g,'')" size="small"></el-input>
</template>
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.DOUBLE">
<el-input v-model="label.value" oninput="value=value.replace(/[^0-9.]/g,'')" size="small"></el-input>
</template>
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.DATETIME">
<template v-if="JSON.parse(label.param).subType === assetConstants.labelSubTypeData.time">
<div v-if="label.interval" style="display: flex; justify-content: space-between">
<el-time-select v-model="label.value[0]" size="small"></el-time-select>
<el-time-select v-model="label.value[1]" size="small"></el-time-select>
</div>
<template v-else>
<el-time-select v-model="label.value" size="small" style="width: 100%"></el-time-select>
</template>
</template>
<template v-else>
<template v-if="label.interval">
<el-date-picker
id="asset-box-input-purchase-date"
v-model="label.value"
:type="JSON.parse(label.param).subType === assetConstants.labelSubTypeData.date ? 'dateRange' : 'datetimerange'"
placeholder=""
size="small"
style="width: 100%">
</el-date-picker>
</template>
<template v-else>
<el-date-picker
id="asset-box-input-parchase-date"
v-model="label.value"
:type="JSON.parse(label.param).subType"
placeholder=""
size="small"
style="width: 100%"
value-format="yyyy-MM-dd">
</el-date-picker>
</template>
</template>
</template>
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.EMAIL">
<input v-model="label.value" size="small"></input>
</template>
</template>
</el-form-item>
</div>
<!-- label的新增按钮 -->
<div class="form__flex-container hide-casc-input">
<button class="form__create-btn" type="button" @click.stop><i class="nz-icon nz-icon-create-square"></i></button>
<el-cascader
v-if="labelCascShow"
:options="fieldGroupData"
:props="labelCascProp"
class="hide-input"
popper-class="prevent-clickoutside"
size="small"
@change="addLabel"
></el-cascader>
</div>
</template>
<!-- 第一级Edit type = state -->
<template v-if="editData.editType === assetConstants.editTypeData.state">
<el-form-item :label="$t('asset.state')" prop="stateId">
<el-select v-model="editData.stateId" class="right-box__select" popper-class="right-box-select-dropdown prevent-clickoutside" size="small" value-key="id">
<el-option v-for="state in stateData" :key="state.id" :label="state.name" :value="state.id"></el-option>
</el-select>
</el-form-item>
</template>
<!-- 第一级Edit type = snmp credential -->
<template v-if="editData.editType === assetConstants.editTypeData.snmpCredential">
<el-form-item :label="$t('asset.snmpCredential')" prop="snmpCredentialId">
<el-select v-model="editData.snmpCredentialId" class="right-box__select" popper-class="right-box-select-dropdown prevent-clickoutside" size="small" value-key="id">
<el-option v-for="snmp in snmpCredentialData" :key="snmp.id" :label="snmp.name" :value="snmp.id"></el-option>
</el-select>
</el-form-item>
</template>
<!-- 选择资产穿梭框 -->
<div class="form__sub-title">{{$t('overall.select')}}</div>
<nz-transfer ref="transfer"
:page-obj="transfer.pageObj"
:search-msg="transfer.searchMsg"
:table-data="transfer.tableData"
style="margin-bottom: 20px;"
@leftToRight="addAsset"
@rightToLeft="removeAsset">
<template v-slot:title>Selected</template>
</nz-transfer>
</el-form>
</div>
</div>
<div class="right-box__footer">
<button id="asset-edit-cancel" v-cancel="{obj: editData, func: esc}" class="footer__btn footer__btn--light">
<span>{{$t('overall.cancel')}}</span>
</button>
<button id="asset-edit-save" :class="{'footer__btn--disabled': prevent_opt.save}" :disabled="prevent_opt.save" class="footer__btn" @click="save">
<span>{{$t('overall.save')}}</span>
</button>
</div>
</div>
</template>
<script>
import nzTransfer from '@/components/common/nzTransfer'
import { asset as assetConstants } from '@/components/common/js/constants'
export default {
name: 'assetBatchEditBox',
components: {
nzTransfer
},
props: {
fieldGroupData: {
type: Array
},
stateData: {
type: Array
},
snmpCredentialData: {
type: Array
}
},
data () {
const vm = this
return {
assetConstants,
url: 'asset/asset',
editData: {
editType: 1,
authProtocol: 0,
authType: 1,
fields: [],
snmpCredentialId: null
},
labelCascProp: {
lazy: true,
value: 'id',
label: 'name',
lazyLoad (node, resolve) {
const { level } = node
vm.$get('asset/field/meta', { groupIds: node.data.id }).then(response => {
if (response.code === 200) {
const meta = response.data.list.map(item => ({
...item,
leaf: level >= 1,
disabled: vm.editData.fields.some(a => a.id === item.id)
}))
vm.metaData = meta
resolve(meta)
}
})
}
},
labelCascShow: true, // 用来控制label的cascader的重新渲染
transfer: {
tableData: [],
selectedData: [],
searchLabel: {},
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [
{
id: 1,
name: 'ID',
type: 'input',
label: 'id',
disabled: false
}, {
id: 20,
name: 'SN',
type: 'input',
label: 'sn',
disabled: false
}, {
id: 21,
name: 'Host',
type: 'input',
label: 'host',
disabled: false
}, {
id: 22,
name: this.$t('asset.state'),
type: 'select',
label: 'assetState',
disabled: false
}, {
id: 23,
name: 'pingStatus',
type: 'select',
label: 'pingStatus',
disabled: false
}, {
id: 23,
name: this.$t('asset.tableTitle.cabinet'),
type: 'input',
label: 'cabinetName',
disabled: false
}
]
},
pageObj: {
pageNo: 1,
pageSize: 10,
pages: 1,
total: 0
}
},
rules: {},
metaData: []
}
},
methods: {
search (searchLabel, page) {
this.transfer.searchLabel = JSON.parse(JSON.stringify(searchLabel))
this.transfer.pageObj = JSON.parse(JSON.stringify(page))
this.getTableData()
},
esc (refresh) {
this.$emit('close', refresh)
},
save () {
this.editData.ids = this.transfer.selectedData.map(d => d.id)
this.$put('asset/asset/bulkEdit', this.editData).then(res => {
if (res.code === 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.esc(true)
}
})
},
addLabel ([groupId, metaId]) {
const label = this.metaData.find(m => m.id === metaId)
this.editData.fields.push({ ...label, value: this.blankLabelValue(label), action: 0 })
this.labelCascShow = false
this.$nextTick(() => {
this.labelCascShow = true
})
},
addMultiTextRow (label) {
label.value.push('')
},
blankLabelValue (label) {
if (label.type.toUpperCase() === this.assetConstants.labelTypeData.CHECKBOX) {
return []
} else if (label.type.toUpperCase() === this.assetConstants.labelTypeData.MULTITEXT) {
return ['']
} else {
return ''
}
},
removeLabel (label) {
let index = 0
this.editData.fields.find((f, i) => {
if (label.id === f.id) {
index = i
return true
}
return false
})
this.editData.fields.splice(index, 1)
this.labelCascShow = false
this.$nextTick(() => {
this.labelCascShow = true
})
},
getTableData () {
this.$refs.transfer.startLoading()
this.$get(this.url, { ...this.transfer.searchLabel, ...this.transfer.pageObj }).then(response => {
this.$refs.transfer.endLoading()
if (response.code === 200) {
this.transfer.tableData = response.data.list
this.transfer.pageObj.total = response.data.total
}
})
},
addAsset (toAdd) {
this.transfer.selectedData = toAdd
this.transfer.tableData.forEach(d => {
this.$set(d, 'hide', this.transfer.selectedData.some(s => s.id === d.id))
})
},
removeAsset (toRemove) {
this.transfer.selectedData = this.transfer.selectedData.filter(d => !toRemove.find(s => d.id === s.id))
this.transfer.tableData.forEach(d => {
this.$set(d, 'hide', this.transfer.selectedData.some(s => s.id === d.id))
})
// dc, brand, model, type
}
},
mounted () {
this.getTableData()
}
}
</script>
<style lang="scss">
@import '@/assets/css/common/rightBoxCommon.scss';
</style>

View File

@@ -0,0 +1,476 @@
<template>
<div v-clickoutside="{obj: editAsset, func: esc}" class="right-box right-box-asset">
<div class="right-box__header">
<div class="header__title">{{editAsset.id ? $t('asset.editAsset') : $t('asset.createAsset')}}</div>
<div class="header__operation">
<span v-cancel="{obj: editAsset, func: esc}"><i class="nz-icon nz-icon-close"></i></span>
</div>
</div>
<div class="right-box__container">
<div class="container__form">
<el-form ref="assetEditForm" :model="editAsset" :rules="rules" label-position="top" label-width="120px">
<el-form-item :label="$t('overall.name')" prop="name">
<el-input v-model="editAsset.name" size="small"/>
</el-form-item>
<el-form-item :label="$t('overall.type')" prop="typeId">
<select-asset-type id="asset-type" :asset-type-data="typeData" :show-type="editAsset.type" size="small"
@selectAssetType="selectType">
<template v-slot:trigger>
<el-input v-model="editAsset.type.name" :clearable="true" :readonly="true" placeholder="" size="small"></el-input>
</template>
</select-asset-type>
</el-form-item>
<el-form-item v-if="editAsset.type && editAsset.type.vm === 1" :label="$t('overall.parent')" prop="pid">
<el-select
v-model="editAsset.pid"
class="right-box__select"
popper-class="right-box-select-dropdown prevent-clickoutside"
size="small"
value-key="id">
<el-option v-for="p in parentAssetData" :key="p.id" :label="p.name" :value="p.id"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('asset.state')" prop="stateId">
<el-select v-model="editAsset.stateId" class="right-box__select" popper-class="right-box-select-dropdown prevent-clickoutside" size="small" value-key="id">
<el-option v-for="state in stateData" :key="state.id" :label="state.name" :value="state.id"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('asset.manageIp')" prop="manageIp">
<el-input v-model="editAsset.manageIp" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.sn')" prop="sn">
<el-input v-model="editAsset.sn" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.number')" prop="number">
<el-input v-model="editAsset.number" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.brandAndModel')" class="placeholder-emphasize" prop="brandAndModel">
<el-cascader
v-if="!vmLock"
v-model="brandAndModelData"
:options="brandData"
:placeholder="lockModelInputValue"
:props="modelCascProp"
popper-class="prevent-clickoutside"
size="small"
style="width: 100%;"
></el-cascader>
<el-input v-else v-model="lockModelInputValue" disabled size="small"></el-input>
</el-form-item>
<el-form-item :label="$t('asset.location')" prop="location">
<location-cascader v-if="!vmLock" ref="locationCascader" :dc-option="dcData" :default-model-u-size="1" @change="setLocationData"></location-cascader>
<el-input v-else v-model="lockLocationInputValue" disabled size="small"></el-input>
</el-form-item>
<el-form-item :label="$t('asset.purchaseDate')" prop="purchaseDate">
<el-date-picker
id="asset-box-input-parchase-date"
v-model="editAsset.purchaseDate"
placeholder=""
size="small"
style="width: 100%"
type="date"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
<!-- labels -->
<div class="form__sub-title">{{$t('overall.labels')}}</div>
<div v-for="(label, i) in editAsset.fields" :key="i" class="form__dotted-item">
<el-form-item :prop="'fields.' + i + '.value'">
<template v-slot:label>
<div class="form__labels-label">
<span>{{label.name}}</span>
<span @click="removeLabel(label)"><i class="nz-icon nz-icon-minus"></i></span>
</div>
</template>
<el-input v-model="label.value" size="small"/>
</el-form-item>
</div>
<!-- label的新增按钮 -->
<div class="form__flex-container hide-casc-input">
<button class="form__create-btn" type="button" @click.stop><i class="nz-icon nz-icon-create-square"></i></button>
<el-cascader
v-if="labelCascShow"
:options="fieldGroupData"
:props="labelCascProp"
class="hide-input"
popper-class="prevent-clickoutside"
size="small"
@change="addLabel"
></el-cascader>
</div>
<!-- SSH -->
<template v-if="editAsset.type && editAsset.type.authProtocol === assetConstants.authProtocolData.ssh">
<div class="form__sub-title">SSH</div>
<el-form-item :label="$t('asset.authType')" prop="authType">
<el-select v-model="editAsset.authType" class="right-box__select" popper-class="right-box-select-dropdown prevent-clickoutside" size="small" value-key="value">
<el-option v-for="type in assetConstants.authTypeOptions" :key="type.value" :label="type.label" :value="type.value"/>
</el-select>
</el-form-item>
<el-form-item :label="$t('asset.username')" prop="authUsername">
<el-input v-model="editAsset.authUsername" size="small"/>
</el-form-item>
<!-- Key支持私钥 -->
<template v-if="editAsset.authType === assetConstants.authTypeData.key">
<el-form-item :label="$t('asset.privateKey')" prop="authPriKey">
<el-input v-model="editAsset.authPriKey" size="small"/>
</el-form-item>
</template>
<el-form-item :label="$t('asset.password')" prop="authPin">
<el-input v-model="editAsset.authPin" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.port')" prop="authProtocolPort">
<el-input v-model="editAsset.authProtocolPort" size="small"/>
</el-form-item>
</template>
<!-- TELNET -->
<template v-if="editAsset.type && editAsset.type.authProtocol === assetConstants.authProtocolData.telnet">
<div class="form__sub-title">TELNET</div>
<el-form-item :label="$t('asset.username')" prop="authUsername">
<el-input v-model="editAsset.authUsername" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.password')" prop="authPin">
<el-input v-model="editAsset.authPin" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.usernamePrompt')" prop="authUserTip">
<el-input v-model="editAsset.authUserTip" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.passwordPrompt')" prop="authPinTip">
<el-input v-model="editAsset.authPinTip" size="small"/>
</el-form-item>
</template>
<!-- SNMP -->
<template v-if="editAsset.type && editAsset.type.snmpEnable === 1">
<div class="form__sub-title">SNMP</div>
<el-form-item :label="$t('asset.snmpCredential')" prop="snmpCredentialId">
<el-select v-model="editAsset.snmpCredentialId" class="right-box__select" popper-class="right-box-select-dropdown prevent-clickoutside" size="small" value-key="id">
<el-option v-for="snmp in snmpCredentialData" :key="snmp.id" :label="snmp.name" :value="snmp.id"></el-option>
</el-select>
</el-form-item>
</template>
</el-form>
</div>
</div>
<div class="right-box__footer">
<button id="asset-edit-cancel" v-cancel="{obj: editAsset, func: esc}" class="footer__btn footer__btn--light">
<span>{{$t('overall.cancel')}}</span>
</button>
<button id="asset-edit-save" :class="{'footer__btn--disabled': prevent_opt.save}" :disabled="prevent_opt.save" class="footer__btn" @click="save">
<span>{{$t('overall.save')}}</span>
</button>
</div>
</div>
</template>
<script>
import { host, port } from '@/components/common/js/validate'
import { asset as assetConstants } from '@/components/common/js/constants'
import selectAssetType from '@/components/common/popBox/selectAssetType'
import locationCascader from '@/components/common/rightBox/locationCascader'
export default {
name: 'assetBox',
components: {
selectAssetType,
locationCascader
},
props: {
obj: {
type: Object
},
dcData: {
type: Array
},
brandData: {
type: Array
},
stateData: {
type: Array
},
typeData: {
type: Array
},
snmpCredentialData: {
type: Array
},
fieldGroupData: {
type: Array
}
},
data () {
const vm = this
return {
assetConstants,
editAsset: {},
url: 'asset/asset',
rightBox: { model: { show: false } },
vmLock: false, // 当自己是虚拟机时锁定品牌型号位置为parent的无法修改
lockModelInputValue: '', // model锁定时的显示内容
lockLocationInputValue: '', // location锁定时显示的内容
cabinetData: [],
parentAssetData: [],
metaData: [], // 下拉选项列表
labelCascShow: true, // 用来控制label的cascader的重新渲染
rules: {
name: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
pid: [
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
],
manageIp: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ validator: host, trigger: 'blur' }
],
modelId: [
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
],
typeId: [
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
],
stateId: [
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
],
dcId: [
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
],
authProtocolPort: [
{ required: true, message: this.$t('validate.required'), trigger: 'change' },
{ validator: port, trigger: 'blur' }
]
},
cabRules: {
name: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
uSize: [
{ required: true, type: 'number', min: 1, max: 47, message: this.$t('validate.required'), trigger: 'blur' }
],
dcId: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
]
},
brandAndModelData: [],
modelCascProp: {
lazy: true,
value: 'id',
label: 'name',
lazyLoad (node, resolve) {
const { level } = node
vm.$get('asset/model', { brandIds: node.data.id }).then(response => {
if (response.code === 200) {
const models = response.data.list.map(item => ({
...item,
leaf: level >= 1
}))
resolve(models)
}
})
}
},
labelCascProp: {
lazy: true,
value: 'id',
label: 'name',
lazyLoad (node, resolve) {
const { level } = node
vm.$get('asset/field/meta', { groupIds: node.data.id }).then(response => {
if (response.code === 200) {
const meta = response.data.list.map(item => ({
...item,
leaf: level >= 1,
disabled: vm.editAsset.fields.some(a => a.id === item.id)
}))
vm.metaData = meta
resolve(meta)
}
})
}
}
}
},
watch: {
obj: {
deep: true,
immediate: true,
handler (n) {
this.editAsset = JSON.parse(JSON.stringify(n))
this.$nextTick(() => {
this.editAsset.stateId = n.state ? n.state.id : ''
this.editAsset.typeId = n.type ? n.type.id : ''
if (n.id) {
this.lockModelInputValue = `${n.brand.name} / ${n.model.name}`
}
this.$refs.locationCascader.initComponet({ cabinet: n.cabinet, dc: n.dc, u: [n.cabinetStart, n.cabinetEnd] })
})
}
},
'editAsset.type': {
deep: true,
immediate: true,
handler (n) {
if (n) {
this.vmLock = n.vm === 1 // vm == 1 时锁定model和location
if (!this.editAsset.authProtocolPort) {
if (n.authProtocol === this.assetConstants.authProtocolData.ssh) {
this.editAsset.authProtocolPort = 22
} else if (n.authProtocol === this.assetConstants.authProtocolData.telnet) {
this.editAsset.authProtocolPort = 23
}
}
}
}
},
'editAsset.pid': {
deep: true,
immediate: true,
handler (n) {
if (n) {
if (this.vmLock) {
if (this.parentAssetData.length === 0) {
this.getParentAsset().then(res => {
const asset = this.parentAssetData.find(a => a.id === n)
if (asset) {
this.editAsset.brandId = asset.brand.id
this.editAsset.modelId = asset.model.id
this.editAsset.dcId = asset.dc.id
this.editAsset.cabinetId = asset.cabinet.id
this.editAsset.cabinetStart = asset.cabinetStart
this.editAsset.cabinetEnd = asset.cabinetEnd
this.lockModelInputValue = `${asset.brand.name} / ${asset.model.name}`
this.lockLocationInputValue = `${asset.dc.name} / ${asset.cabinet.name} / ${asset.cabinetStart}-${asset.cabinetEnd}`
}
})
} else {
const asset = this.parentAssetData.find(a => a.id === n)
if (asset) {
this.editAsset.brandId = asset.brand.id
this.editAsset.modelId = asset.model.id
this.editAsset.dcId = asset.dc.id
this.editAsset.cabinetId = asset.cabinet.id
this.editAsset.cabinetStart = asset.cabinetStart
this.editAsset.cabinetEnd = asset.cabinetEnd
this.lockModelInputValue = `${asset.brand.name} / ${asset.model.name}`
this.lockLocationInputValue = `${asset.dc.name} / ${asset.cabinet.name} / ${asset.cabinetStart}-${asset.cabinetEnd}`
}
}
}
}
}
}
},
mounted () {
this.getParentAsset()
},
methods: {
clickOutside () {
this.esc(false)
},
setLocationData ({ cabinet, dc, u }) {
if (dc) {
this.editAsset.dcId = dc.id
this.editAsset.cabinetId = cabinet.id
this.editAsset.cabinetStart = u[0]
this.editAsset.cabinetEnd = u[1]
}
},
removeLabel (label) {
let index = 0
this.editAsset.fields.find((f, i) => {
if (label.id === f.id) {
index = i
return true
}
return false
})
this.editAsset.fields.splice(index, 1)
this.labelCascShow = false
this.$nextTick(() => {
this.labelCascShow = true
})
},
getParentAsset () {
return new Promise(resolve => {
this.$get(this.url, { pageSize: -1, vmh: 1 }).then(response => {
if (response.code === 200) {
this.parentAssetData = response.data.list
}
resolve()
})
})
},
selectType (type) {
this.editAsset.type = { ...type }
this.editAsset.typeId = type.id ? type.id : ''
},
addLabel ([groupId, metaId]) {
const label = this.metaData.find(m => m.id === metaId)
this.editAsset.fields.push({ id: label.id, value: '', name: label.name })
this.labelCascShow = false
this.$nextTick(() => {
this.labelCascShow = true
})
},
/* 关闭弹框 */
esc (refresh) {
this.prevent_opt.save = false
this.$emit('close', refresh)
},
getCabinetData (id) {
return new Promise(resolve => {
this.$get('cabinet?dcId=' + id).then(response => {
if (response.code === 200) {
this.cabinetData = response.data.list
for (let i = 0; i < this.cabinetData.length; i++) {
this.$set(this.cabinetData[i], 'children', this.dcData)
}
}
resolve(this.cabinetData)
})
})
},
save () {
if (this.prevent_opt.save) { return } ;
this.prevent_opt.save = true
this.$refs.assetEditForm.validate((valid) => {
if (valid) {
if (this.editAsset.id) {
this.$put(this.url, this.editAsset).then(res => {
this.prevent_opt.save = false
if (res.code === 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.esc(true)
} else {
this.$message.error(res.msg)
}
})
} else {
this.$post(this.url, this.editAsset).then(res => {
this.prevent_opt.save = false
if (res.code === 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
this.esc(true)
} else {
this.$message.error(res.msg)
}
})
}
} else {
this.prevent_opt.save = false
return false
}
})
}
}
}
</script>
<style lang="scss">
@import '@/assets/css/common/rightBoxCommon.scss';
.placeholder-emphasize input::-webkit-input-placeholder {
color: #606266 !important;
}
</style>

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="right-box right-box-asset" v-clickoutside="{obj:editAsset,func:clickOutside}"> <div v-clickoutside="{obj:editAsset, func:clickOutside}" class="right-box right-box-asset">
<!--顶部按钮--> <!--顶部按钮-->
<div class="right-box-top-btns right-box-form-delete"> <div class="right-box-top-btns right-box-form-delete">
<button @click="del" id="asset-edit-del" type="button" v-has="'asset_delete'" v-if="editAsset.id" <button @click="del" id="asset-edit-del" type="button" v-has="'asset_delete'" v-if="editAsset.id"
@@ -686,7 +686,8 @@ export default {
} }
} }
</script> </script>
<style > <style lang="scss">
@import '@/assets/css/common/rightBoxCommon.scss';
.location-selector{ .location-selector{
width: 512px; width: 512px;
} }

View File

@@ -24,7 +24,7 @@
</el-form-item> </el-form-item>
<!--parent--> <!--parent-->
<el-form-item :label="$t('config.assetType.parent')" prop="pid"> <el-form-item :label="$t('config.assetType.parent')" prop="pid">
<select-asset-type :asset-type-data="assetTypeData2" :show-parent="showParentAssetType" @selectAssetType="selectParent" id="asset-type-parent" <select-asset-type id="asset-type-parent" :asset-type-data="assetTypeData2" :show-type="showParentAssetType" @selectAssetType="selectParent"
size="small"> size="small">
<template v-slot:trigger> <template v-slot:trigger>
<el-input :clearable="true" :readonly="true" placeholder="" size="small" v-model="showParentAssetType.name"> <el-input :clearable="true" :readonly="true" placeholder="" size="small" v-model="showParentAssetType.name">
@@ -79,7 +79,7 @@
</div> </div>
</template> </template>
<script> <script>
import selectAssetType from '../popBox/selectAssetType' import selectAssetType from '@/components/common/popBox/selectAssetType'
export default { export default {
name: 'asset-type-right-box', name: 'asset-type-right-box',
props: { props: {

View File

@@ -6,13 +6,13 @@
</el-input> </el-input>
</div> </div>
<div class="dropdown" :class="{'dropdown-active':dropDownVisible == true}" > <div class="dropdown" :class="{'dropdown-active':dropDownVisible == true}" >
<div class="container"> <div class="location-container">
<div class="container-item"> <div class="container-item">
<div style="height: 100%; overflow: auto;"> <div style="height: 100%; overflow: auto;">
<ul v-if="idcInfos&& idcInfos.length>0"> <ul v-if="dcInfos&& dcInfos.length>0">
<li v-for="(item,index) in idcInfos" :key="item.id+'-'+index" @click="loadCabinetInfos(item)"> <li v-for="(item,index) in dcInfos" :key="item.id+'-'+index" @click="loadCabinetInfos(item)">
<div class="container-item-content"> <div class="container-item-content">
<div :title="item.name" class="container-item-content_label" :class="{'selected':selectedData.idc&&selectedData.idc.id == item.id}">{{item.name}}</div> <div :class="{'selected':selectedData.dc&&selectedData.dc.id == item.id}" :title="item.name" class="container-item-content_label">{{item.name}}</div>
<div><i class="el-icon-arrow-right"></i></div> <div><i class="el-icon-arrow-right"></i></div>
</div> </div>
</li> </li>
@@ -36,7 +36,7 @@
<div class="container-item" v-show="isShowCabinetU || uChecked.length>0" style="border-right: unset"> <div class="container-item" v-show="isShowCabinetU || uChecked.length>0" style="border-right: unset">
<div style="height: 100%; overflow: auto;"> <div style="height: 100%; overflow: auto;">
<el-checkbox-group v-model="uChecked" v-if="refresh" @change="uChange"> <el-checkbox-group v-model="uChecked" v-if="refresh" @change="uChange">
<el-checkbox v-for="(item,index) in showUInfos" :key="index" :label="item.label" :value="item.value" :disabled="item.occupy==true" :checked="item.occupy==true||item.checked==true" :ref="'u-'+selectedData.idc.id+'-'+selectedData.cabinet.id+'-'+item.value" style="width: 50%"></el-checkbox> <el-checkbox v-for="(item,index) in showUInfos" :key="index" :ref="'u-'+selectedData.dc.id+'-'+selectedData.cabinet.id+'-'+item.value" :checked="item.occupy==true||item.checked==true" :disabled="item.occupy==true" :label="item.label" :value="item.value" style="width: 50%"></el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</div> </div>
</div> </div>
@@ -60,19 +60,19 @@ export default {
defaultModelUSize: { default: 1 }, defaultModelUSize: { default: 1 },
value: { default: null }, value: { default: null },
disabled: { type: Boolean }, disabled: { type: Boolean },
idcOption: { type: Array } dcOption: { type: Array }
}, },
data () { data () {
return { return {
initData: null, initData: null,
dropDownVisible: false, dropDownVisible: false,
idcInfos: [], dcInfos: [],
cabinetInfos: new Map(), cabinetInfos: new Map(),
showCabinetInfos: [], showCabinetInfos: [],
uInfos: new Map(), uInfos: new Map(),
showUInfos: [], showUInfos: [],
selectedData: { selectedData: {
idc: null, dc: null,
cabinet: null, cabinet: null,
u: null u: null
}, },
@@ -88,7 +88,7 @@ export default {
mounted () { mounted () {
}, },
methods: { methods: {
toggleDropdown: function () { toggleDropdown () {
if (this.disabled == false) { if (this.disabled == false) {
this.dropDownVisible = !this.dropDownVisible this.dropDownVisible = !this.dropDownVisible
if (this.dropDownVisible) { if (this.dropDownVisible) {
@@ -103,30 +103,22 @@ export default {
} }
} }
}, },
queryIdcInfos: function () { queryDcInfos () {
this.idcInfos = this.idcOption this.dcInfos = this.dcOption
/* this.$get('idc?pageSize=-1').then(response=>{
console.info(2)
if(response.code == 200){
this.idcInfos=response.data.list;
}else{
console.error(response.msg);
}
}) */
}, },
loadCabinetInfos: function (idc) { loadCabinetInfos (dc) {
if (!idc) { if (!dc) {
return return
} }
this.selectedData.idc = idc this.selectedData.dc = dc
this.selectedData.cabinet = null this.selectedData.cabinet = null
this.selectedData.u = null this.selectedData.u = null
const cabinetKey = 'idc-' + idc.name + '-' + idc.id const cabinetKey = 'dc-' + dc.name + '-' + dc.id
this.showCabinetInfos = [] this.showCabinetInfos = []
if (this.cabinetInfos.has(cabinetKey) && this.cabinetInfos.get(cabinetKey) && this.cabinetInfos.get(cabinetKey).length > 0) { if (this.cabinetInfos.has(cabinetKey) && this.cabinetInfos.get(cabinetKey) && this.cabinetInfos.get(cabinetKey).length > 0) {
this.showCabinetInfos = this.cabinetInfos.get(cabinetKey) this.showCabinetInfos = this.cabinetInfos.get(cabinetKey)
} else { } else {
this.$get('cabinet?pageSize=-1&idcId=' + idc.id).then(response => { this.$get('cabinet?pageSize=-1&dcId=' + dc.id).then(response => {
if (response.code == 200) { if (response.code == 200) {
this.cabinetInfos.set(cabinetKey, response.data.list) this.cabinetInfos.set(cabinetKey, response.data.list)
this.showCabinetInfos = response.data.list this.showCabinetInfos = response.data.list
@@ -139,14 +131,14 @@ export default {
this.isShowCabinetU = false this.isShowCabinetU = false
this.showUInfos = [] this.showUInfos = []
}, },
loadCabinetUInfos: function (cabinet, isInit = false) { loadCabinetUInfos (cabinet, isInit = false) {
if (!cabinet) { if (!cabinet) {
return return
} }
// console.log('load u',cabinet,isInit) // console.log('load u',cabinet,isInit)
this.selectedData.cabinet = cabinet this.selectedData.cabinet = cabinet
this.selectedData.u = null this.selectedData.u = null
const cabinetUKey = 'cabinet-' + this.selectedData.idc.id + '-' + cabinet.id const cabinetUKey = 'cabinet-' + this.selectedData.dc.id + '-' + cabinet.id
this.showUInfos = [] this.showUInfos = []
this.uChecked = [] this.uChecked = []
this.oldUChecked = [] this.oldUChecked = []
@@ -196,7 +188,7 @@ export default {
this.isShowCabinetU = true this.isShowCabinetU = true
this.refreshCheckBox() this.refreshCheckBox()
}, },
uChange: function (data) { uChange (data) {
if (data.length < this.oldUChecked.length) { // 取消选择操作 if (data.length < this.oldUChecked.length) { // 取消选择操作
// 1.判断是否仅剩下defualtModelusize 的u位选中 // 1.判断是否仅剩下defualtModelusize 的u位选中
const checkedValues = this.findUnoccupyU(this.oldUChecked) const checkedValues = this.findUnoccupyU(this.oldUChecked)
@@ -300,11 +292,11 @@ export default {
this.oldUChecked = this.uChecked this.oldUChecked = this.uChecked
this.selectedData.u = this.findOldCheckedMinMax(this.uChecked) this.selectedData.u = this.findOldCheckedMinMax(this.uChecked)
}, },
clearUChecked: function () { // 取消所有选中,恢复到刚打开时的状态 clearUChecked () { // 取消所有选中,恢复到刚打开时的状态
this.uChecked = [] this.uChecked = []
this.uChecked = this.uChecked.concat(this.occupyU) this.uChecked = this.uChecked.concat(this.occupyU)
}, },
findOldCheckedMinMax: function () { findOldCheckedMinMax () {
let oldUCheckCopy = Object.assign([], this.oldUChecked) let oldUCheckCopy = Object.assign([], this.oldUChecked)
oldUCheckCopy = this.findUnoccupyU(oldUCheckCopy) oldUCheckCopy = this.findUnoccupyU(oldUCheckCopy)
if (oldUCheckCopy && oldUCheckCopy.length > 0) { if (oldUCheckCopy && oldUCheckCopy.length > 0) {
@@ -316,14 +308,14 @@ export default {
return [] return []
} }
}, },
findUnoccupyU: function (arr) { findUnoccupyU (arr) {
// console.log('findUnoccupyU') // console.log('findUnoccupyU')
// console.log(this.occupyU) // console.log(this.occupyU)
return arr.filter((item, index) => { return arr.filter((item, index) => {
return !this.occupyU.includes(item) return !this.occupyU.includes(item)
}) })
}, },
findSuitableU: function (checkValue) { findSuitableU (checkValue) {
// 将u位数组分为左右两部分先查找右边的是否符合 // 将u位数组分为左右两部分先查找右边的是否符合
let left = this.showUInfos.filter((item, index) => { return item.value < checkValue }) let left = this.showUInfos.filter((item, index) => { return item.value < checkValue })
left = left.reverse()// 自下而上查找 left = left.reverse()// 自下而上查找
@@ -353,39 +345,39 @@ export default {
} }
return result return result
}, },
refreshCheckBox: function () { refreshCheckBox () {
this.refresh = false this.refresh = false
this.$nextTick(() => { this.$nextTick(() => {
this.refresh = true this.refresh = true
}) })
}, },
initComponet: function (initData) { initComponet (initData) {
this.initData = Object.assign({}, initData) this.initData = Object.assign({}, initData)
if (initData) { if (initData) {
this.selectedData.idc = initData.idc this.selectedData.dc = initData.dc
this.selectedData.cabinet = initData.cabinet this.selectedData.cabinet = initData.cabinet
this.selectedData.u = initData.u this.selectedData.u = initData.u
this.loadCabinetInfos(initData.idc) this.loadCabinetInfos(initData.dc)
this.loadCabinetUInfos(initData.cabinet, true) this.loadCabinetUInfos(initData.cabinet, true)
} }
} }
}, },
computed: { computed: {
inputShowInfo () { inputShowInfo () {
const idcName = this.selectedData.idc ? this.selectedData.idc.name + '/' : '' const dcName = this.selectedData.dc ? this.selectedData.dc.name + ' / ' : ''
const cabinetName = this.selectedData.cabinet ? this.selectedData.cabinet.name + '/' : '' const cabinetName = this.selectedData.cabinet ? this.selectedData.cabinet.name + ' / ' : ''
const uValues = this.selectedData.u && this.selectedData.u.length > 0 && this.selectedData.u[0] && this.selectedData.u[1] ? this.selectedData.u[0] + '-' + this.selectedData.u[1] : '' const uValues = this.selectedData.u && this.selectedData.u.length > 0 && this.selectedData.u[0] && this.selectedData.u[1] ? this.selectedData.u[0] + '-' + this.selectedData.u[1] : ''
if (!this.selectedData.idc) { if (!this.selectedData.dc) {
return '' return ''
} else if (this.selectedData.idc && !this.selectedData.cabinet) { } else if (this.selectedData.dc && !this.selectedData.cabinet) {
return idcName return dcName
} else if (this.selectedData.idc && this.selectedData.cabinet && !this.selectedData.u) { } else if (this.selectedData.dc && this.selectedData.cabinet && !this.selectedData.u) {
return idcName + cabinetName return dcName + cabinetName
} else if (this.selectedData.idc && this.selectedData.cabinet && this.selectedData.u) { } else if (this.selectedData.dc && this.selectedData.cabinet && this.selectedData.u) {
return idcName + cabinetName + uValues return dcName + cabinetName + uValues
} }
return '' return ''
} }
@@ -398,11 +390,11 @@ export default {
this.$emit('change', n) this.$emit('change', n)
} }
}, },
idcOption: { dcOption: {
deep: true, deep: true,
immediate: true, immediate: true,
handler (n, o) { handler (n, o) {
this.queryIdcInfos() this.queryDcInfos()
} }
} }
} }
@@ -448,12 +440,12 @@ export default {
height: 200px; height: 200px;
width: 100%; width: 100%;
} }
.container{ .location-container{
height: 100%; height: 100%;
width: 100%; width: 100%;
display: flex; display: flex;
} }
.container .container-item{ .location-container .container-item{
height: 100%; height: 100%;
flex: 1; flex: 1;
width: 0; width: 0;
@@ -469,6 +461,7 @@ export default {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
color: #606266;
} }
.container-item-content .selected{ .container-item-content .selected{
font-weight: 700; font-weight: 700;

View File

@@ -311,6 +311,7 @@ export default {
} }
</script> </script>
<style lang="scss"> <style lang="scss">
@import '@/assets/css/common/rightBoxCommon.scss';
.right-box-account { .right-box-account {
.right-box-sub-title { .right-box-sub-title {
#add-notification { #add-notification {

View File

@@ -0,0 +1,142 @@
<template>
<el-table
id="assetMetaTable"
ref="dataTable"
:data="tableData"
:height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<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">
<div v-if="item.prop === 'group'">
{{scope.row[item.prop] ? scope.row[item.prop].name : '-'}}
</div>
<div v-else-if=" item.prop === 'display' ">
<el-switch
v-model="scope.row[item.prop]"
:active-value="1"
:inactive-value="0"
active-color="#ee9d3f"
@change="putMeta(scope.row)">
</el-switch>
</div>
<div v-else-if=" item.prop === 'search' ">
<el-switch
v-model="scope.row[item.prop]"
:active-value="1"
:inactive-value="0"
active-color="#ee9d3f"
@change="putMeta(scope.row)">
</el-switch>
</div>
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop] || '-'}}</span>
<template v-else>-</template>
</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="$refs.dataList.showBottomBox('operationLog', 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 v-has="'asset_label_edit'" :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 v-has="'asset_label_delete'" :command="['delete', scope.row]"><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: 'roleTable',
mixins: [table],
data () {
return {
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.assetMeta.name'),
prop: 'name',
show: true
}, {
label: this.$t('config.assetMeta.key'),
prop: 'metaKey',
show: true
}, {
label: this.$t('config.assetMeta.group'),
prop: 'group',
show: true
}, {
label: this.$t('config.assetMeta.search'),
prop: 'search',
show: true
}, {
label: this.$t('config.assetMeta.display'),
prop: 'display',
show: true
}, {
label: this.$t('config.assetMeta.type'),
prop: 'type',
show: true
}, {
label: this.$t('config.assetMeta.params'),
prop: 'param',
show: false
}
]
}
},
methods: {
putMeta (row) {
this.tools.loading = true
this.$put('asset/field/meta', row).then(response => {
this.prevent_opt.save = false
if (response.code === 200) {
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
} else {
this.$message.error(response.msg)
}
this.getTableData()
})
}
}
}
</script>

View File

@@ -0,0 +1,206 @@
<template>
<el-table
id="roleTable"
ref="dataTable"
:data="tableData"
:height="height"
border
@header-dragend="dragend"
@sort-change="tableDataSort"
@selection-change="selectionChange"
>
<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 === 'type'">{{scope.row.type ? scope.row.type.name : '-'}}</template>
<template v-else-if="item.prop === 'state'">{{scope.row.state ? scope.row.state.name : '-'}}</template>
<template v-else-if="item.prop === 'endpointNum'">
<div :class="messageStyle(item, scope.row)" @mouseenter="showTableTooltip(`${$t('asset.down')} / ${$t('asset.suspended')} / ${$t('asset.total')}`, true, $event)" @mouseleave="hideTableTooltip">
<span class="link" style="padding: 2px 8px" @click="showEndpoint(scope.row)">{{scope.row.endpointDownNum}}/{{scope.row.endpointSuspendedNum}}/{{scope.row.endpointNum}}</span>
</div>
</template>
<template v-else-if="item.prop === 'alertNum'">
<div :class="messageStyle(item, scope.row)" @mouseenter="showTableTooltip(scope.row.alertNum+' '+$t('overall.active'), scope.row.alertNum >= 99, $event)" @mouseleave="hideTableTooltip">
<span :id="'asset-alerts-'+scope.row.id" class="link" @click="jumpToAlertMsg(scope.row)">
{{(scope.row.alertNum < 99 ? scope.row.alertNum : 99)}}
<sup v-if="scope.row.alertNum > 99" class="linkSup">+</sup>
{{' ' + $t('overall.active')}}
</span>
</div>
</template>
<template v-else-if="item.prop === 'dc'">{{scope.row.dc ? scope.row.dc.name : '-'}}</template>
<template v-else-if="item.prop === 'cabinet'">
<span v-if="scope.row.cabinet && scope.row.cabinet !== '--'">{{scope.row.cabinet.name}}&nbsp;{{returnCabinet( scope.row.cabinetStart, scope.row.cabinetEnd)}}</span>
<span v-else >--</span>
</template>
<template v-else-if="item.prop === 'model'">{{scope.row.model ? scope.row.model.name : '-'}}</template>
<template v-else-if="item.prop === 'parent'">{{scope.row.parent ? scope.row.parent.name : '-'}}</template>
<template v-else-if="item.prop === 'brand'">{{scope.row.brand ? scope.row.brand.name : '-'}}</template>
<template v-else-if="item.prop === 'purchaseDate'">{{scope.row.purchaseDate ? scope.row.purchaseDate : '--'}}</template>
<template v-else>{{scope.row[item.prop]}}</template>
</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="tableOperation(['detail', 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="['copy', scope.row]"><i class="nz-icon nz-icon-override"></i><span class="operation-dropdown-text">Copy</span></el-dropdown-item>
<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="['cli', scope.row]" :disabled="!scope.row.authUsername"><i class="nz-icon nz-icon-cli"></i><span class="operation-dropdown-text">Connect</span></el-dropdown-item>
<el-dropdown-item :command="['delete', scope.row]"><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'
import { showTableTooltip, hideTableTooltip } from '@/components/common/js/tools'
export default {
name: 'assetTable',
mixins: [table],
data () {
return {
tableTitle: [
{
label: this.$t('overall.id'),
prop: 'id',
show: false,
width: 110
}, {
label: this.$t('overall.name'),
prop: 'name',
show: true,
width: 110
}, {
label: 'SN',
prop: 'sn',
show: true
}, {
label: this.$t('overall.parent'),
prop: 'parent',
show: true,
width: 110
}, {
label: this.$t('overall.type'),
prop: 'type',
show: true,
width: 110
}, {
label: this.$t('asset.state'),
prop: 'state',
show: true,
width: 110
}, {
label: this.$t('asset.brand'),
prop: 'brand',
show: true,
width: 120
}, {
label: this.$t('asset.model'),
prop: 'model',
show: true,
width: 110
}, {
label: this.$t('overall.dc'),
prop: 'dc',
show: true,
width: 110
}, {
label: this.$t('asset.cabinet'),
prop: 'cabinet',
show: true,
width: 110
}, {
label: this.$t('asset.manageIp'),
prop: 'manageIp',
show: true,
width: 120
}, {
label: this.$t('asset.alertNum'),
prop: 'alert',
show: true,
width: 120
}, {
label: this.$t('asset.endpointNum2'),
prop: 'endpointNum',
show: true,
width: 150
}, {
label: this.$t('asset.purchaseDate'),
prop: 'purchaseDate',
show: false,
width: 110
}
]
}
},
methods: {
showTableTooltip,
hideTableTooltip,
messageStyle (title, row) {
if (title.prop === 'alertNum') {
if (row.alertNum > 0) {
return 'danger'
} else {
return 'success'
}
}
if (title.label === 'endpointNum') {
if (row.state === 3) {
return 'suspended'
} else {
if (row.endpointDownNum > 0) {
return 'danger'
} else {
return 'success'
}
}
}
return ''
},
showEndpoint (asset) {
this.bottomBox.asset = Object.assign({}, asset)
this.bottomBox.targetTab = 'endpoint'
this.bottomBox.showSubList = true
},
returnCabinet (start, end) { // 返回机柜u位信息
if (!start || !end) {
return ''
}
return `[${start}-${end}]`
}
}
}
</script>

View File

@@ -43,7 +43,7 @@
fixed="right"> fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div> <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items"> <div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" title="Copy" @click="copyRow(scope.row,'exprTemp')"><i class="nz-icon nz-icon-override"></i></button> <button class="table-operation-item" title="Copy" @click="tableOperation('copy', scope.row)"><i class="nz-icon nz-icon-override"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation"> <el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more"> <div class="table-operation-item table-operation-item--more">
<span></span><i class="nz-icon nz-icon-arrow-down"></i> <span></span><i class="nz-icon nz-icon-arrow-down"></i>

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,19 @@
<template> <template>
<div style="height: 100%"> <div>
<nz-data-list <nz-data-list
ref="dataList" ref="dataList"
:components="['searchInput', 'elementSet']" :api="url"
:from="fromRoute.assetLabel"
:custom-table-title.sync="tools.customTableTitle" :custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.role" :layout="['searchInput', 'elementSet']"
:search-msg="searchMsg" :search-msg="searchMsg">
:table-id="tableId"
:table-title="tableTitle">
<template v-slot:top-tool-left> <template v-slot:top-tool-left>
<select-group ref="selectGroup" :filter-object="filterGroup" :object-data="groupData" :placement="'bottom-start'" <select-group ref="selectGroup" :filter-object="filterGroup" :object-data="groupData" :placement="'bottom-start'"
:show-object="showGroup" style="width: 300px;" @del="delGroup" @edit="editGroup" @selectObject="groupChange"> :show-object="showGroup" style="width: 300px;" @del="delGroup" @edit="editGroup" @selectObject="groupChange">
<template v-slot:header> <template v-slot:header>
<div class="panel-select-header"> <div class="panel-select-header">
<el-input id="panel-list-search" v-model="filterGroup" :placeholder="$t('overall.search')" clearable size="mini" style="width: 240px; margin-right: 5px;"></el-input> <el-input id="panel-list-search" v-model="filterGroup" :placeholder="$t('overall.search')" clearable size="mini" style="width: 240px; margin-right: 5px;"></el-input>
<span id="panel-list-toadd" v-has="'panel_toAdd'" :title='$t("dashboard.panel.createPanelTitleSec")' class="panel-select-add" @click="addGroup"><i class="nz-icon nz-icon-plus"></i></span> <span id="panel-list-toadd" v-has="'asset_label_add'" :title='$t("dashboard.panel.createPanelTitleSec")' class="panel-select-add" @click="addGroup"><i class="nz-icon nz-icon-plus"></i></span>
</div> </div>
</template> </template>
<template v-slot:trigger> <template v-slot:trigger>
@@ -23,94 +22,28 @@
</select-group> </select-group>
</template> </template>
<template v-slot:top-tool-right> <template v-slot:top-tool-right>
<button id="meta-add-meta" v-has="'expr_temp_save'" :title="$t('overall.exportExcelLower')" class="top-tool-btn margin-l-20" <button id="meta-add-meta" v-has="'asset_label_add'" :title="$t('overall.exportExcelLower')" class="top-tool-btn margin-r-10"
type="button" @click="add"> type="button" @click="add">
<i class="nz-icon nz-icon-create-square"></i> <i class="nz-icon nz-icon-create-square"></i>
</button> </button>
<delete-button :delete-objs="batchDeleteObjs" @after="getTableData" <delete-button :delete-objs="batchDeleteObjs" @after="getTableData"
:api="'asset/field/meta'" v-has="'expr_temp_delete'" id="meta-msg-batch-delete"></delete-button> id="meta-msg-batch-delete" v-has="'asset_label_delete'" :api="url"></delete-button>
</template> </template>
<template v-slot:default="slotProps"> <template v-slot:default="slotProps">
<el-table <asset-meta-table
id="role-list-table"
ref="dataTable" ref="dataTable"
v-loading="tools.loading" v-loading="slotProps.loading"
:data="tableData" :api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight" :height="mainTableHeight"
border :table-data="tableData"
@header-dragend="dragend" @del="del"
@sort-change="tableDataSort" @edit="edit"
@selection-change="(selection)=>{batchDeleteObjs=selection}" @orderBy="tableDataSort"
> @reload="getTableData"
<el-table-column @selectionChange="selectionChange"
:resizable="false" @showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"
align="center" ></asset-meta-table>
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</span>
</template>
<template slot-scope="scope" :column="item">
<div v-if="item.prop === 'group'">
{{scope.row[item.prop] ? scope.row[item.prop].name : '-'}}
</div>
<div v-else-if=" item.prop === 'display' ">
<el-switch
v-model="scope.row[item.prop]"
active-color="#ee9d3f"
:active-value="1"
@change="putMeta(scope.row)"
:inactive-value="0">
</el-switch>
</div>
<div v-else-if=" item.prop === 'search' ">
<el-switch
v-model="scope.row[item.prop]"
active-color="#ee9d3f"
:active-value="1"
@change="putMeta(scope.row)"
:inactive-value="0">
</el-switch>
</div>
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop] || '-'}}</span>
<template v-else>-</template>
</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="$refs.dataList.showBottomBox('operationLog', 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]" :disabled="isBuildIn(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, `asset/field/meta?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><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>
<!-- 回到table顶部的按钮 --> <!-- 回到table顶部的按钮 -->
<button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button> <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
</template> </template>
@@ -137,62 +70,29 @@ import assetMetaGroup from '@/components/common/rightBox/assetMetaGroup'
import assetMetaBox from '@/components/common/rightBox/assetMetaBox' import assetMetaBox from '@/components/common/rightBox/assetMetaBox'
import selectGroup from '@/components/common/popBox/selectAssetMetaGroup' import selectGroup from '@/components/common/popBox/selectAssetMetaGroup'
import nzDataList from '@/components/common/table/nzDataList' import nzDataList from '@/components/common/table/nzDataList'
import tableMixin from '@/components/common/mixin/table' import dataListMixin from '@/components/common/mixin/dataList'
import assetMetaTable from '@/components/common/table/asset/assetMetaTable'
export default { export default {
name: 'assetMeta', name: 'assetMeta',
components: { components: {
deleteButton, deleteButton,
assetMetaGroup, assetMetaGroup,
assetMetaBox,
selectGroup, selectGroup,
nzDataList nzDataList,
assetMetaBox,
assetMetaTable
}, },
mixins: [tableMixin], mixins: [dataListMixin],
data () { data () {
return { return {
url: 'asset/field/meta',
tableId: 'assetMeta', tableId: 'assetMeta',
// 侧滑 // 侧滑
rightBox: { rightBox: {
metaShow: false, metaShow: false,
groupShow: false groupShow: false
}, },
tableTitle: [
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.assetMeta.name'),
prop: 'name',
show: true
}, {
label: this.$t('config.assetMeta.key'),
prop: 'metaKey',
show: true
}, {
label: this.$t('config.assetMeta.group'),
prop: 'group',
show: true
}, {
label: this.$t('config.assetMeta.search'),
prop: 'search',
show: true
}, {
label: this.$t('config.assetMeta.display'),
prop: 'display',
show: true
}, {
label: this.$t('config.assetMeta.type'),
prop: 'type',
show: true
}, {
label: this.$t('config.assetMeta.params'),
prop: 'param',
show: false
}
],
groupData: [{ groupData: [{
name: this.$t('config.assetMeta.all'), name: this.$t('config.assetMeta.all'),
id: -1, id: -1,
@@ -233,7 +133,6 @@ export default {
param: {}, param: {},
remark: '' remark: ''
}, },
object: {},
blankMetaGroup: { blankMetaGroup: {
id: '', id: '',
name: '', name: '',
@@ -266,25 +165,21 @@ export default {
if (!this.searchLabel.groupId) { if (!this.searchLabel.groupId) {
delete this.searchLabel.groupId delete this.searchLabel.groupId
} }
this.$get('asset/field/meta', this.searchLabel).then(response => { this.$get(this.url, this.searchLabel).then(response => {
this.tools.loading = false this.tools.loading = false
if (response.code == 200) { if (response.code == 200) {
this.tableData = response.data.list this.tableData = response.data.list
this.pageObj.total = response.data.total this.pageObj.total = response.data.total
this.nowTime = this.utcTimeToTimezoneStr(response.time) this.nowTime = this.utcTimeToTimezoneStr(response.time)
// console.info(this.$refs.dataTable)
if (!this.scrollbarWrap) { if (!this.scrollbarWrap) {
this.$nextTick(() => { this.$nextTick(() => {
this.scrollbarWrap = this.$refs.dataTable.bodyWrapper this.scrollbarWrap = this.$refs.dataTable.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap) this.toTopBtnHandler(this.scrollbarWrap)
}) })
} }
} }
}) })
}, },
afterTableListChange () {
this.getTableData()
},
addGroup () { addGroup () {
this.metaGroup = JSON.parse(JSON.stringify(this.blankMetaGroup)) this.metaGroup = JSON.parse(JSON.stringify(this.blankMetaGroup))
this.rightBox.groupShow = true this.rightBox.groupShow = true
@@ -330,26 +225,16 @@ export default {
this.getTableData() this.getTableData()
}, },
add () { add () {
this.assetMeta = JSON.parse(JSON.stringify(this.blankObject)) this.object = JSON.parse(JSON.stringify(this.blankObject))
this.rightBox.metaShow = true this.rightBox.metaShow = true
}, },
edit (row) { edit (row) {
this.$get('asset/field/meta/' + row.id).then(res => { /* this.$get('asset/field/meta/' + row.id).then(res => {
this.assetMeta = { ...res.data, param: JSON.parse(res.data.param) } this.object = { ...res.data, param: JSON.parse(res.data.param) }
this.rightBox.metaShow = true this.rightBox.metaShow = true
}) }) */
}, this.object = JSON.parse(JSON.stringify(row))
putMeta (row) { this.rightBox.metaShow = true
this.tools.loading = true
this.$put('asset/field/meta', row).then(response => {
this.prevent_opt.save = false
if (response.code === 200) {
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
} else {
this.$message.error(response.msg)
}
this.getTableData()
})
}, },
closeRightBox (refresh) { closeRightBox (refresh) {
this.rightBox.metaShow = false this.rightBox.metaShow = false

View File

@@ -10,12 +10,11 @@
<template v-slot:top-tool-right> <template v-slot:top-tool-right>
<export-excel <export-excel
id="expression-template-list" id="expression-template-list"
v-has="'expressionTemplate_add'"
export-url="expression/tmpl/export" export-url="expression/tmpl/export"
import-url="expression/tmpl/import" import-url="expression/tmpl/import"
export-file-name="expression-template" export-file-name="expression-template"
:params="searchLabel" :params="searchLabel"
:permissions="{import: 'asset_import', export: 'asset_export'}" :permissions="{import: 'expressionTemplate_add', export: 'expressionTemplate_view'}"
@afterImport="getTableData" @afterImport="getTableData"
class="top-tool-export margin-r-10" class="top-tool-export margin-r-10"
> >
@@ -39,6 +38,7 @@
:table-data="tableData" :table-data="tableData"
@del="del" @del="del"
@edit="edit" @edit="edit"
@copy="(row) => {copyRow(row, 'exprTmpl')}"
@orderBy="tableDataSort" @orderBy="tableDataSort"
@reload="getTableData" @reload="getTableData"
@selectionChange="selectionChange" @selectionChange="selectionChange"