2025-05-21 15:29:38 +08:00

350 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>