You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

382 lines
12 KiB

This file contains ambiguous Unicode characters!

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

<template>
<a-drawer
:title="title"
:maskClosable="true"
width="45%"
placement="right"
v-if="visible"
:closable="true"
@close="handleCancel"
:visible="visible"
style="overflow: auto;padding-bottom: 53px;">
<a-form-model ref="form" :layout="layout" :label-col="labelCol" :wrapper-col="wrapperCol" :model="router">
<a-form-model-item label="路由ID">
<a-input v-model="router.routerId" placeholder="路由唯一ID"/>
</a-form-model-item>
<a-form-model-item label="路由名称">
<a-input v-model="router.name" placeholder="路由名称"/>
</a-form-model-item>
<a-form-model-item label="路由URI">
<a-input v-model="router.uri" placeholder="路由URL"/>
</a-form-model-item>
<a-form-model-item label="路由状态" prop="status">
<a-switch default-checked v-model="router.status"/>
</a-form-model-item>
<a-form-model-item prop="predicates" label="路由条件">
<div v-for="(item,index) in router.predicates">
<a-divider>{{item.name}}
<a-icon type="delete" size="22" @click="removePredicate(router,index)"/>
</a-divider>
<!--name genKeyRouter keykey -->
<div v-if="genKeyRouter.includes(item.name)">
<template v-for="(tag, tagIndex) in item.args">
<a-input v-if="tagIndex==currentTagIndex&&index==currentNameIndex" ref="input" type="text" size="small"
:style="{ width: '190px' }"
:value="tag"
@change="handleInputChange" @blur="handleInputEditConfirm(item,tag,tagIndex)"
@keyup.enter="handleInputEditConfirm(item,tag,tagIndex)"/>
<a-tag v-else :key="tag" :closable="true" @close="() => removeTag(item,tag)" @click="editTag(tag,tagIndex,index)">
{{ tag }}
</a-tag>
</template>
<a-input v-if="inputVisible&&index==currentNameIndex" ref="input" type="text" size="small"
:style="{ width: '100px' }"
:value="inputValue"
@change="handleInputChange" @blur="handleInputConfirm(item)"
@keyup.enter="handleInputConfirm(item)"/>
<a-tag v-else style="background: #fff; borderStyle: dashed;" @click="showInput(item,index)">
<a-icon type="plus"/>
{{item.name}}
</a-tag>
</div>
<!--name genKeyRouter key-->
<div v-if="!genKeyRouter.includes(item.name)">
<template v-for="(value, key) in item.args">
<a-row>
<a-col :span="5" style="margin-top:2px">
<span v-if="key=='header'" >Header</span>
<span v-if="key=='regexp'"></span>
<span v-if="key=='param'"></span>
<span v-if="key=='name'">Cookie</span>
</a-col>
<a-col :span="18">
<a-input :defaultValue="value" placeholder="参数值" style="width: 70%; margin-right: 8px;margin-top: 3px" @change="(e)=>valueChange(e,item.args,key)"/>
</a-col>
</a-row>
</template>
</div>
</div>
<p class="btn" style="padding-top: 10px">
<a-dropdown>
<a-menu slot="overlay">
<a-menu-item :key="item.name" v-for="item in tagArray" @click="predicatesHandleMenuClick(item)">{{item.name}}</a-menu-item>
</a-menu>
<a-button type="dashed" style="margin-left: 8px;width:100%">
<a-icon type="down"/>
</a-button>
</a-dropdown>
</p>
</a-form-model-item>
<a-form-model-item prop="predicates" label="过滤器">
<div v-for="(item,index) in router.filters">
<a-divider>{{item.name}}
<a-icon type="delete" size="22" @click="removeFilter(router,index)"/>
</a-divider>
<div v-for="(tag, index) in item.args" :key="tag.key">
<a-input v-model="tag.key" placeholder="参数键" style="width: 45%; margin-right: 8px"/>
<a-input v-model="tag.value" placeholder="参数值" style="width: 40%; margin-right: 8px"/>
<a-icon class="dynamic-delete-button" type="minus-circle-o" @click="removeFilterParams(item,index)"/>
</div>
<a-button type="dashed" style="margin-left:28%;width: 30%" size="small" @click="addFilterParams(item)">
<a-icon type="plus"/>
</a-button>
</div>
<p class="btn" style="padding-top: 10px">
<a-dropdown>
<a-menu slot="overlay" @click="filterHandleMenuClick">
<a-menu-item :key="item.key" :name="item.name" v-for="item in filterArray">{{item.name}}</a-menu-item>
</a-menu>
<a-button type="dashed" style="margin-left: 8px;width:100%">
<a-icon type="down"/>
</a-button>
</a-dropdown>
</p>
</a-form-model-item>
<a-row :style="{textAlign:'right'}" class="drawer-bootom-button">
<a-button :style="{marginRight: '8px'}" @click="handleCancel">
</a-button>
<a-button @click="handleSubmit" type="primary"></a-button>
</a-row>
</a-form-model>
</a-drawer>
</template>
<script>
import { postAction } from '@/api/manage'
export default {
name: 'GateWayRouteModal',
components: {},
data() {
return {
layout: 'horizontal',
labelCol: { span: 3 },
wrapperCol: { span: 14 },
currentNameIndex: 0,
currentTagIndex:-1,
predicates: {},
filterArray: [ { key: 1, name: '' }],
//gateway对应的规则key
tagArray: [
{
name:'Path',
args:[]
},
{
name:'Header',
args:{
header:'',
regexp:''
}
},
{
name:'Query',
args:{
param:'',
regexp:''
}
},
{
name:'Method',
args:[]
},
{
name:'Host',
args:[]
},
{
name:'Cookie',
args:{
name:'',
regexp:''
}
},
{
name:'After',
args:[]
},
{
name:'Before',
args:[]
},
{
name:'Between',
args:[]
},
{
name:'RemoteAddr',
args:[]
}
],
inputVisible: false,
inputValue: '',
url: {
update: '/sys/gatewayRoute/updateAll',
clear: '/sys/gatewayRoute/clearRedis'
},
router: this.getRouter(),
title: '',
visible: false,
loading: false,
genKeyRouter:["Path","Host","Method","After","Before","Between","RemoteAddr"]
}
},
methods: {
getRouter() {
return {
routerId: '',
name: '',
uri: '',
predicates: [],
filters: []
}
},
show(router) {
if (router) {
router.status=Boolean(router.status)
this.router = router
} else {
this.router = this.getRouter()
this.inputValue=''
}
this.visible = true
this.currentTagIndex=-1
this.currentNameIndex=-1
},
close() {
this.reset()
this.$emit('close')
this.$refs['form'].resetFields()
this.visible = false
},
//删除路由条件配置项
removeTag(item, removedTag) {
const tags = item.args.filter(tag => tag !== removedTag)
item.args = tags
},
//添加路由选项
predicatesHandleMenuClick(e) {
this.router.predicates.push({
args: e.args,
name: e.name,
})
},
editTag(tag, tagIndex,index){
this.currentNameIndex = index;
this.currentTagIndex=tagIndex
},
/**
* 值修改事件
* @param e
* @param item
* @param key
*/
valueChange(e,item,key){
item[key]=e.target.value
},
//显示输入框
showInput(item, index) {
this.inputVisible = true
this.currentNameIndex = index
},
//路由选项输入框失去焦点事件
handleInputChange(e) {
this.inputValue = e.target.value
},
//删除路由条件
removePredicate(item, index) {
item.predicates.splice(index, 1)
},
//删除过滤器参数
removeFilterParams(item, index) {
item.args.splice(index, 1)
},
//删除过滤器
removeFilter(item, index) {
item.filters.splice(index, 1)
},
//添加过滤器参数
addFilterParams(item) {
item.args.push({
key: 'key' + item.args.length + 1,
value: ''
})
},
//过滤器添加事件
filterHandleMenuClick(e) {
if (e.key == 0) {
this.router.filters.push({
args: [ {
key: 'name',
value: 'default'
},{
key: 'fallbackUri',
value: 'forward:/fallback'
}],
name:'Hystrix',
title: this.filterArray[0].name
})
}
if (e.key == 1) {
this.router.filters.push({
args: [ {
key: 'key-resolver',
value: '#{@ipKeyResolver}'
}, {
key: 'redis-rate-limiter.replenishRate',
value: 20
}, {
key: 'redis-rate-limiter.burstCapacity',
value: 20
}],
name:"RequestRateLimiter",
title: this.filterArray[0].name
})
}
},
//输入框确认
handleInputConfirm(item) {
const inputValue = this.inputValue
let tags = item.args
if (inputValue && tags.indexOf(inputValue) === -1) {
item.args = [...tags, inputValue]
}
console.log(tags)
Object.assign(this, {
tags,
inputVisible: false,
inputValue: ''
})
this.currentTagIndex=-1
},
//输入框确认
handleInputEditConfirm(item,tag,index) {
if(this.inputValue)
{
const inputValue = this.inputValue
item.args[index]=inputValue
}
this.currentTagIndex=-1
},
reset() {
this.expandedKeysss = []
this.checkedKeys = []
this.defaultCheckedKeys = []
this.loading = false
},
//关闭弹窗
handleCancel() {
this.close()
},
//提交路由
handleSubmit() {
let { predicates, filters, ...other } = this.router
let router = other
router.predicates = JSON.stringify(this.router.predicates)
router.filters = JSON.stringify(this.router.filters)
postAction(this.url.update, {
router
}).then(res => {
if (res.success) {
this.close()
this.$emit('ok')
this.$message.success(res.message)
} else {
this.$message.error(res.message)
}
})
}
}
}
</script>
<style lang="less" scoped>
.drawer-bootom-button {
position: absolute;
bottom: 0;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>