增加同步API功能 (#1811)

* feature:新增同步API功能
This commit is contained in:
PiexlMax(奇淼
2024-07-04 21:19:20 +08:00
committed by GitHub
parent 227755b892
commit 02f5d6fea2
14 changed files with 635 additions and 28 deletions

View File

@@ -144,3 +144,36 @@ export const freshCasbin = () => {
method: 'get'
})
}
export const syncApi = () => {
return service({
url: '/api/syncApi',
method: 'get'
})
}
export const getApiGroups = () => {
return service({
url: '/api/getApiGroups',
method: 'get'
})
}
export const ignoreApi = (data) => {
return service({
url: '/api/ignoreApi',
method: 'post',
data
})
}
export const enterSyncApi = (data) => {
return service({
url: '/api/enterSyncApi',
method: 'post',
data
})
}

View File

@@ -43,11 +43,15 @@
type="primary"
icon="search"
@click="onSubmit"
>查询</el-button>
>
查询
</el-button>
<el-button
icon="refresh"
@click="onReset"
>重置</el-button>
>
重置
</el-button>
</el-form-item>
</el-form>
</div>
@@ -57,20 +61,34 @@
type="primary"
icon="plus"
@click="openDialog('addApi')"
>新增</el-button>
>
新增
</el-button>
<el-icon
class="cursor-pointer"
@click="toDoc('https://www.bilibili.com/video/BV1kv4y1g7nT?p=7&vd_source=f2640257c21e3b547a790461ed94875e')"
><VideoCameraFilled /></el-icon>
>
<VideoCameraFilled />
</el-icon>
<el-button
icon="delete"
:disabled="!apis.length"
@click="onDelete"
>删除</el-button>
>
删除
</el-button>
<el-button
icon="Refresh"
@click="onFresh"
>刷新缓存</el-button>
>
刷新缓存
</el-button>
<el-button
icon="Compass"
@click="onSync"
>
同步API
</el-button>
<ExportTemplate
template-id="api"
/>
@@ -147,14 +165,18 @@
type="primary"
link
@click="editApiFunc(scope.row)"
>编辑</el-button>
>
编辑
</el-button>
<el-button
icon="delete"
type="primary"
link
@click="deleteApiFunc(scope.row)"
>删除</el-button>
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
@@ -169,9 +191,184 @@
@size-change="handleSizeChange"
/>
</div>
</div>
<el-drawer
v-model="syncApiFlag"
size="80%"
:before-close="closeSyncDialog"
:show-close="false"
>
<template #header>
<div class="flex justify-between items-center">
<span class="text-lg">同步路由</span>
<div>
<el-button @click="closeSyncDialog">
</el-button>
<el-button
type="primary"
@click="enterSyncDialog"
>
</el-button>
</div>
</div>
</template>
<h4>新增路由 <span class="text-xs text-gray-500 ml-2 font-normal">存在于当前路由中但是不存在于api表</span></h4>
<el-table
:data="syncApiData.newApis"
>
<el-table-column
align="left"
label="API路径"
min-width="150"
prop="path"
/>
<el-table-column
align="left"
label="API分组"
min-width="150"
prop="apiGroup"
>
<template #default="{row}">
<el-select
v-model="row.apiGroup"
placeholder="请选择或新增"
allow-create filterable default-first-option
>
<el-option
v-for="item in apiGroupOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column
align="left"
label="API简介"
min-width="150"
prop="description"
>
<template #default="{row}">
<el-input
v-model="row.description"
autocomplete="off"
/>
</template>
</el-table-column>
<el-table-column
align="left"
label="请求"
min-width="150"
prop="method"
>
<template #default="scope">
<div>
{{ scope.row.method }} / {{ methodFilter(scope.row.method) }}
</div>
</template>
</el-table-column>
<el-table-column
label="操作"
min-width="150"
fixed="right"
>
<template #default="{row}">
<el-button type="primary" text @click="ignoreApiFunc(row,true)">
忽略
</el-button>
</template>
</el-table-column>
</el-table>
<h4>已删除路由 <span class="text-xs text-gray-500 ml-2 font-normal">已经不存在于当前项目的路由中确定同步后会自动从apis表删除</span></h4>
<el-table
:data="syncApiData.deleteApis"
>
<el-table-column
align="left"
label="API路径"
min-width="150"
prop="path"
/>
<el-table-column
align="left"
label="API分组"
min-width="150"
prop="apiGroup"
/>
<el-table-column
align="left"
label="API简介"
min-width="150"
prop="description"
/>
<el-table-column
align="left"
label="请求"
min-width="150"
prop="method"
>
<template #default="scope">
<div>
{{ scope.row.method }} / {{ methodFilter(scope.row.method) }}
</div>
</template>
</el-table-column>
</el-table>
<h4>忽略路由 <span class="text-xs text-gray-500 ml-2 font-normal">忽略路由不参与api同步常见为不需要进行鉴权行为的路由</span></h4>
<el-table
:data="syncApiData.ignoreApis"
>
<el-table-column
align="left"
label="API路径"
min-width="150"
prop="path"
/>
<el-table-column
align="left"
label="API分组"
min-width="150"
prop="apiGroup"
/>
<el-table-column
align="left"
label="API简介"
min-width="150"
prop="description"
/>
<el-table-column
align="left"
label="请求"
min-width="150"
prop="method"
>
<template #default="scope">
<div>
{{ scope.row.method }} / {{ methodFilter(scope.row.method) }}
</div>
</template>
</el-table-column>
<el-table-column
label="操作"
min-width="150"
fixed="right"
>
<template #default="{row}">
<el-button type="primary" text @click="ignoreApiFunc(row,false)">
取消忽略
</el-button>
</template>
</el-table-column>
</el-table>
</el-drawer>
<el-drawer
v-model="dialogFormVisible"
size="60%"
@@ -182,11 +379,15 @@
<div class="flex justify-between items-center">
<span class="text-lg">{{ dialogTitle }}</span>
<div>
<el-button @click="closeDialog"> </el-button>
<el-button @click="closeDialog">
</el-button>
<el-button
type="primary"
@click="enterDialog"
> </el-button>
>
</el-button>
</div>
</div>
</template>
@@ -228,10 +429,17 @@
label="api分组"
prop="apiGroup"
>
<el-input
<el-select
v-model="form.apiGroup"
autocomplete="off"
/>
placeholder="请选择或新增" allow-create filterable default-first-option
>
<el-option
v-for="item in apiGroupOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label="api简介"
@@ -255,7 +463,11 @@ import {
updateApi,
deleteApi,
deleteApisByIds,
freshCasbin
freshCasbin,
syncApi,
getApiGroups,
ignoreApi,
enterSyncApi
} from '@/api/api'
import { toSQLLine } from '@/utils/stringFun'
import WarningBar from '@/components/warningBar/warningBar.vue'
@@ -325,6 +537,49 @@ const total = ref(0)
const pageSize = ref(10)
const tableData = ref([])
const searchInfo = ref({})
const apiGroupOptions = ref([])
const getGroup = async() => {
const res = await getApiGroups()
if (res.code === 0) {
apiGroupOptions.value = res.data.map(item => ({ label: item, value: item }))
}
}
const ignoreApiFunc = async (row,flag) =>{
const res = await ignoreApi({path:row.path,method:row.method,flag})
if (res.code === 0) {
ElMessage({
type: 'success',
message: res.msg
})
if(flag){
syncApiData.value.newApis = syncApiData.value.newApis.filter(item => !(item.path === row.path && item.method === row.method))
syncApiData.value.ignoreApis.push(row)
return
}
syncApiData.value.ignoreApis = syncApiData.value.ignoreApis.filter(item => !(item.path === row.path && item.method === row.method))
syncApiData.value.newApis.push(row)
}
}
const closeSyncDialog = () => {
syncApiFlag.value = false
}
const enterSyncDialog = async() => {
const res = await enterSyncApi(syncApiData.value)
if (res.code === 0) {
ElMessage({
type: 'success',
message: res.msg
})
syncApiFlag.value = false
getTableData()
}
}
const onReset = () => {
searchInfo.value = {}
@@ -372,7 +627,7 @@ const getTableData = async() => {
}
getTableData()
getGroup()
// 批量操作
const handleSelectionChange = (val) => {
apis.value = val
@@ -414,6 +669,22 @@ const onFresh = async() => {
})
}
const syncApiData = ref({
newApis:[],
deleteApis:[],
ignoreApis:[]
})
const syncApiFlag = ref(false)
const onSync = async() => {
const res = await syncApi()
if (res.code === 0) {
syncApiData.value = res.data
syncApiFlag.value = true
}
}
// 弹窗相关
const apiForm = ref(null)
const initForm = () => {
@@ -468,6 +739,7 @@ const enterDialog = async() => {
})
}
getTableData()
getGroup()
closeDialog()
}
@@ -518,6 +790,7 @@ const deleteApiFunc = async(row) => {
page.value--
}
getTableData()
getGroup()
}
})
}