350 lines
12 KiB
Vue
Raw Normal View History

2025-05-21 15:29:38 +08:00
<template>
<div class="app-container-flex">
<el-container>
<el-header>
{{titleName}}
<el-divider/>
</el-header>
<el-main v-loading="loading">
<el-form ref="form" :model="form" :rules="rules" label-width="130px" label-position="right" :disabled="!editable">
<el-row>
<el-col :span="24">
<el-form-item label="策略类型" prop="strategyType">
<el-radio-group v-model="form.strategyType" @input="strategyTypeChange">
<el-radio
v-for="dict in dict.type.gateway_strategy_type"
:key="dict.value"
:label="dict.value"
:disabled="disabledType(dict.value)"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="策略名称" prop="strategyName">
<el-input v-model="form.strategyName" clearable placeholder="描述性的名称,用于识别和管理该策略" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="策略描述" prop="description">
<el-input v-model="form.description" type="textarea" placeholder="请输入策略描述" />
</el-form-item>
</el-col>
<!-- 认证策略 start -->
<!-- 认证策略 end -->
<!-- 鉴权策略 start -->
<!-- 鉴权策略 end -->
<!-- 限流策略 start-->
<template v-if="form.strategyType === 'CURRENT_LIMITING'">
<el-col :span="8">
<el-form-item label="限流阈值" prop="currentLimitingThreshold">
<template slot="label">
<span>限流阈值</span>
<el-popover
placement="top-start"
width="280"
trigger="hover"
>
<span slot="reference"><i class="el-icon-info ml10"></i></span>
<p class="tip">设置限流的阈值即允许通过的请求次数或者并发连接数</p>
</el-popover>
</template>
<el-input-number
v-model="form.currentLimitingThreshold"
placeholder="请输入限流阈值"
:min="0"
:controls="false"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="限流时间窗口" prop="currentLimitingTimeWindow">
<template slot="label">
<span>限流时间窗口</span>
<el-popover
placement="top-start"
trigger="hover"
>
<span slot="reference"><i class="el-icon-info ml10"></i></span>
<p class="tip">限流时间窗口单位s</p>
</el-popover>
</template>
<el-input-number
v-model="form.currentLimitingTimeWindow"
placeholder="请输入限流时间窗口"
:min="0"
:controls="false"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="限流响应" prop="currentLimitingResponse">
<template slot="label">
<span>限流响应</span>
<el-popover
placement="top-start"
trigger="hover"
>
<span slot="reference"><i class="el-icon-info ml10"></i></span>
<p class="tip">限流响应JSON字符串</p>
</el-popover>
</template>
<el-input
v-model="form.currentLimitingResponse"
:autosize="{ minRows: 4}"
type="textarea"
placeholder="请输入限流响应"
/>
</el-form-item>
</el-col>
</template>
<!-- 限流策略 end -->
<!-- 熔断策略 start -->
<template v-if="form.strategyType === 'CIRCUIT_BREAKER'">
<el-col :span="8">
<el-form-item label="熔断阈值" prop="circuitBreakerThreshold">
<el-input-number
v-model="form.circuitBreakerThreshold"
placeholder="请输入熔断阈值"
:min="0"
:controls="false"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="熔断时间窗口" prop="circuitBreakerTimeWindow">
<template slot="label">
<span>熔断时间窗口</span>
<el-popover
placement="top-start"
trigger="hover"
>
<span slot="reference"><i class="el-icon-info ml10"></i></span>
<p class="tip">调用失败阈值对应的时间窗口单位s</p>
</el-popover>
</template>
<el-input-number
v-model="form.circuitBreakerTimeWindow"
placeholder="请输入熔断时间窗口"
:min="0"
:controls="false"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="恢复时间间隔" prop="circuitBreakerRecoveryInterval">
<template slot="label">
<span>恢复时间间隔</span>
<el-popover
placement="top-start"
trigger="hover"
>
<span slot="reference"><i class="el-icon-info ml10"></i></span>
<p class="tip">熔断后的恢复时间间隔单位s</p>
</el-popover>
</template>
<el-input-number
v-model="form.circuitBreakerRecoveryInterval"
placeholder="请输入恢复时间间隔"
:min="0"
:controls="false"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="熔断响应" prop="circuitBreakerResponse">
<template slot="label">
<span>熔断响应</span>
<el-popover
placement="top-start"
trigger="hover"
>
<span slot="reference"><i class="el-icon-info ml10"></i></span>
<p class="tip">熔断响应JSON字符串</p>
</el-popover>
</template>
<el-input
v-model="form.circuitBreakerResponse"
type="textarea"
:autosize="{ minRows: 4}"
placeholder="请输入熔断响应"
/>
</el-form-item>
</el-col>
</template>
<!-- 熔断策略 end -->
</el-row>
</el-form>
</el-main>
<el-footer class="footer">
<el-button :disabled="btnLoading" @click="close">取消</el-button>
<el-button v-if="editable" type="primary" :loading="btnLoading" @click="submitForm">保存</el-button>
</el-footer>
</el-container>
</div>
</template>
<script>
import EventBus from '@/utils/eventBus'
import { deepClone } from '@/utils'
import { updateStrategy, getStrategy, addStrategy } from "@/api/gateway/strategy";
let CACHEFOEM;
export default {
components: { },
dicts: ['gateway_strategy_type'],
data() {
return {
loading: false,
btnLoading: false,
form: {
id: void 0,
strategyType: 'CURRENT_LIMITING',
strategyName: void 0,
description: void 0,
currentLimitingThreshold: void 0,
currentLimitingTimeWindow: void 0,
currentLimitingResponse: '{"msg":"到达限流阈值,请稍后重试!","code":500}',
circuitBreakerThreshold: void 0,
circuitBreakerTimeWindow: void 0,
circuitBreakerRecoveryInterval: void 0,
circuitBreakerResponse: '{"msg":"到达熔断阈值,请稍后重试!","code":500}',
},
rules: {
strategyType: [
{ required: true, message: '策略类型不能为空', trigger: 'change' }
],
strategyName:[
{ required: true, message: '策略名称不能为空', trigger: 'blur' }
],
currentLimitingThreshold: [
{ required: true, message: '限流阈值不能为空', trigger: 'blur' }
],
currentLimitingTimeWindow: [
{ required: true, message: '限流时间窗口不能为空', trigger: 'blur' }
],
currentLimitingResponse: [
{ required: true, message: '限流响应不能为空', trigger: 'blur' }
],
circuitBreakerThreshold: [
{ required: true, message: '熔断阈值不能为空', trigger: 'blur' }
],
circuitBreakerTimeWindow: [
{ required: true, message: '熔断时间窗口不能为空', trigger: 'blur' }
],
circuitBreakerRecoveryInterval: [
{ required: true, message: '恢复时间间隔不能为空', trigger: 'blur' }
],
circuitBreakerResponse: [
{ required: true, message: '熔断响应不能为空', trigger: 'blur' }
],
}
}
},
computed: {
editable() {
return this.$route.query.type !== 'detail'
},
titleName() {
if (!this.editable) {
return '策略详情'
}
return this.$route.query.id ? '编辑策略' : '新增策略'
},
},
created() {
this.getDetail()
},
activated() {
this.getDetail()
},
methods: {
disabledType(type) {
return !(['CURRENT_LIMITING', 'CIRCUIT_BREAKER'].includes(type)) || !!(this.form.id);
},
async getDetail() {
const { id } = this.$route.query
if (id) {
this.loading = true;
try {
const { data } = await getStrategy(id)
this.form = data;
CACHEFOEM = deepClone(data);
} catch (error) {
this.$message.error(error.message || '请求失败')
}
this.loading = false;
}
},
// 表单重置
reset() {
this.form = {
id: void 0,
strategyType: 'CURRENT_LIMITING',
strategyName: void 0,
description: void 0,
currentLimitingThreshold: void 0,
currentLimitingTimeWindow: void 0,
currentLimitingResponse: '{"msg":"到达限流阈值,请稍后重试!","code":500}',
circuitBreakerThreshold: void 0,
circuitBreakerTimeWindow: void 0,
circuitBreakerRecoveryInterval: void 0,
circuitBreakerResponse: '{"msg":"到达熔断阈值,请稍后重试!","code":500}',
};
this.resetForm("form");
},
strategyTypeChange() {
const { id, strategyType } = this.form;
this.reset();
if (CACHEFOEM && strategyType === CACHEFOEM.strategyType) {
Object.keys(this.form).forEach((key) => {
this.form[key] = CACHEFOEM[key];
})
} else {
this.form.id = id;
this.form.strategyType = strategyType;
}
},
async submitForm() {
const request = this.form.id != null ? updateStrategy : addStrategy;
const msg = this.form.id != null ? '修改' : '新增';
await this.$refs.form.validate();
try {
this.btnLoading = true;
await request(this.form);
this.$modal.msgSuccess(`${msg}成功`);
EventBus.$emit('reloadStratefyList');
this.close();
} catch (error) {
this.$modal.msgError(`${msg}失败`);
}
this.btnLoading = false;
},
close() {
this.$tab.closePage();
},
}
}
</script>
<style lang="scss" scoped>
.footer {
display: flex;
align-items: center;
justify-content: flex-end;
}
::v-deep.el-input-number .el-input__inner{
text-align: left;
}
.el-icon-info {
color: #959595;
cursor: pointer;
}
.tip {
color: #999;
font-size: 14px;
margin: 0;
}
</style>