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

355 lines
13 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>
<el-row type="flex" justify="space-between">
<span>网关设置</span>
<div>
<el-button
type="primary"
size="mini"
:icon="editable ? 'el-icon-close' : `el-icon-edit`"
plain
@click="handleToggle"
:disabled="loading || btnLoading"
>{{ editable ? '取消' : '编辑' }}</el-button>
<el-button
type="primary"
size="mini"
icon="el-icon-setting"
plain
@click="handleSyncConfig"
:disabled="loading || btnLoading || syncLoading"
>同步配置</el-button>
</div>
</el-row>
<el-divider class="mt10 mb10" />
</el-header>
<el-main v-loading="loading">
<el-form
ref="form"
:model="form"
:rules="rules"
label-position="left"
size="mini"
:disabled="!editable"
:validate-on-rule-change="false"
>
<el-row :gutter="40">
<!-- <el-col :span="24">
<el-form-item label="限流">
<el-switch v-model="limiting" />
</el-form-item>
</el-col> -->
<el-col :span="12">
<el-form-item label="API限流默认配置" prop="apiCurrentLimitingStatus" label-width="145px">
<template slot="label">
<span>API限流默认配置</span>
<el-popover
placement="top-start"
width="360"
trigger="hover"
>
<span slot="reference"><i class="el-icon-info ml10"></i></span>
<p class="tip">1.对开启默认限流配置开关之前的历史API不受影响</p>
<p class="tip">2.对已经生效了的使用默认限流配置的API在下次修改默认配置时同样会生效</p>
<p class="tip">3.单个API限流配置会覆盖API默认限流配置</p>
</el-popover>
</template>
<el-switch v-model="form.apiCurrentLimitingStatus" active-value="1" inactive-value="0" />
</el-form-item>
<el-form-item label="限流阈值" prop="apiCurrentLimitingThreshold" label-width="106px">
<el-input-number
v-model="form.apiCurrentLimitingThreshold"
placeholder="设置限流的阈值,即允许通过的请求次数或者并发连接数"
:min="1"
:controls="false"
/>
</el-form-item>
<el-form-item label="限流时间窗口" prop="apiCurrentLimitingTimeWindow" label-width="106px">
<el-input-number
v-model="form.apiCurrentLimitingTimeWindow"
placeholder="请输入限流时间窗口"
:min="1"
:controls="false"
/>
</el-form-item>
<el-form-item label="限流响应" prop="apiCurrentLimitingDefaultResponse">
<el-input
v-model="form.apiCurrentLimitingDefaultResponse"
:autosize="{ minRows: 4, maxRows: 4}"
type="textarea"
placeholder="限流响应JSON字符串"
/>
</el-form-item>
<el-form-item label="数据加密" prop="dataEncryptionStatus">
<el-switch v-model="form.dataEncryptionStatus" active-value="1" inactive-value="0" />
</el-form-item>
<el-form-item label="加密算法" prop="encryptionAlgorithm" label-width="80px">
<el-radio-group v-model="form.encryptionAlgorithm">
<el-radio label="ECC" border>ECC</el-radio>
<el-radio label="RSA" border>RSA</el-radio>
<el-radio label="SM2" border>国密</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="`${isRSA ? '私钥' : '秘钥'}内容`" prop="privateKey" label-width="80px">
<el-input
v-model="form.privateKey"
:autosize="{ minRows: 4, maxRows: 4}"
type="textarea"
:placeholder="`请输入${isRSA ? '私钥' : '秘钥'}内容`"
/>
</el-form-item>
<template v-if="isRSA">
<el-form-item label="公钥内容" prop="publicKey" label-width="80px">
<el-input
v-model="form.publicKey"
:autosize="{ minRows: 4, maxRows: 4}"
type="textarea"
placeholder="请输入公钥内容"
/>
</el-form-item>
</template>
</el-col>
<el-col :span="12">
<el-form-item label="APP限流默认配置" prop="appCurrentLimitingStatus" label-width="150px">
<template slot="label">
<span>APP限流默认配置</span>
<el-popover
placement="top-start"
width="360"
trigger="hover"
>
<span slot="reference"><i class="el-icon-info ml10"></i></span>
<p class="tip">1.对开启默认限流配置开关之前的历史APP不受影响</p>
<p class="tip">2.对已经生效了的使用默认限流配置的APP在下次修改默认配置时同样会生效</p>
<p class="tip">3.单个APP限流配置会覆盖APP默认限流配置</p>
</el-popover>
</template>
<el-switch v-model="form.appCurrentLimitingStatus" active-value="1" inactive-value="0" />
</el-form-item>
<el-form-item label="限流阈值" prop="appCurrentLimitingThreshold" label-width="106px">
<el-input-number
v-model="form.appCurrentLimitingThreshold"
placeholder="设置限流的阈值,即允许通过的请求次数或者并发连接数"
:min="1"
:controls="false"
/>
</el-form-item>
<el-form-item label="限流时间窗口" prop="appCurrentLimitingTimeWindow" label-width="106px">
<el-input-number
v-model="form.appCurrentLimitingTimeWindow"
placeholder="请输入限流时间窗口"
:min="1"
:controls="false"
/>
</el-form-item>
<el-form-item label="限流响应" prop="appCurrentLimitingDefaultResponse">
<el-input
v-model="form.appCurrentLimitingDefaultResponse"
:autosize="{ minRows: 4, maxRows: 4}"
type="textarea"
placeholder="限流响应JSON字符串"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-main>
<el-footer v-if="editable">
<el-row type="flex" justify="end">
<el-button :disabled="btnLoading" @click="close">返回</el-button>
<el-button type="primary" :loading="btnLoading" @click="submitForm">保存</el-button>
</el-row>
</el-footer>
</el-container>
</div>
</template>
<script>
import { deepClone } from '@/utils'
import { getGatewayConfig, updateGatewayConfig, updateGatewaySync } from '@/api/gateway/config'
let CACHEFOEM;
export default {
data() {
return {
editable: false,
loading: false,
btnLoading: false,
syncLoading: false,
form: {
apiCurrentLimitingStatus: '0',
apiCurrentLimitingThreshold: void 0,
apiCurrentLimitingTimeWindow: void 0,
apiCurrentLimitingDefaultResponse: void 0,
appCurrentLimitingStatus: '0',
appCurrentLimitingThreshold: void 0,
appCurrentLimitingTimeWindow: void 0,
appCurrentLimitingDefaultResponse: void 0,
dataEncryptionStatus: '0',
encryptionAlgorithm: void 0,
privateKey: void 0,
publicKey: void 0,
},
}
},
computed: {
isRSA() {
return this.form.encryptionAlgorithm === 'RSA'
},
apiRequired() {
return this.form.apiCurrentLimitingStatus === '1'
},
appRequired() {
return this.form.appCurrentLimitingStatus === '1'
},
dataEncryRequired() {
return this.form.dataEncryptionStatus === '1'
},
rules() {
return {
// apiCurrentLimitingStatus: [
// { required: true, message: 'API限流默认配置不能为空', trigger: 'change' }
// ],
apiCurrentLimitingThreshold: [
{ required: this.apiRequired, message: '限流阈值不能为空', trigger: 'blur' }
],
apiCurrentLimitingTimeWindow: [
{ required: this.apiRequired, message: '限流时间窗口不能为空', trigger: 'blur' }
],
apiCurrentLimitingDefaultResponse: [
{ required: this.apiRequired, message: '限流响应不能为空', trigger: 'blur' }
],
// appCurrentLimitingStatus: [
// { required: true, message: 'APP限流默认配置不能为空', trigger: 'change' }
// ],
appCurrentLimitingThreshold: [
{ required: this.appRequired, message: '限流阈值不能为空', trigger: 'blur' }
],
appCurrentLimitingTimeWindow: [
{ required: this.appRequired, message: '限流时间窗口不能为空', trigger: 'blur' }
],
appCurrentLimitingDefaultResponse: [
{ required: this.appRequired, message: '限流响应不能为空', trigger: 'blur' }
],
// dataEncryptionStatus: [
// { required: true, message: '数据加密默认配置不能为空', trigger: 'change' }
// ],
encryptionAlgorithm: [
{ required: this.dataEncryRequired, message: '加密算法不能为空', trigger: 'change' }
],
privateKey: [
{ required: this.dataEncryRequired, message: '秘钥内容不能为空', trigger: 'blur' }
],
publicKey: [
{ required: this.dataEncryRequired, message: '公钥内容不能为空', trigger: 'blur' }
]
}
}
},
created() {
this.getDetail()
},
methods: {
async getDetail() {
try {
this.loading = true;
const {code, data} = await getGatewayConfig();
if (code === 200) {
Object.keys(this.form).forEach((key) => {
this.form[key] = data[key];
})
this.$nextTick(() => {
CACHEFOEM = deepClone(this.form);
})
}
this.loading = false;
} catch (error) {
this.loading = false;
}
},
async handleToggle() {
await this.validateChange();
if (this.editable) this.$refs.form.clearValidate();
this.editable = !this.editable;
},
async handleSyncConfig() {
await this.$modal.confirm('确定同步网关配置吗?', '提示', {
distinguishCancelAndClose: true,
confirmButtonText: '确定',
cancelButtonText: '取消'
})
try {
this.syncLoading = true;
const res = await updateGatewaySync();
if (res.code === 200) {
this.$modal.msgSuccess('同步配置成功')
this.getDetail();
} else {
this.$modal.msgError(res.msg || '同步配置失败')
}
this.syncLoading = false;
} catch (error) {
this.syncLoading = false;
}
},
async submitForm() {
// if (!this.apiRequired && !this.appRequired && !this.dataEncryRequired) {
// this.$modal.msgError('请至少选择一种配置')
// return
// }
await this.$refs.form.validate();
try {
this.btnLoading = true;
await updateGatewayConfig(this.form);
this.$modal.msgSuccess('保存成功')
this.getDetail();
this.btnLoading = false;
} catch (error) {
this.$modal.msgError(error.message || '保存失败')
this.btnLoading = false;
}
},
validateChange() {
if (!this.editable || JSON.stringify(this.form) === JSON.stringify(CACHEFOEM)) {
return Promise.resolve();
}
return this.$modal.confirm('当前有未保存的配置,是否放弃修改?', '提示', {
distinguishCancelAndClose: true,
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
this.form = deepClone(CACHEFOEM);
})
},
close() {
this.validateChange().then(() => {
this.$tab.closePage();
})
}
}
}
</script>
<style lang="scss" scoped>
::v-deep.el-input-number {
width: 100%;
.el-input__inner {
text-align: left;
}
}
.el-icon-info {
color: #959595;
cursor: pointer;
}
.tip {
color: #999;
font-size: 14px;
margin: 0;
}
</style>