gateway基本功能页面

This commit is contained in:
yin fuxian 2024-04-24 17:24:58 +08:00
parent e922dfbc4a
commit 87f61bc4d8
14 changed files with 953 additions and 151 deletions

View File

@ -42,3 +42,12 @@ export function delInterface(id) {
method: 'delete' method: 'delete'
}) })
} }
// 禁用/启用接口管理
export function changeInterfaceStatus(data) {
return request({
url: '/gateway/interface/status',
method: 'put',
data: data
})
}

View File

@ -42,3 +42,12 @@ export function delServer(id) {
method: 'delete' method: 'delete'
}) })
} }
// 启用/停用接口信息(支持批量)
export function changeServerStatus(data) {
return request({
url: '/gateway/server/status',
method: 'put',
data: data
})
}

View File

@ -42,3 +42,12 @@ export function delStrategy(id) {
method: 'delete' method: 'delete'
}) })
} }
// 禁用/启用策略管理
export function changeStrategyStatus(data) {
return request({
url: '/gateway/strategy/status',
method: 'put',
data: data
})
}

View File

@ -0,0 +1,100 @@
<template>
<el-form ref="queryForm" :inline="true" :model="queryParams" label-width="90px" size="small">
<el-form-item
v-for="item in queryOptions"
:key="item.value"
:label="item.label"
:prop="item.prop"
>
<template v-if="item.type === 'input'">
<el-input
v-model="queryParams[item.prop]"
clearable
:placeholder="`请输入${item.label}`"
@keyup.enter.native="handleQuery"
/>
</template>
<template v-else-if="item.type === 'select'">
<el-select v-model="queryParams[item.prop]" clearable :placeholder="`请选择${item.label}`">
<el-option
v-for="dict in item.dicts"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</template>
<template v-else-if="item.type === 'daterange'">
<el-date-picker
v-model="queryParams[item.prop]"
end-placeholder="结束日期"
range-separator="-"
start-placeholder="开始日期"
style="width: 240px"
type="daterange"
value-format="yyyy-MM-dd"
/>
</template>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
props: {
defaultValue: {
type: Object,
default: () => {}
},
queryOptions: {
type: Array,
default: () => []
}
},
data() {
return {
queryParams: {}
}
},
created() {
this.initValue();
},
watch: {
defaultValue: {
handler(val) {
Object.keys(val).forEach(key => {
if (val[key]) {
this.$set(this.queryParams, key, val[key]);
}
});
},
deep: true,
immediate: true
}
},
methods: {
initValue() {
this.queryOptions.forEach(item => {
if (item.prop && this.queryParams[item.prop] === void 0) {
this.$set(this.queryParams, item.prop, void 0)
}
})
},
handleQuery() {
this.$emit('query', this.queryParams)
},
resetQuery() {
this.resetForm('queryForm')
this.handleQuery();
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,78 @@
<template>
<div>
<el-table v-loading="loading" :data="tableData" max-height="500" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"/>
<template v-for="item in tableOptions">
<el-table-column
v-if="item.type === 'slot'"
:key="item.prop"
:label="item.label"
:width="item.width"
:fixed="item.fixed"
>"
<template slot-scope="scope">
<slot :name="item.prop" :row="scope.row" />
</template>
</el-table-column>
<el-table-column
v-else
:key="item.prop"
:label="item.label"
:prop="item.prop"
:width="item.width"
:fixed="item.fixed"
/>
</template>
</el-table>
</div>
</template>
<script>
export default {
props: {
loading: {
type: Boolean,
default: false
},
tableOptions: {
type: Array,
default: () => []
},
tableData: {
type: Array,
default: () => []
},
},
data() {
return {
// loading: false,
// tableData: [
// {
// serviceId: 'shgj34',
// serviceName: '1',
// address: ' 1518 ',
// status: '1',
// version: '1.0.0',
// creator: 'admin',
// createTime: '2024-04-20',
// updateTime: '2024-04-20',
// }
// ],
multipleSelection: [],
}
},
created() {
},
methods: {
handleSelectionChange(val) {
this.multipleSelection = val;
this.$emit('chooseChange', val);
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -53,10 +53,10 @@
plain plain
icon="el-icon-edit" icon="el-icon-edit"
size="mini" size="mini"
:disabled="single" :disabled="multiple"
@click="handleUpdate" @click="handleStatus()"
v-hasPermi="['gateway:interface:edit']" v-hasPermi="['gateway:interface:edit']"
>修改</el-button> >批量启用</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -67,7 +67,7 @@
:disabled="multiple" :disabled="multiple"
@click="handleDelete" @click="handleDelete"
v-hasPermi="['gateway:interface:remove']" v-hasPermi="['gateway:interface:remove']"
>删除</el-button> >批量删除</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -84,24 +84,31 @@
<el-table v-loading="loading" :data="interfaceList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="interfaceList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" /> <el-table-column label="接口ID" width="60" align="center" prop="id" />
<el-table-column label="接口名称" align="center" prop="interfaceName" /> <el-table-column label="接口名称" align="center" show-overflow-tooltip prop="interfaceName" />
<el-table-column label="接口路径" align="center" prop="interfacePath" /> <el-table-column label="接口路径" align="center" show-overflow-tooltip prop="interfacePath" />
<el-table-column label="请求方式" align="center" prop="requestMethod"> <el-table-column label="接口描述" align="center" show-overflow-tooltip prop="description" />
<el-table-column label="接口文档" align="center" show-overflow-tooltip prop="document" />
<el-table-column label="请求方式" width="80" align="center" prop="requestMethod">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.http_request_method" :value="scope.row.requestMethod"/> <dict-tag :options="dict.type.http_request_method" :value="scope.row.requestMethod"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="接口描述" align="center" prop="description" /> <el-table-column label="接口版本" width="100" align="center" prop="version" />
<el-table-column label="接口版本" align="center" prop="version" /> <el-table-column label="接口状态" width="80" align="center" prop="status">
<el-table-column label="接口状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.gateway_data_status" :value="scope.row.status"/> <dict-tag :options="dict.type.gateway_data_status" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="接口文档" align="center" prop="document" /> <el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleStatus(scope.row)"
v-hasPermi="['gateway:interface:edit']"
>{{scope.row === '0' ? '启用' : '禁用' }}</el-button>
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
@ -129,7 +136,7 @@
/> />
<!-- 添加或修改接口管理对话框 --> <!-- 添加或修改接口管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="接口名称" prop="interfaceName"> <el-form-item label="接口名称" prop="interfaceName">
<el-input v-model="form.interfaceName" placeholder="请输入接口名称" /> <el-input v-model="form.interfaceName" placeholder="请输入接口名称" />
@ -165,7 +172,7 @@
</template> </template>
<script> <script>
import { listInterface, getInterface, delInterface, addInterface, updateInterface } from "@/api/gateway/interface"; import { listInterface, getInterface, delInterface, addInterface, updateInterface, changeInterfaceStatus } from "@/api/gateway/interface";
export default { export default {
name: "Interface", name: "Interface",
@ -293,6 +300,21 @@ export default {
this.title = "修改接口管理"; this.title = "修改接口管理";
}); });
}, },
/** 启用/禁用按钮操作 */
handleStatus(row) {
const ids = row?.id ? [row.id] : this.ids;
let status = '1'
if (row) {
status = row.status == '1' ? '0' : '1'
}
const params = {ids, status};
changeInterfaceStatus(params).then(({code, msg}) => {
if (code === 200) {
this.$message.success(msg);
this.getList();
}
})
},
/** 提交按钮 */ /** 提交按钮 */
submitForm() { submitForm() {
this.$refs["form"].validate(valid => { this.$refs["form"].validate(valid => {

View File

@ -0,0 +1,41 @@
<template>
<div class="advanced-container">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="重试策略" prop="retry">
<el-input v-model="form.retry" placeholder="设置在请求失败时的重试次数" />
</el-form-item>
<el-form-item label="超时设置" prop="timeout">
<el-input v-model="form.timeout" placeholder="设想响应数据的缓存策略" />
</el-form-item>
<el-form-item label="压缩配置" prop="cache">
<el-input v-model="form.cache" placeholder="响应数据的压缩方式" />
</el-form-item>
<el-form-item label="监控指标" prop="alarm">
<el-input v-model="form.alarm" placeholder="监控的指标、阈值和告警规则" />
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
form: {
retry: '',
timeout: '',
cache: '',
alarm: '',
},
rules: {},
}
},
}
</script>
<style lang="scss" scoped>
.advanced-container {
width: 600px;
margin: 40px auto 0;
}
</style>

View File

@ -0,0 +1,142 @@
<template>
<div>
<el-dialog :title="title" :visible.sync="open" :close-on-click-modal="false" width="1200px" append-to-body destroy-on-close>
<BaseSearch
:defaultValue="queryParams"
:queryOptions="queryOptions"
@query="handleQuery"
/>
<BaseTable
v-loading="loading"
:tableData="tableData"
:tableOptions="tableOptions"
@chooseChange="chooseChange"
>
<template v-for="item in tableSolts" :slot="item.prop" slot-scope="scope">
<slot :name="item.prop" :row="scope.row" />
</template>
</BaseTable>
<pagination
v-show="total>0"
:total="total"
:page.sync="pages.pageNum"
:limit.sync="pages.pageSize"
@pagination="getList"
/>
<div slot="footer" class="dialog-footer">
<el-button @click="open = false"> </el-button>
<el-button type="primary" @click="chooseEnd"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import BaseSearch from '@/views/gateway/components/BaseSearch';
import BaseTable from '@/views/gateway/components/BaseTable';
export default {
components: {
BaseSearch,
BaseTable,
},
props: {
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: ''
},
queryParams: {
type: Object,
default: () => {
return {}
}
},
queryOptions: {
type: Array,
default: () => {
return []
}
},
tableOptions: {
type: Array,
default: () => {
return []
}
},
request: {
type: Function,
}
},
computed: {
open: {
get() {
return this.visible
},
set(val) {
this.$emit('update:visible', val)
}
},
tableSolts() {
return this.tableOptions.filter((item) => item.type === 'slot');
},
},
data() {
return {
loading: false,
tableData: [],
total: 0,
pages: {
pageNum: 1,
pageSize: 10,
},
multipleSelection: []
}
},
created() {
this.getList();
console.log(this.tableSolts)
},
methods: {
async getList(param) {
try {
this.loading = true;
const params = {
...this.queryParams,
...this.pages,
...param,
}
const { code, rows, total } = await this.request(params);
if (code === 200) {
this.tableData = rows;
this.total = total;
}
this.loading = false;
} catch (error) {
this.loading = false;
}
},
handleQuery(form) {
console.log(form)
this.getList(form);
},
chooseChange(rows) {
this.multipleSelection = rows;
},
chooseEnd() {
this.$emit('chooseEnd', this.multipleSelection);
this.open = false;
},
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -15,7 +15,12 @@
</el-steps> </el-steps>
<div class="mt10"> <div class="mt10">
<RouteConfig :serverId="detail.id" /> <StrategyConfig v-show="active == 0" :serverId="detail.id" />
<InterfaceConfig v-show="active == 1" :serverId="detail.id" />
<AdvancedConfig v-show="active == 2" :serverId="detail.id" />
<!-- <RouteConfig :serverId="detail.id" /> -->
</div> </div>
</el-main> </el-main>
<el-footer style="text-align: center;"> <el-footer style="text-align: center;">
@ -29,25 +34,31 @@
<script> <script>
import { getServer, } from "@/api/gateway/server"; import { getServer, } from "@/api/gateway/server";
import RouteConfig from './routeConfig.vue'; import RouteConfig from './routeConfig.vue';
import StrategyConfig from './strategyConfig.vue';
import InterfaceConfig from './interfaceConfig.vue';
import AdvancedConfig from './advancedConfig.vue';
export default { export default {
components: { components: {
RouteConfig, RouteConfig,
StrategyConfig,
InterfaceConfig,
AdvancedConfig,
}, },
data() { data() {
return { return {
detail: {}, detail: {},
active: 1, active: 0,
setpList: [ setpList: [
{ title: '添加路由', value: '0' }, // { title: '', value: '0' },
{ title: '添加策略', value: '1' }, { title: '添加策略', value: '0' },
{ title: '添加接口', value: '2' }, { title: '添加接口', value: '1' },
{ title: '高级配置', value: '3' }, { title: '高级配置', value: '2' },
] ]
} }
}, },
computed: { computed: {
nextBtn() { nextBtn() {
return this.active == 3 ? '保存' : '下一步' return this.active == 2 ? '保存' : '下一步'
} }
}, },
created() { created() {
@ -73,7 +84,7 @@ export default {
}, },
// //
next() { next() {
if (this.active == 3) { if (this.active == 2) {
return return
} }
this.active++; this.active++;

View File

@ -0,0 +1,115 @@
<template>
<div>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="open = true"
>添加</el-button>
</el-col>
</el-row>
<BaseTable
ref="table"
:loading="loading"
:tableOptions="tableOptions"
:tableData="tableData"
>
<template #action="{ row }">
<el-button
circle
icon="el-icon-minus"
@click="handleMinus(row)"
></el-button>
</template>
</BaseTable>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<ChooseDialog
title="添加接口"
:visible.sync="open"
:queryOptions="queryOptions"
:tableOptions="chooseTableOptions"
:request="listInterface"
@chooseEnd="chooseEnd"
/>
</div>
</template>
<script>
import BaseTable from '@/views/gateway/components/BaseTable';
import ChooseDialog from './chooseDialog.vue'
import { listInterface } from "@/api/gateway/interface";
export default {
components: {
BaseTable,
ChooseDialog,
},
dicts: ['gateway_data_status', 'gateway_strategy_type'],
data() {
return {
listInterface,
tableOptions: [
{ label: '接口ID', prop: 'id', width: '80' },
{ label: '接口名称', prop: 'interfaceName' },
{ label: '接口路劲', prop: 'interfacePath' },
{ label: '接口描述', prop: 'description' },
{ label: '接口版本', prop: 'version', width: '120' },
{ type: 'slot', prop: 'action', label: '操作', fixed: 'right', width: '100px' }
],
loading: false,
tableData: [],
total: 1,
queryParams: {
pageNum: 1,
pageSize: 10,
},
//
open: false,
}
},
computed: {
chooseTableOptions() {
return this.tableOptions.filter(item => item.prop !== 'action');
},
queryOptions() {
return [
{ label: '接口名称', prop: 'interfaceName', type: 'input' },
]
},
},
created() {
this.getList();
},
methods: {
async getList() {
console.log('getList');
//
this.tableData = []
},
handleMinus(row) {
console.log(row);
this.tableData = this.tableData.filter(item => item.id !== row.id);
},
chooseEnd(rows) {
// TODO
this.tableData = this.tableData.concat(rows);
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -28,8 +28,8 @@
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
circle circle
icon="el-icon-plus" icon="el-icon-minus"
@click="handleAdd(scope.row)" @click="handleMinus(scope.row)"
v-hasPermi="['gateway:route:edit']" v-hasPermi="['gateway:route:edit']"
></el-button> ></el-button>
</template> </template>
@ -44,28 +44,24 @@
@pagination="getList" @pagination="getList"
/> />
<el-dialog title="添加路由" :visible.sync="open" width="1200px" append-to-body draggable> <ChooseDialog
<el-form :model="dialogQuery" ref="queryForm" size="small" :inline="true" label-width="68px"> title="添加路由"
<el-form-item label="路由名称" prop="routerName"> :visible.sync="open"
<el-input :queryOptions="queryOption"
v-model="dialogQuery.routerName" :tableOptions="tableOptions"
placeholder="请输入路由名称" :request="listRoute"
clearable @chooseEnd="chooseEnd"
@keyup.enter.native="handleQuery" />
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { listRoute } from '@/api/gateway/route' import { listRoute } from '@/api/gateway/route'
import ChooseDialog from './chooseDialog.vue'
export default { export default {
components: {
ChooseDialog
},
props: { props: {
serverId: { serverId: {
type: String | Number, type: String | Number,
@ -75,6 +71,7 @@ export default {
dicts: ['http_request_method',], dicts: ['http_request_method',],
data() { data() {
return { return {
listRoute,
loading: false, loading: false,
total: 0, total: 0,
routeList: [], routeList: [],
@ -88,10 +85,21 @@ export default {
dialogQuery: { dialogQuery: {
routerName: '', routerName: '',
}, },
queryOption: [
{ label: '路由名称', prop: 'routerName', type: 'input' },
],
tableOptions: [
{ label: '路由ID', prop: 'id' },
{ label: '路由名称', prop: 'routerName' },
{ label: '请求路径', prop: 'requestPath' },
{ label: '请求方式', prop: 'requestMethod' },
{ label: '服务地址', prop: 'serverAddress' },
{ label: '服务器端口', prop: 'serverPort' },
],
} }
}, },
created() { created() {
this.getList() // this.getList()
}, },
methods: { methods: {
/** 查询路由管理列表 */ /** 查询路由管理列表 */
@ -106,8 +114,8 @@ export default {
handleSelectionChange() { handleSelectionChange() {
}, },
handleAdd(row) { handleMinus(row) {
// this.routeList = this.routeList.filter(item => item.id !== row.id);
}, },
handleQuery() { handleQuery() {
@ -115,6 +123,11 @@ export default {
resetQuery() { resetQuery() {
}, },
chooseEnd(data) {
console.log(data);
this.routeList = data;
//
},
} }
} }
</script> </script>

View File

@ -0,0 +1,131 @@
<template>
<div>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="open = true"
>添加</el-button>
</el-col>
</el-row>
<BaseTable
ref="table"
:loading="loading"
:tableOptions="tableOptions"
:tableData="tableData"
>
<template #strategyType="{ row }">
<dict-tag :options="dict.type.gateway_strategy_type" :value="row.strategyType"/>
</template>
<template #action="{ row }">
<el-button
circle
icon="el-icon-minus"
@click="handleMinus(row)"
></el-button>
</template>
</BaseTable>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<ChooseDialog
title="添加策略"
:visible.sync="open"
:queryOptions="queryOptions"
:tableOptions="chooseTableOptions"
:request="listStrategy"
@chooseEnd="chooseEnd"
>
<template #strategyType="{ row }">
<dict-tag :options="dict.type.gateway_strategy_type" :value="row.strategyType"/>
</template>
</ChooseDialog>
</div>
</template>
<script>
import BaseTable from '@/views/gateway/components/BaseTable';
import ChooseDialog from './chooseDialog.vue'
import { listStrategy } from "@/api/gateway/strategy";
export default {
components: {
BaseTable,
ChooseDialog,
},
dicts: ['gateway_data_status', 'gateway_strategy_type'],
data() {
return {
listStrategy,
tableOptions: [
{ label: '策略ID', prop: 'id', width: '80' },
{ type: 'slot', label: '策略类型', prop: 'strategyType', width: '120' },
{ label: '策略名称', prop: 'strategyName' },
{ label: '策略描述', prop: 'description' },
{ type: 'slot', prop: 'action', label: '操作', fixed: 'right', width: '100px' }
// { label: '', prop: 'serverPort' },
],
loading: false,
tableData: [],
total: 1,
queryParams: {
pageNum: 1,
pageSize: 10,
},
//
open: false,
}
},
computed: {
chooseTableOptions() {
return this.tableOptions.filter(item => item.prop !== 'action');
},
queryOptions() {
return [
{ label: '策略名称', prop: 'strategyName', type: 'input' },
{ label: '策略类型', prop: 'strategyType', type: 'select', dicts: this.dict.type.gateway_strategy_type },
// { label: '', prop: 'description', type: 'input' },
]
},
},
created() {
this.getList();
},
methods: {
async getList() {
console.log('getList');
//
this.tableData = [{
id: 'xxx',
strategyName: '策略名称',
strategyType: 'AUTHENTICATION',
description: '策略描述',
}
]
},
handleMinus(row) {
console.log(row);
this.tableData = this.tableData.filter(item => item.id !== row.id);
},
chooseEnd(rows) {
console.log(rows)
// TODO
this.tableData = this.tableData.concat(rows);
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -55,28 +55,16 @@
v-hasPermi="['gateway:server:add']" v-hasPermi="['gateway:server:add']"
>新增</el-button> >新增</el-button>
</el-col> </el-col>
<!-- <el-col :span="1.5"> <el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['gateway:server:edit']"
>修改</el-button>
</el-col> -->
<!-- <el-col :span="1.5">
<el-button <el-button
type="success" type="success"
plain plain
icon="el-icon-position" icon="el-icon-position"
size="mini" size="mini"
:disabled="multiple" :disabled="multiple"
@click="handleDelete" @click="handleStatus()"
v-hasPermi="['gateway:server:remove']"
>批量发布</el-button> >批量发布</el-button>
</el-col> --> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="danger" type="danger"
@ -84,7 +72,7 @@
icon="el-icon-delete" icon="el-icon-delete"
size="mini" size="mini"
:disabled="multiple" :disabled="multiple"
@click="handleDelete" @click="handleDelete()"
v-hasPermi="['gateway:server:remove']" v-hasPermi="['gateway:server:remove']"
>批量删除</el-button> >批量删除</el-button>
</el-col> </el-col>
@ -103,23 +91,23 @@
<el-table v-loading="loading" :data="serverList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="serverList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" /> <el-table-column label="服务ID" width="60" align="center" prop="id" />
<el-table-column label="服务名称" align="center" prop="serverName" /> <el-table-column label="服务名称" align="center" show-overflow-tooltip prop="serverName" />
<el-table-column label="服务地址" align="center" prop="serverAddress" /> <el-table-column label="服务地址" align="center" show-overflow-tooltip prop="serverAddress" />
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" show-overflow-tooltip prop="remark" />
<el-table-column label="接口版本" align="center" prop="version" /> <!-- <el-table-column label="接口版本" align="center" prop="version" /> -->
<el-table-column label="服务状态" align="center" prop="status"> <el-table-column label="服务状态" width="100" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.gateway_data_status" :value="scope.row.status"/> <dict-tag :options="dict.type.gateway_data_status" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建者" align="center" prop="createBy" /> <el-table-column label="创建者" width="100" align="center" prop="createBy" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180"> <el-table-column label="创建时间" align="center" prop="createTime" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="更新时间" align="center" prop="updateTime" width="180"> <el-table-column label="更新时间" align="center" prop="updateTime" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
</template> </template>
@ -129,21 +117,24 @@
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-edit"
@click="handleConfig(scope.row)"
v-hasPermi="['gateway:server:config']"
>服务配置</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)" @click="handleUpdate(scope.row)"
v-hasPermi="['gateway:server:edit']" v-hasPermi="['gateway:server:edit']"
>修改</el-button> >修改</el-button>
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-delete" @click="handleConfig(scope.row)"
v-hasPermi="['gateway:server:config']"
>服务配置</el-button>
<el-button
size="mini"
type="text"
@click="handleStatus(scope.row)"
v-hasPermi="['gateway:server:config']"
>{{scope.row.status == '1' ? '停止' : '启用'}}</el-button>
<el-button
size="mini"
type="text"
@click="handleDelete(scope.row)" @click="handleDelete(scope.row)"
v-hasPermi="['gateway:server:remove']" v-hasPermi="['gateway:server:remove']"
>删除</el-button> >删除</el-button>
@ -181,7 +172,7 @@
</template> </template>
<script> <script>
import { listServer, getServer, delServer, addServer, updateServer } from "@/api/gateway/server"; import { listServer, getServer, delServer, addServer, updateServer, changeServerStatus } from "@/api/gateway/server";
export default { export default {
name: "Server", name: "Server",
@ -339,7 +330,7 @@ export default {
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ids = row.id || this.ids; const ids = row.id || this.ids.join(",");
this.$modal.confirm('是否确认删除服务管理编号为"' + ids + '"的数据项?').then(function() { this.$modal.confirm('是否确认删除服务管理编号为"' + ids + '"的数据项?').then(function() {
return delServer(ids); return delServer(ids);
}).then(() => { }).then(() => {
@ -347,6 +338,27 @@ export default {
this.$modal.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).catch(() => {}); }).catch(() => {});
}, },
/** 停用/启用按钮操作 */
handleStatus(row) {
const ids = row?.id ? [row.id] : this.ids;
let status = '1';
if (row) {
status = row.status === '0' ? '1' : '0';
}
const params = {
ids,
status: status
}
changeServerStatus(params).then((res) => {
console.log(res)
if (res.code === 200) {
this.getList();
this.$modal.msgSuccess(row.status === '1' ? "停用成功" : "启用成功");
} else {
this.$modal.msgError(row.status === '1' ? "停用失败" : "启用失败");
}
})
},
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.download('gateway/server/export', { this.download('gateway/server/export', {

View File

@ -19,14 +19,6 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="请求方式" prop="requestMethod">
<el-input
v-model="queryParams.requestMethod"
placeholder="请输入请求方式"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="策略状态" prop="status"> <el-form-item label="策略状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择策略状态" clearable> <el-select v-model="queryParams.status" placeholder="请选择策略状态" clearable>
<el-option <el-option
@ -71,10 +63,10 @@
plain plain
icon="el-icon-edit" icon="el-icon-edit"
size="mini" size="mini"
:disabled="single" :disabled="multiple"
@click="handleUpdate" @click="handleStatus()"
v-hasPermi="['gateway:strategy:edit']" v-hasPermi="['gateway:strategy:edit']"
>修改</el-button> >批量启用</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -102,32 +94,39 @@
<el-table v-loading="loading" :data="strategyList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="strategyList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" /> <el-table-column label="策略ID" width="60" align="center" prop="id" />
<el-table-column label="策略名称" align="center" prop="strategyName" /> <el-table-column label="策略类型" width="120" align="center" prop="strategyType">
<el-table-column label="策略类型" align="center" prop="strategyType">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.gateway_strategy_type" :value="scope.row.strategyType"/> <dict-tag :options="dict.type.gateway_strategy_type" :value="scope.row.strategyType"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="策略描述" align="center" prop="description" /> <el-table-column label="策略名称" align="left" show-overflow-tooltip prop="strategyName" />
<el-table-column label="请求方式" align="center" prop="requestMethod" /> <el-table-column label="策略描述" align="left" show-overflow-tooltip prop="description" />
<el-table-column label="策略状态" align="center" prop="status"> <!-- <el-table-column label="请求方式" align="center" prop="requestMethod" /> -->
<el-table-column label="策略状态" width="80" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.gateway_data_status" :value="scope.row.status"/> <dict-tag :options="dict.type.gateway_data_status" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180"> <el-table-column label="创建时间" align="center" prop="createTime" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="更新时间" align="center" prop="updateTime" width="180"> <el-table-column label="更新时间" align="center" prop="updateTime" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleStatus(scope.row)"
v-hasPermi="['gateway:strategy:edit']"
>{{scope.row === '0' ? '启用' : '禁用' }}</el-button>
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
@ -155,57 +154,104 @@
/> />
<!-- 添加或修改策略管理对话框 --> <!-- 添加或修改策略管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form ref="form" :model="form" :rules="rules" :validate-on-rule-change="false" label-width="100px">
<el-form-item label="策略名称" prop="strategyName">
<el-input v-model="form.strategyName" placeholder="请输入策略名称" />
</el-form-item>
<el-form-item label="策略类型" prop="strategyType"> <el-form-item label="策略类型" prop="strategyType">
<el-select v-model="form.strategyType" placeholder="请选择策略类型"> <el-radio-group v-model="form.strategyType" @input="strategyTypeChange">
<el-option
v-for="dict in dict.type.gateway_strategy_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="策略描述" prop="description">
<el-input v-model="form.description" placeholder="请输入策略描述" />
</el-form-item>
<el-form-item label="请求方式" prop="requestMethod">
<el-input v-model="form.requestMethod" placeholder="请输入请求方式" />
</el-form-item>
<el-form-item label="加密算法" prop="encryptionAlgorithm">
<el-input v-model="form.encryptionAlgorithm" placeholder="请输入加密算法" />
</el-form-item>
<el-form-item label="策略状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio <el-radio
v-for="dict in dict.type.gateway_data_status" v-for="dict in dict.type.gateway_strategy_type"
:key="dict.value" :key="dict.value"
:label="dict.value" :label="dict.value"
>{{dict.label}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="私钥" prop="privateKey"> <el-form-item label="策略名称" prop="strategyName">
<el-input v-model="form.privateKey" placeholder="请输入私钥" /> <el-input v-model="form.strategyName" clearable placeholder="描述性的名称,用于识别和管理该策略" />
</el-form-item> </el-form-item>
<el-form-item label="公钥" prop="publicKey"> <el-form-item label="策略描述" prop="description">
<el-input v-model="form.publicKey" placeholder="请输入公钥" /> <el-input v-model="form.description" placeholder="请输入策略描述" />
</el-form-item>
<el-form-item label="限流算法" prop="currentLimitingAlgorithm">
<el-input v-model="form.currentLimitingAlgorithm" placeholder="请输入限流算法" />
</el-form-item>
<el-form-item label="限流阈值" prop="currentLimitingThreshold">
<el-input v-model="form.currentLimitingThreshold" placeholder="请输入限流阈值" />
</el-form-item>
<el-form-item label="限流周期" prop="currentLimitingPeriod">
<el-input v-model="form.currentLimitingPeriod" placeholder="请输入限流周期" />
</el-form-item>
<el-form-item label="限流处理方式" prop="currentLimitingProcessingMethod">
<el-input v-model="form.currentLimitingProcessingMethod" placeholder="请输入限流处理方式" />
</el-form-item> </el-form-item>
<!-- 认证策略 -->
<template v-if="form.strategyType === 'AUTHENTICATION'">
<!-- 认证方式 -->
<!-- 认证配置 针对选定的认证方式需要相应的配置信息如秘钥证书令牌有效期等 -->
<!-- 生效范围 -->
</template>
<!-- 认证策略 -->
<!-- 鉴权策略 -->
<template v-if="form.strategyType === 'PERMISSION'">
<!-- 角色授权 指定用户或角色是否具有访问接口或资源的权限-->
<!-- 角色列表 指定哪些角色拥有访问接口或资源的权限-->
<!-- 用户ID 标识请求中的用户身份信息-->
<!-- IP地址 允许访问接口或资源的IP地址范围限制请求来源-->
<el-form-item label="请求方法" prop="requestMethod">
<el-radio-group v-model="form.requestMethod">
<el-radio
v-for="dict in dict.type.http_request_method"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<!-- 请求路劲 允许访问的接口路劲或URL -->
<!-- 访问频率限制 设置允许用户或角色在一定时间内访问接口的次数限制 -->
<!-- 访问时间限制 允许用户或者角色访问接口的时间段 -->
<!-- 访问来源 访问接口的来源 -->
<!-- 有限期 -->
<!-- 授权范围 指定用户或角色 -->
</template>
<!-- 鉴权策略 -->
<!-- 限流策略 -->
<template v-if="form.strategyType == 'CURRENT_LIMITING'">
<el-form-item label="限流算法" prop="currentLimitingAlgorithm">
<el-input v-model="form.currentLimitingAlgorithm" placeholder="选择具体的限流算法,如令牌桶算法、楼桶算法、计数器算法等" />
</el-form-item>
<el-form-item label="限流阈值" prop="currentLimitingThreshold">
<el-input v-model="form.currentLimitingThreshold" placeholder="设置限流的预制,即允许通过的请求次数或者并发连接数" />
</el-form-item>
<el-form-item label="限流周期" prop="currentLimitingPeriod">
<el-input v-model="form.currentLimitingPeriod" placeholder="设置限流的时间周期,如每秒限流、没分钟限流等" />
</el-form-item>
<!-- 生效范围 -->
<el-form-item label="限流处理方式" prop="currentLimitingProcessingMethod">
<el-input v-model="form.currentLimitingProcessingMethod" placeholder="请输入限流处理方式" />
</el-form-item>
<!-- 超限处理策略 -->
<!-- 监控和警告 -->
<!-- 限流日志 -->
</template>
<!-- 限流策略 -->
<!-- 数据加密策略 -->
<template v-if="form.strategyType == 'DATA_ENCRYPTION'">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.gateway_data_status"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="加密算法" prop="encryptionAlgorithm">
<el-radio-group v-model="form.encryptionAlgorithm" @input="changeEncryptionAlgorithm">
<!-- ECCRSASM2国密 -->
<el-radio label="ECC">ECC</el-radio>
<el-radio label="RSA">RSA</el-radio>
<el-radio label="SM2">国密</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="私钥内容" prop="privateKey">
<el-input v-model="form.privateKey" type="textarea" placeholder="请输入私钥" />
</el-form-item>
<el-form-item v-if="publicKeyRequired" label="公钥内容" prop="publicKey">
<el-input v-model="form.publicKey" type="textarea" placeholder="请输入公钥" />
</el-form-item>
</template>
<!-- 数据加密策略 -->
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button> <el-button type="primary" @click="submitForm"> </el-button>
@ -216,11 +262,11 @@
</template> </template>
<script> <script>
import { listStrategy, getStrategy, delStrategy, addStrategy, updateStrategy } from "@/api/gateway/strategy"; import { listStrategy, getStrategy, delStrategy, addStrategy, updateStrategy, changeStrategyStatus } from "@/api/gateway/strategy";
export default { export default {
name: "Strategy", name: "Strategy",
dicts: ['gateway_data_status', 'gateway_strategy_type'], dicts: ['gateway_data_status', 'gateway_strategy_type', 'http_request_method'],
data() { data() {
return { return {
// //
@ -254,20 +300,54 @@ export default {
createTime: null, createTime: null,
}, },
// //
form: {}, form: {
// id: null,
rules: { strategyName: null,
strategyType: null,
description: null,
requestMethod: null,
encryptionAlgorithm: null,
status: null,
privateKey: null,
publicKey: null,
currentLimitingAlgorithm: null,
currentLimitingThreshold: null,
currentLimitingPeriod: null,
currentLimitingProcessingMethod: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
},
};
},
computed: {
publicKeyRequired() {
return this.form.encryptionAlgorithm === 'RSA';
},
//
rules() {
return {
strategyName: [ strategyName: [
{ required: true, message: "策略名称不能为空", trigger: "blur" } { required: this.form.strategyType === 'DATA_ENCRYPTION', message: "策略名称不能为空", trigger: "blur" }
], ],
strategyType: [ strategyType: [
{ required: true, message: "策略类型不能为空", trigger: "change" } { required: true, message: "策略类型不能为空", trigger: "change" }
], ],
requestMethod: [ // requestMethod: [
{ required: true, message: "请求方式不能为空", trigger: "blur" } // { required: true, message: "", trigger: "blur" }
// ],
encryptionAlgorithm: [
{ required: true, message: "加密算法不能为空", trigger: "blur" }
],
privateKey: [
{ required: true, message: "私钥内容不能为空", trigger: "blur" }
],
publicKey: [
{ required: this.publicKeyRequired, message: "公钥内容不能为空", trigger: "blur" }
], ],
} }
}; }
}, },
created() { created() {
this.getList(); this.getList();
@ -351,8 +431,23 @@ export default {
this.title = "修改策略管理"; this.title = "修改策略管理";
}); });
}, },
strategyTypeChange() {
const { id, strategyName, strategyType } = this.form;
this.reset();
this.form.id = id;
this.form.strategyName = strategyName;
this.form.strategyType = strategyType;
},
changeEncryptionAlgorithm(val) {
// RSA
if (val === 'RSA') {
this.form.publicKey = null;
};
},
/** 提交按钮 */ /** 提交按钮 */
submitForm() { submitForm() {
console.log(this.form)
// return;
this.$refs["form"].validate(valid => { this.$refs["form"].validate(valid => {
if (valid) { if (valid) {
if (this.form.id != null) { if (this.form.id != null) {
@ -383,6 +478,21 @@ export default {
this.$modal.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).catch(() => {}); }).catch(() => {});
}, },
/** 启用/禁用按钮操作 */
handleStatus(row) {
const ids = row?.id ? [row.id] : this.ids;
let status = '1'
if (row) {
status = row.status == '1' ? '0' : '1'
}
const params = {ids, status};
changeStrategyStatus(params).then(({code, msg}) => {
if (code === 200) {
this.$message.success(msg);
this.getList();
}
})
},
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.download('gateway/strategy/export', { this.download('gateway/strategy/export', {