355 lines
13 KiB
Vue
355 lines
13 KiB
Vue
<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> |