blob: 780b9c6f89186f572929f94b19a204bfb0caa235 [file] [log] [blame]
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<template>
<v-container grid-list-xl fluid>
<v-layout row wrap>
<v-flex lg12>
<Breadcrumb title="trafficGray" :items="breads"></breadcrumb>
</v-flex>
<v-flex lg12>
可在这里了解应用 <a href="https://cn.dubbo.apache.org/zh-cn/overview/tasks/traffic-management/isolation/" target="_blank">灰度环境隔离</a> 的工作原理与使用方式!
</v-flex>
<v-flex lg12>
<v-card flat color="transparent">
<v-card-text>
<v-form>
<v-layout row wrap>
<v-flex xs6 sm3 md9>
<v-text-field
v-model="application"
flat
label="请输入应用名"
></v-text-field>
</v-flex>
<v-btn @click="submit" color="primary" large>{{$t('search')}}</v-btn>
<v-btn @click="create" color="primary" large>新建</v-btn>
</v-layout>
</v-form>
</v-card-text>
</v-card>
</v-flex>
<v-flex xs12>
<v-card>
<v-toolbar flat color="transparent" class="elevation-0">
<v-toolbar-title><span class="headline">{{$t('trafficGray')}}</span></v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
<v-data-table :headers="headers" :items="tableData" hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td >{{props.item.service}}</td>
<td>{{props.item.Gary}}</td>
<td class="text-xs-center px-0" nowrap>
<!-- <v-btn
class="tiny"
color='success'
@click="Check(props.item)"
>
查看
</v-btn> -->
<v-btn
class="tiny"
color='success'
@click="update(props.item)"
>
查看修改
</v-btn>
<v-btn
class="tiny"
outline
@click="deleteItem(props.item)"
>
删除
</v-btn>
</td>
</template>
</v-data-table>
</v-card>
</v-flex>
<v-dialog v-model="dialog" width="800px" persistent >
<v-card>
<v-card-title class="justify-center">
<span class="headline">新增灰度</span>
</v-card-title>
<v-layout row wrap>
<v-flex lg12>
可在这里了解如何为应用设置不同的 <a href="https://cn.dubbo.apache.org/zh-cn/overview/tasks/traffic-management/gray/" target="_blank">灰度流量隔离环境</a>
</v-flex>
</v-layout>
<v-card>
<v-card-text>
<v-layout row warp>
<v-flex xs6 sm3 md8>
<v-text-field
label="application"
hint="请输入application"
v-model="createGary.application"
></v-text-field>
</v-flex>
<v-flex xs6 sm3 md4>
<v-btn
style="margin-left: 20px;"
depressed
color="primary"
@click="addCreateGary"
>
新增
</v-btn>
</v-flex>
</v-layout>
</v-card-text>
<v-card-text v-for="(modal,index) in createGary.tags" :key="index">
<v-flex xs6 sm3 md6>
<v-text-field
label="灰度隔离环境名称"
hint="请输入名称,该值将作为灰度流量的匹配条件"
v-model="modal.name"
></v-text-field>
</v-flex>
<v-layout row wrap v-for="(item,idx) in modal.match" :key="idx">
<v-flex xs6 sm3 md3>
<v-text-field
label="key"
hint="请输入key"
v-model="item.key"
></v-text-field>
</v-flex>
<v-flex xs6 sm3 md3>
<v-select
style="margin-left: 20px;"
:items="items"
label="Outlined style"
v-model="selectedOption[index][idx]"
@change="updateValue"
outlined
></v-select>
</v-flex>
<v-flex xs6 sm3 md>
<v-text-field
style="margin-left: 20px;"
label="value"
hint="请输入匹配的值"
v-model="item.value[selectedOption[index][idx]]"
></v-text-field>
</v-flex>
<v-flex xs6 sm3 md3>
<v-btn
style="margin-left: 20px;"
class="tiny"
color='success'
outline
@click="addItem(index)"
>
新增灰度环境
</v-btn>
</v-flex>
</v-layout>
</v-card-text>
</v-card>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn flat @click.native="closeDialog">{{$t('close')}}</v-btn>
<v-btn depressed color="primary" @click.native="save">{{$t('save')}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="updateDialog" width="800px" persistent >
<v-card>
<v-card-title class="justify-center">
<span class="headline">修改灰度</span>
</v-card-title>
<v-layout row wrap>
<v-flex lg12>
可在这里了解如何为应用设置不同的 <a href="https://cn.dubbo.apache.org/zh-cn/overview/tasks/traffic-management/gray/" target="_blank">灰度流量隔离环境</a>
</v-flex>
</v-layout>
<v-card>
<v-card-text>
<v-layout row warp>
<v-flex xs6 sm3 md8>
<v-text-field
label="application"
hint="请输入 Provider 应用名"
disabled
v-model="updateGary.application"
></v-text-field>
</v-flex>
<v-flex xs6 sm3 md4>
<v-btn
style="margin-left: 20px;"
depressed
color="primary"
@click="addUpdateGary"
>
新增
</v-btn>
</v-flex>
</v-layout>
</v-card-text>
<v-card-text v-for="(modal,index) in updateGary.tags" :key="index">
<v-flex xs6 sm3 md6>
<v-text-field
label="灰度隔离环境名称"
hint="请输入名称,该值将作为灰度流量的匹配条件"
v-model="modal.name"
></v-text-field>
</v-flex>
<v-layout row wrap v-for="(item,idx) in modal.match" :key="idx">
<v-flex xs6 sm3 md3>
<v-text-field
label="key"
hint="请输入key"
v-model="item.key"
></v-text-field>
</v-flex>
<v-flex xs6 sm3 md3>
<v-select
style="margin-left: 20px;"
:items="items"
label="Outlined style"
v-model="selectedUpdateOption[index][idx]"
@change="updateValue(index, idx)"
outlined
></v-select>
</v-flex>
<v-flex xs6 sm3 md>
<v-text-field
style="margin-left: 20px;"
label="value"
hint="请输入匹配的值"
v-model="item.value[selectedUpdateOption[index][idx]]"
></v-text-field>
</v-flex>
<v-flex xs6 sm3 md3>
<v-btn
style="margin-left: 20px;"
class="tiny"
color='success'
outline
@click="addUpdateItem(index)"
>
新增灰度环境
</v-btn>
</v-flex>
</v-layout>
</v-card-text>
</v-card>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn flat @click.native="closeUpdateDialog">{{$t('close')}}</v-btn>
<v-btn depressed color="primary" @click.native="saveUpdate">{{$t('save')}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog
v-model="deleteDialog"
persistent
max-width="290"
>
<v-card>
<v-card-title class="text-h5">
您确认删除这条数据嘛?
</v-card-title>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="green darken-1"
text
@click="deleteDialog = false"
>
取消
</v-btn>
<v-btn
color="green darken-1"
text
@click="confirmDelete"
>
确定
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-layout>
</v-container>
</template>
<script>
import Breadcrumb from '../public/Breadcrumb.vue'
export default {
name: 'Gray',
components: { Breadcrumb },
data: () => ({
breads: [
{
text: 'trafficManagement',
href: ''
},
{
text: 'trafficGray',
href: ''
}
],
typeAhead: [],
input: null,
searchLoading: false,
timerID: null,
service: '',
Gary: '',
mock: '',
group: '',
version: '',
createGroup: '',
createVersion: '',
updateService: '',
updateMock: '',
updateGroup: '',
updateVersion: '',
deleteDialog: false,
createService: '',
createMock: '',
deleteService: '',
deleteMock: '',
deleteVersion: '',
deleteGroup: '',
dialog: false,
selectedOption: [['exact']],
selectedUpdateOption: [[]],
headers: [
],
items: ['empty', 'exact', 'noempty', 'prefix', 'regex', 'wildcard'],
tableData: [],
services: [],
loading: false,
updateDialog: false,
application: '',
updateGary: {},
createGary:
{
application: '',
tags: [
{
name: '',
match: [
{
key: '',
value: {
empty: '',
exact: '',
noempty: '',
prefix: '',
regex: '',
wildcard: ''
}
}
]
}
]
}
}),
methods: {
updateValue (index, idx) {
const temp = {
empty: '',
exact: '',
noempty: '',
prefix: '',
regex: '',
wildcard: ''
}
this.updateGary.tags[index].match[idx].value = temp
},
submit () {
this.search()
},
addCreateGary () {
const temp = {
name: '',
match: [
{
key: '',
value: {
empty: '',
exact: '',
noempty: '',
prefix: '',
regex: '',
wildcard: ''
}
}
]
}
this.selectedOption.push(['exact'])
this.createGary.tags.push(temp)
},
addUpdateGary () {
const temp = {
name: '',
match: [
{
key: '',
value: {
empty: '',
exact: '',
noempty: '',
prefix: '',
regex: '',
wildcard: ''
}
}
]
}
this.selectedUpdateOption.push([])
this.updateGary.tags.push(temp)
},
addItem (params) {
const temp = {
key: '',
value: {
empty: '',
exact: '',
noempty: '',
prefix: '',
regex: '',
wildcard: ''
}
}
const index = parseInt(params)
this.selectedOption[index].push('exact')
this.createGary.tags[index].match.push(temp)
},
addUpdateItem (params) {
const temp = {
key: '',
value: {
empty: '',
exact: '',
noempty: '',
prefix: '',
regex: '',
wildcard: ''
}
}
const index = parseInt(params)
this.updateGary.tags[index].match.push(temp)
},
search () {
this.$axios.get('/traffic/gray', {
params: {
application: this.application
}
}).then(response => {
this.tableData = []
response.data.forEach(element => {
const array = []
element.tags.forEach(item => {
array.push(item.name)
})
const uniqueArray = Array.from(new Set(array))
const Gary = uniqueArray.join('|')
const result = {
service: element.application,
Gary,
element
}
this.tableData.push(result)
})
})
},
saveUpdate () {
this.updateDialog = false
this.$axios.put('/traffic/gray', this.updateGary).then((res) => {
if (res) {
alert('操作成功')
}
})
this.dialog = false
setTimeout(() => {
this.search()
}, 1000)
},
setHeaders: function () {
this.headers = [
{
text: '应用名',
value: 'service'
},
{
text: '灰度环境',
value: 'Gary'
},
{
text: '操作',
value: 'version'
}
]
},
closeUpdateDialog () {
this.updateDialog = false
},
create () {
this.dialog = true
this.createGary = {
application: '',
tags: [
{
name: '',
match: [
{
key: '',
value: {
empty: '',
exact: '',
noempty: '',
prefix: '',
regex: '',
wildcard: ''
}
}
]
}
]
}
},
confirmDelete () {
this.$axios.delete('/traffic/mock',
{
params: {
service: this.deleteService,
group: this.deleteGroup,
version: this.deleteVersion
}
}).then((res) => {
if (res) {
alert('操作成功')
}
})
this.deleteDialog = false
setTimeout(() => {
this.search()
}, 1000)
},
deleteItem (props) {
this.deleteDialog = true
this.deleteService = props.service
},
update (props) {
this.updateGary = props.element
props.element.tags.forEach((item, index) => {
this.selectedUpdateOption[index] = []
item.match.forEach((it, idx) => {
if (it.value.empty !== '') {
this.selectedUpdateOption[index][idx] = 'empty'
} else if (it.value.exact !== '') {
this.selectedUpdateOption[index][idx] = 'exact'
} else if (it.value.noempty !== '') {
this.selectedUpdateOption[index][idx] = 'noempty'
} else if (it.value.prefix !== '') {
this.selectedUpdateOption[index][idx] = 'prefix'
} else if (it.value.regex !== '') {
this.selectedUpdateOption[index][idx] = 'regex'
} else if (it.value.wildcard !== '') {
this.selectedUpdateOption[index][idx] = 'wildcard'
}
})
})
this.updateDialog = true
},
save () {
this.$axios.post('/traffic/gray', this.createGary).then((res) => {
if (res) {
alert('操作成功')
}
})
this.dialog = false
setTimeout(() => {
this.search()
}, 1000)
},
closeDialog () {
this.dialog = false
}
},
watch: {
area () {
this.setHeaders()
}
},
mounted () {
this.setHeaders()
this.application = '*'
this.search()
}
}
</script>