swagger查看页面路由交互开发
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" href="/logo.png" />
|
<link rel="icon" href="/logo.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>swagger文档管理</title>
|
<title>Swagger文档管理</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@@ -5,26 +5,28 @@
|
|||||||
</a-menu>
|
</a-menu>
|
||||||
<a-divider style="margin: 6px 0;"/>
|
<a-divider style="margin: 6px 0;"/>
|
||||||
<div v-show="!collapsed" class="doc-tree">
|
<div v-show="!collapsed" class="doc-tree">
|
||||||
<div style="padding: 10px 5px;">
|
<a-spin tip="加载中..." :spinning="treeDataLoading">
|
||||||
<a-select placeholder="请选择分组" v-model:value="swaggerDocChoice" @change="swaggerDocChoiceChange" style="width: 100%;">
|
<div style="padding: 10px 5px;">
|
||||||
<a-select-option :value="item.url" v-for="item in swaggerResourceList">{{item.name}}</a-select-option>
|
<a-select placeholder="请选择分组" v-model:value="swaggerDocChoice" @change="swaggerDocChoiceChange" style="width: 100%;">
|
||||||
</a-select>
|
<a-select-option :value="item.url" v-for="item in swaggerResourceList">{{item.name}}</a-select-option>
|
||||||
</div>
|
</a-select>
|
||||||
<a-directory-tree :showIcon="false" :tree-data="treeData" v-model:expandedKeys="expandedKeys" @select="docChecked">
|
</div>
|
||||||
<template #title="{ title, isLeaf, method }">
|
<a-directory-tree :showIcon="false" :tree-data="treeData" v-model:expandedKeys="expandedKeys" @select="docChecked">
|
||||||
<template v-if="isLeaf">
|
<template #title="{ title, isLeaf, method }">
|
||||||
<a-tag color="pink" v-if="method === 'get'">get</a-tag>
|
<template v-if="isLeaf">
|
||||||
<a-tag color="red" v-else-if="method === 'post'">post</a-tag>
|
<a-tag color="pink" v-if="method === 'get'">get</a-tag>
|
||||||
<a-tag color="orange" v-else-if="method === 'put'">put</a-tag>
|
<a-tag color="red" v-else-if="method === 'post'">post</a-tag>
|
||||||
<a-tag color="green" v-else-if="method === 'head'">head</a-tag>
|
<a-tag color="orange" v-else-if="method === 'put'">put</a-tag>
|
||||||
<a-tag color="cyan" v-else-if="method === 'patch'">patch</a-tag>
|
<a-tag color="green" v-else-if="method === 'head'">head</a-tag>
|
||||||
<a-tag color="blue" v-else-if="method === 'delete'">delete</a-tag>
|
<a-tag color="cyan" v-else-if="method === 'patch'">patch</a-tag>
|
||||||
<a-tag color="purple" v-else-if="method === 'options'">options</a-tag>
|
<a-tag color="blue" v-else-if="method === 'delete'">delete</a-tag>
|
||||||
<a-tag color="purple" v-else-if="method === 'trace'">trace</a-tag>
|
<a-tag color="purple" v-else-if="method === 'options'">options</a-tag>
|
||||||
|
<a-tag color="purple" v-else-if="method === 'trace'">trace</a-tag>
|
||||||
|
</template>
|
||||||
|
{{title}}
|
||||||
</template>
|
</template>
|
||||||
{{title}}
|
</a-directory-tree>
|
||||||
</template>
|
</a-spin>
|
||||||
</a-directory-tree>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -48,34 +50,17 @@
|
|||||||
selectedKeys: [],
|
selectedKeys: [],
|
||||||
openKeys: [],
|
openKeys: [],
|
||||||
// 文档树
|
// 文档树
|
||||||
treeData: [
|
treeDataLoading: false,
|
||||||
{
|
treeData: [],
|
||||||
title: '用户管理接口文档',
|
|
||||||
key: '0-0',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: '用户信息管理',
|
|
||||||
key: '0-0-0',
|
|
||||||
children: [
|
|
||||||
{title: '/getUserInfo', key: '0-0-0-0', isLeaf: true, query: {path: '/getUserInfo'}},
|
|
||||||
{title: '/deleteUserInfo', key: '0-0-0-1', isLeaf: true, query: {path: '/deleteUserInfo'}},
|
|
||||||
{title: '/updateUserInfo', key: '0-0-0-2', isLeaf: true, query: {path: '/updateUserInfo'}},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
expandedKeys: [],
|
expandedKeys: [],
|
||||||
swaggerResourceList: [],
|
swaggerResourceList: [],
|
||||||
swaggerDocChoice: undefined,
|
swaggerDocChoice: undefined,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch:{
|
watch:{
|
||||||
'$store.state.userInfo'(userInfo) {
|
'$store.state.docChangedNum'() {
|
||||||
|
this.getSwaggerResourceList();
|
||||||
},
|
},
|
||||||
collapsed(x) {
|
|
||||||
console.log(x, this.collapsed)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
components: {MenuChildrenLayout},
|
components: {MenuChildrenLayout},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -103,7 +88,7 @@
|
|||||||
customApi.get('./swagger-resources').then(res => {
|
customApi.get('./swagger-resources').then(res => {
|
||||||
if (res instanceof Array) {
|
if (res instanceof Array) {
|
||||||
this.swaggerResourceList = res || [];
|
this.swaggerResourceList = res || [];
|
||||||
if (this.swaggerResourceList.length > 0) {
|
if (this.swaggerResourceList.length > 0 && !this.swaggerDocChoice) {
|
||||||
this.swaggerDocChoice = this.swaggerResourceList[0].url;
|
this.swaggerDocChoice = this.swaggerResourceList[0].url;
|
||||||
this.swaggerDocChoiceChange();
|
this.swaggerDocChoiceChange();
|
||||||
}
|
}
|
||||||
@@ -116,16 +101,20 @@
|
|||||||
this.loadV2Doc(this.swaggerDocChoice);
|
this.loadV2Doc(this.swaggerDocChoice);
|
||||||
},
|
},
|
||||||
loadV2Doc(url) {
|
loadV2Doc(url) {
|
||||||
|
this.treeDataLoading = true;
|
||||||
customApi.get(url).then(res => {
|
customApi.get(url).then(res => {
|
||||||
let v2Doc = this.toJsonObj(res);
|
let v2Doc = this.toJsonObj(res);
|
||||||
if (typeof v2Doc !== 'object') {
|
if (typeof v2Doc !== 'object' || !v2Doc.swagger) {
|
||||||
this.$message.error('获取文档数据请求失败');
|
this.$message.error('获取文档数据请求失败');
|
||||||
|
this.treeDataLoading = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
this.$store.commit('setSwaggerDoc', v2Doc);
|
this.$store.commit('setSwaggerDoc', v2Doc);
|
||||||
let metaInfo = {url};
|
let metaInfo = {url};
|
||||||
let treeData = createTreeViewByTag(v2Doc);
|
let treeData = createTreeViewByTag(v2Doc);
|
||||||
this.treeData = getTreeDataForTag(v2Doc, treeData.pathIndex, metaInfo);
|
this.treeData = getTreeDataForTag(v2Doc, treeData.pathIndex, metaInfo);
|
||||||
this.$store.commit('setSwaggerTreePathMap', treeData.treePathDataMap);
|
this.$store.commit('setSwaggerTreePathMap', treeData.treePathDataMap);
|
||||||
|
setTimeout(() => this.treeDataLoading = false, 300);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
toJsonObj(value) {
|
toJsonObj(value) {
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
<a-tab-pane closable :tab="pageTabNameMap[item.fullPath]||item.name" :name="getRouteRealPath(item)" :fullPath="item.fullPath" :key="item.fullPath" v-for="item in pageList"/>
|
<a-tab-pane closable :tab="pageTabNameMap[item.fullPath]||item.name" :name="getRouteRealPath(item)" :fullPath="item.fullPath" :key="item.fullPath" v-for="item in pageList"/>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
<div class="page-body">
|
<div class="page-body">
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component, route }">
|
||||||
<keep-alive>
|
<keep-alive>
|
||||||
<component :is="Component" />
|
<component :is="Component" :key="route.fullPath" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</router-view>
|
</router-view>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,21 +6,13 @@ let routers = [
|
|||||||
path: '/',
|
path: '/',
|
||||||
name: '主页',
|
name: '主页',
|
||||||
component: () => import('./components/layouts/GlobalLayout.vue'),
|
component: () => import('./components/layouts/GlobalLayout.vue'),
|
||||||
redirect: '/doc/console',
|
redirect: '/doc/info',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/doc',
|
path: '/doc',
|
||||||
name: '系统配置',
|
name: '系统配置',
|
||||||
component: PageLayout,
|
component: PageLayout,
|
||||||
children: [
|
children: [
|
||||||
{
|
|
||||||
path: '/doc/console',
|
|
||||||
name: '控制台',
|
|
||||||
meta: {
|
|
||||||
hidden: true,
|
|
||||||
},
|
|
||||||
component: () => import('./views/common/Console.vue')
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/doc/info',
|
path: '/doc/info',
|
||||||
name: '文档信息',
|
name: '文档信息',
|
||||||
|
|||||||
@@ -102,8 +102,9 @@ function getTreeHtmlForTag(pathData, treeId, metaInfo) {
|
|||||||
isLeaf: true,
|
isLeaf: true,
|
||||||
method: nodeSub.method,
|
method: nodeSub.method,
|
||||||
query: {
|
query: {
|
||||||
path: nodeSub.path,
|
...metaInfo,
|
||||||
...metaInfo
|
path: nodeSub.url,
|
||||||
|
method: nodeSub.method,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (actionArrays.indexOf(key) >= 0) {
|
} else if (actionArrays.indexOf(key) >= 0) {
|
||||||
@@ -115,8 +116,9 @@ function getTreeHtmlForTag(pathData, treeId, metaInfo) {
|
|||||||
isLeaf: true,
|
isLeaf: true,
|
||||||
method: tempNode.method,
|
method: tempNode.method,
|
||||||
query: {
|
query: {
|
||||||
path: tempNode.path,
|
...metaInfo,
|
||||||
...metaInfo
|
path: tempNode.url,
|
||||||
|
method: tempNode.method,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -4,19 +4,9 @@ import {getDefinitions, createTreeViewByTag} from './SwaggerDocUtil'
|
|||||||
export default createStore({
|
export default createStore({
|
||||||
state() {
|
state() {
|
||||||
return {
|
return {
|
||||||
|
docChangedNum: 1,
|
||||||
userInfo: {},
|
userInfo: {},
|
||||||
pageTabNameMap: {},
|
pageTabNameMap: {},
|
||||||
docMap: {
|
|
||||||
'/getUserInfo': {
|
|
||||||
name: '获取用户信息'
|
|
||||||
},
|
|
||||||
'/deleteUserInfo': {
|
|
||||||
name: '删除用户信息'
|
|
||||||
},
|
|
||||||
'/updateUserInfo': {
|
|
||||||
name: '修改用户信息'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
swaggerDoc: {},
|
swaggerDoc: {},
|
||||||
swaggerDefinitions: {},
|
swaggerDefinitions: {},
|
||||||
swaggerTreePathMap: [],
|
swaggerTreePathMap: [],
|
||||||
@@ -26,6 +16,9 @@ export default createStore({
|
|||||||
setUserInfo(state, userInfo) {
|
setUserInfo(state, userInfo) {
|
||||||
state.userInfo = userInfo;
|
state.userInfo = userInfo;
|
||||||
},
|
},
|
||||||
|
addDocChangedNum(state) {
|
||||||
|
state.docChangedNum++;
|
||||||
|
},
|
||||||
setSwaggerDoc(state, swaggerDoc) {
|
setSwaggerDoc(state, swaggerDoc) {
|
||||||
state.swaggerDoc = swaggerDoc;
|
state.swaggerDoc = swaggerDoc;
|
||||||
state.swaggerDefinitions = getDefinitions(swaggerDoc.definitions);
|
state.swaggerDefinitions = getDefinitions(swaggerDoc.definitions);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-card style="width: 600px">
|
<a-card>
|
||||||
<a-form :label-col="{span: 4}" :wrapper-col="{span: 20}">
|
<a-form :label-col="{span: 4}" :wrapper-col="{span: 20}" v-if="swaggerDocInfo">
|
||||||
<a-form-item label="标题">{{swaggerDocInfo.title}}</a-form-item>
|
<a-form-item label="标题">{{swaggerDocInfo.title}}</a-form-item>
|
||||||
<a-form-item label="版本">{{swaggerDocInfo.version}}</a-form-item>
|
<a-form-item label="版本">{{swaggerDocInfo.version}}</a-form-item>
|
||||||
<a-form-item label="作者" v-if="swaggerDocInfo.contact">
|
<a-form-item label="作者" v-if="swaggerDocInfo.contact">
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
<span v-html="swaggerDocInfo.description"></span>
|
<span v-html="swaggerDocInfo.description"></span>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
|
<div v-else style="text-align: center;">暂无文档信息,请先选择文档</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@
|
|||||||
return this.$store.state.swaggerDoc || {};
|
return this.$store.state.swaggerDoc || {};
|
||||||
},
|
},
|
||||||
swaggerDocInfo () {
|
swaggerDocInfo () {
|
||||||
return this.$store.state.swaggerDoc.info || {};
|
return this.$store.state.swaggerDoc.info;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
@@ -88,9 +88,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import { toRefs, ref, reactive, onMounted } from 'vue';
|
import { toRefs, ref, reactive, onMounted } from 'vue';
|
||||||
import {zyplayerApi} from '../../api';
|
import {zyplayerApi} from '../../api';
|
||||||
|
import {useStore} from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
const store = useStore()
|
||||||
let docList = ref([]);
|
let docList = ref([]);
|
||||||
let docListLoading = ref(false);
|
let docListLoading = ref(false);
|
||||||
let searchParam = ref({docType: '', openVisit: '', docStatus: ''});
|
let searchParam = ref({docType: '', openVisit: '', docStatus: ''});
|
||||||
@@ -109,6 +111,7 @@
|
|||||||
zyplayerApi.swaggerDocAdd(docEdit.value).then(res => {
|
zyplayerApi.swaggerDocAdd(docEdit.value).then(res => {
|
||||||
searchDocList();
|
searchDocList();
|
||||||
newDocVisible.value = false;
|
newDocVisible.value = false;
|
||||||
|
store.commit('addDocChangedNum');
|
||||||
});
|
});
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.log('error', error);
|
console.log('error', error);
|
||||||
@@ -127,6 +130,7 @@
|
|||||||
const updateDoc = async (id, docStatus, yn) => {
|
const updateDoc = async (id, docStatus, yn) => {
|
||||||
zyplayerApi.swaggerDocUpdate({id, docStatus, yn}).then(res => {
|
zyplayerApi.swaggerDocUpdate({id, docStatus, yn}).then(res => {
|
||||||
searchDocList();
|
searchDocList();
|
||||||
|
store.commit('addDocChangedNum');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const deleteDoc = async (row) => updateDoc(row.id, null, 0);
|
const deleteDoc = async (row) => updateDoc(row.id, null, 0);
|
||||||
|
|||||||
@@ -1,30 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-tabs v-model:activeKey="activePage" closable @tab-click="changePage" style="padding: 5px 10px 0;">
|
<a-tabs v-model:activeKey="activePage" closable @tab-click="changePage" style="padding: 5px 10px 0;">
|
||||||
<a-tab-pane tab="接口说明" key="doc"/>
|
<a-tab-pane tab="接口说明" key="doc">
|
||||||
<a-tab-pane tab="在线调试" key="debug"/>
|
{{activePage}}
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="在线调试" key="debug">
|
||||||
|
{{activePage}}
|
||||||
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {toRefs, ref, reactive, onMounted} from 'vue';
|
import {toRefs, ref, reactive, onMounted, onActivated} from 'vue';
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter, useRoute } from "vue-router";
|
||||||
import {useStore} from 'vuex';
|
import {useStore} from 'vuex';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
|
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
const router = useRouter();
|
const route = useRoute();
|
||||||
const store = useStore()
|
const store = useStore();
|
||||||
let activePage = ref('doc');
|
let activePage = ref('doc');
|
||||||
onBeforeRouteUpdate(async (to, from) => {
|
onMounted(() => {
|
||||||
let path = to.query.path;
|
console.log('DocView onMounted', route.query);
|
||||||
|
let path = route.query.path + '.' + route.query.method;
|
||||||
let docInfo = store.state.swaggerTreePathMap[path];
|
let docInfo = store.state.swaggerTreePathMap[path];
|
||||||
if (!docInfo) {
|
if (!docInfo) {
|
||||||
message.error('没有找到对应的文档');
|
message.error('没有找到对应的文档');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
store.commit('addTableName', {key: to.fullPath, val: docInfo.summary});
|
store.commit('addTableName', {key: route.fullPath, val: docInfo.summary});
|
||||||
});
|
});
|
||||||
const changePage = () => {
|
const changePage = () => {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user