swagger文档增加文档搜索和录入示例,修改编辑问题
This commit is contained in:
@@ -35,8 +35,7 @@ export default {
|
||||
} else if (parameter.items && parameter.items.type) {
|
||||
subType = parameter.items.type;
|
||||
} else {
|
||||
console.log('001-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
message.error('001-遇到未处理的类型,请联系开发人员修改:' + type);
|
||||
this.logMessage('001', type, parameter);
|
||||
}
|
||||
} else if (!type) {
|
||||
if (parameter.schema) {
|
||||
@@ -56,14 +55,13 @@ export default {
|
||||
} else if (parameter.schema.items.type) {
|
||||
subType = parameter.schema.items.type;
|
||||
} else {
|
||||
console.log('0014-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
this.log('0014', type, parameter);
|
||||
}
|
||||
} else {
|
||||
console.log('0011-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
this.log('0011', type, parameter);
|
||||
}
|
||||
} else {
|
||||
console.log('0013-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
message.error('0013-遇到未处理的类型,请联系开发人员修改:' + type);
|
||||
this.logMessage('0013', type, parameter);
|
||||
}
|
||||
} else if (parameter.items && parameter.items.type) {
|
||||
// 解析parameter.items {type: "object", $ref: "#/definitions/Model"}
|
||||
@@ -73,19 +71,16 @@ export default {
|
||||
children = this.getAdditionalProperties(parameter.items.additionalProperties, additional, definitionsDataMap, indexKey, {}, 0);
|
||||
format = additional.type;
|
||||
} else {
|
||||
console.log('0012-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
message.error('0012-遇到未处理的类型,请联系开发人员修改:' + type);
|
||||
this.logMessage('0012', type, parameter);
|
||||
}
|
||||
} else {
|
||||
console.log('002-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
message.error('002-遇到未处理的类型,请联系开发人员修改:' + type);
|
||||
this.logMessage('002', type, parameter);
|
||||
}
|
||||
} else {
|
||||
if (notNeedHandleTypeArr.indexOf(type) >= 0) {
|
||||
// 无需特殊处理的类型
|
||||
} else {
|
||||
console.log('003-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
message.error('003-遇到未处理的类型,请联系开发人员修改:' + type);
|
||||
this.logMessage('003', type, parameter);
|
||||
}
|
||||
}
|
||||
if (parameter.enum && parameter.enum.length > 0) {
|
||||
@@ -171,8 +166,7 @@ export default {
|
||||
} else if (parameter.items && parameter.items.type) {
|
||||
subType = parameter.items.type;
|
||||
} else {
|
||||
console.log('004-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
message.error('004-遇到未处理的类型,请联系开发人员修改:' + type);
|
||||
this.logMessage('004', type, parameter);
|
||||
}
|
||||
} else if (type === 'object') {
|
||||
if (parameter.additionalProperties) {
|
||||
@@ -180,22 +174,20 @@ export default {
|
||||
children = this.getAdditionalProperties(parameter.additionalProperties, additional, definitionsDataMap, keySub, parentRef, deep + 1);
|
||||
format = additional.type;
|
||||
} else {
|
||||
console.log('0041-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
this.log('0041', type, parameter);
|
||||
}
|
||||
} else if (!type) {
|
||||
if (parameter.originalRef) {
|
||||
type = parameter.originalRef;
|
||||
children = this.getParamDefinitions(parameter.originalRef, definitionsDataMap, keySub, parentRef, deep + 1);
|
||||
} else {
|
||||
console.log('005-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
message.error('005-遇到未处理的类型,请联系开发人员修改:' + type);
|
||||
this.logMessage('005', type, parameter);
|
||||
}
|
||||
} else {
|
||||
if (notNeedHandleTypeArr.indexOf(type) >= 0) {
|
||||
// 无需特殊处理的类型
|
||||
} else {
|
||||
console.log('006-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
message.error('006-遇到未处理的类型,请联系开发人员修改:' + type);
|
||||
this.logMessage('006', type, parameter);
|
||||
}
|
||||
}
|
||||
if (parameter.items && parameter.items.enum && parameter.items.enum.length > 0) {
|
||||
@@ -239,19 +231,24 @@ export default {
|
||||
};
|
||||
return children;
|
||||
} else {
|
||||
console.log('007-遇到未处理的类型,请联系开发人员修改:', additionalProperties);
|
||||
message.error('007-遇到未处理的类型,请联系开发人员修改');
|
||||
this.logMessage('007', '', additionalProperties);
|
||||
}
|
||||
} else {
|
||||
additional.type = additionalProperties.type;
|
||||
if (notNeedHandleTypeArr.indexOf(additional.type) >= 0) {
|
||||
// 无需特殊处理的类型
|
||||
} else {
|
||||
console.log('008-遇到未处理的类型,请联系开发人员修改:', additionalProperties);
|
||||
message.error('008-遇到未处理的类型,请联系开发人员修改');
|
||||
this.logMessage('008', '', additionalProperties);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
log(code, type, parameter) {
|
||||
console.log(code + '-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
},
|
||||
logMessage(code, type, parameter) {
|
||||
console.log(code + '-遇到未处理的类型,请联系开发人员修改:' + type, parameter);
|
||||
message.error(code + '-遇到未处理的类型,请联系开发人员修改:' + type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<a-select placeholder="请选择分组" v-model:value="swaggerDocChoice" @change="swaggerDocChoiceChange" style="width: 100%;">
|
||||
<a-select-option :value="item.url" v-for="item in swaggerResourceList">{{item.name}}</a-select-option>
|
||||
</a-select>
|
||||
<a-input-search v-model:value="searchKeywords" placeholder="搜索文档内容" style="width: 100%;margin-top: 10px;" @search="loadTreeData"/>
|
||||
</div>
|
||||
<a-directory-tree :showIcon="false" :tree-data="treeData" v-model:expandedKeys="expandedKeys" @select="docChecked">
|
||||
<template #title="{ title, isLeaf, method, children, key }">
|
||||
@@ -35,7 +36,7 @@
|
||||
<script>
|
||||
import MenuChildrenLayout from './MenuChildrenLayout.vue'
|
||||
import {customApi} from '../../api'
|
||||
import {createTreeViewByTag, getTreeDataForTag} from '../../store/SwaggerDocUtil'
|
||||
import {createTreeViewByTag, getTreeDataForTag} from '../../store/TreeViewByTag'
|
||||
|
||||
export default {
|
||||
name: 'MenuLayout',
|
||||
@@ -52,10 +53,13 @@
|
||||
openKeys: [],
|
||||
// 文档树
|
||||
treeDataLoading: false,
|
||||
pathData: {},
|
||||
swaggerDoc: {},
|
||||
treeData: [],
|
||||
expandedKeys: [],
|
||||
swaggerResourceList: [],
|
||||
swaggerDocChoice: undefined,
|
||||
searchKeywords: '',
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
@@ -104,27 +108,32 @@
|
||||
});
|
||||
},
|
||||
swaggerDocChoiceChange() {
|
||||
this.loadV2Doc(this.swaggerDocChoice);
|
||||
this.loadV2Doc();
|
||||
},
|
||||
loadV2Doc(url) {
|
||||
this.expandedKeys = [];
|
||||
loadV2Doc() {
|
||||
this.treeDataLoading = true;
|
||||
customApi.get(url).then(res => {
|
||||
customApi.get(this.swaggerDocChoice).then(res => {
|
||||
let v2Doc = this.toJsonObj(res);
|
||||
if (typeof v2Doc !== 'object' || !v2Doc.swagger) {
|
||||
this.$message.error('获取文档数据请求失败');
|
||||
this.treeDataLoading = false;
|
||||
return;
|
||||
}
|
||||
this.$store.commit('setSwaggerDoc', v2Doc);
|
||||
let metaInfo = {url};
|
||||
let treeData = createTreeViewByTag(v2Doc, '');
|
||||
this.treeData = getTreeDataForTag(v2Doc, treeData.pathData, metaInfo);
|
||||
this.swaggerDoc = v2Doc;
|
||||
this.$store.commit('setSwaggerDoc', this.swaggerDoc);
|
||||
let treeData = createTreeViewByTag(this.swaggerDoc);
|
||||
this.$store.commit('setSwaggerTreePathMap', treeData.pathDataMap);
|
||||
this.$store.commit('setMethodStatistic', treeData.methodStatistic);
|
||||
this.pathData = treeData.pathData;
|
||||
this.loadTreeData();
|
||||
setTimeout(() => this.treeDataLoading = false, 100);
|
||||
});
|
||||
},
|
||||
loadTreeData() {
|
||||
this.expandedKeys = ['main'];
|
||||
let metaInfo = {url: this.swaggerDocChoice};
|
||||
this.treeData = getTreeDataForTag(this.swaggerDoc, this.pathData, this.searchKeywords, metaInfo);
|
||||
},
|
||||
toJsonObj(value) {
|
||||
if (typeof value !== 'string') {
|
||||
return value;
|
||||
|
||||
@@ -3,10 +3,9 @@ const methodArray = ["get", "head", "post", "put", "patch", "delete", "options",
|
||||
/**
|
||||
* 通过tag创建文档树
|
||||
* @param swagger 文档内容
|
||||
* @param keywords 搜索内容
|
||||
* @returns {{pathDataMap: {}, pathData: {}}}
|
||||
*/
|
||||
export function createTreeViewByTag(swagger, keywords) {
|
||||
export function createTreeViewByTag(swagger) {
|
||||
let pathData = {}, pathDataMap = {}, methodStatistic = {};
|
||||
let swaggerPaths = swagger.paths;
|
||||
if (!swaggerPaths) {
|
||||
@@ -45,21 +44,11 @@ export function createTreeViewByTag(swagger, keywords) {
|
||||
return {pathData, pathDataMap, methodStatistic};
|
||||
}
|
||||
|
||||
export function getTreeDataForTag(swagger, pathData, metaInfo) {
|
||||
return [
|
||||
{
|
||||
key: 'main',
|
||||
title: swagger.title || 'Swagger接口文档',
|
||||
children: getTreeHtmlForTag(swagger.tags, pathData, metaInfo)
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function getTreeHtmlForTag(swaggerTags, pathData, metaInfo) {
|
||||
export function getTreeDataForTag(swagger, pathData, keywords, metaInfo) {
|
||||
let treeData = [];
|
||||
let indexTag = 1;
|
||||
// 遍历分组
|
||||
swaggerTags.forEach(tag => {
|
||||
swagger.tags.forEach(tag => {
|
||||
let indexUrl = 1;
|
||||
let urlTree = [];
|
||||
let pathTagNode = pathData[tag.name];
|
||||
@@ -74,6 +63,9 @@ function getTreeHtmlForTag(swaggerTags, pathData, metaInfo) {
|
||||
Object.keys(pathUrlNode).forEach(method => {
|
||||
let tempTreeId = indexTag + "_" + indexUrl + "_" + indexMethod;
|
||||
let methodNode = pathUrlNode[method];
|
||||
if (!searchInPathMethods(url, methodNode, keywords)) {
|
||||
return;
|
||||
}
|
||||
methodNode.treeId = tempTreeId;
|
||||
let title = methodNode.summary || methodNode.path;
|
||||
urlTree.push({
|
||||
@@ -94,5 +86,25 @@ function getTreeHtmlForTag(swaggerTags, pathData, metaInfo) {
|
||||
treeData.push({title: tag.name, key: indexTag, children: urlTree});
|
||||
indexTag++;
|
||||
});
|
||||
return treeData;
|
||||
return [
|
||||
{
|
||||
key: 'main',
|
||||
title: swagger.title || 'Swagger接口文档',
|
||||
children: treeData
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function searchInPathMethods(url, methodNode, keywords) {
|
||||
if (!keywords || !url) {
|
||||
return true;
|
||||
}
|
||||
url = url.toLowerCase();
|
||||
keywords = keywords.toLowerCase();
|
||||
// 路径中有就不用再去找了
|
||||
if (url.indexOf(keywords) >= 0) {
|
||||
return true;
|
||||
}
|
||||
let searchData = methodNode.path + methodNode.summary + methodNode.description + methodNode.tags;
|
||||
return (searchData && searchData.toLowerCase().indexOf(keywords) >= 0);
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import {createStore} from 'vuex'
|
||||
import {createTreeViewByTag} from './SwaggerDocUtil'
|
||||
|
||||
export default createStore({
|
||||
state() {
|
||||
|
||||
@@ -31,25 +31,20 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { toRefs, ref, reactive, onMounted, computed } from 'vue';
|
||||
import {useStore} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'docInfo',
|
||||
components: {},
|
||||
data() {
|
||||
return {}
|
||||
setup() {
|
||||
const store = useStore()
|
||||
const swaggerDoc = computed(() => store.state.swaggerDoc);
|
||||
const swaggerDocInfo = computed(() => store.state.swaggerDoc.info);
|
||||
const methodStatistic = computed(() => store.state.methodStatistic);
|
||||
return {
|
||||
swaggerDoc,
|
||||
swaggerDocInfo,
|
||||
methodStatistic
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
swaggerDoc () {
|
||||
return this.$store.state.swaggerDoc || {};
|
||||
},
|
||||
swaggerDocInfo () {
|
||||
return this.$store.state.swaggerDoc.info;
|
||||
},
|
||||
methodStatistic () {
|
||||
return this.$store.state.methodStatistic;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -65,9 +65,32 @@
|
||||
</a-form-item>
|
||||
<a-form-item label="文档地址" required name="docUrl" v-if="docEdit.docType === 1">
|
||||
<a-input placeholder="请输入文档地址URL" v-model:value="docEdit.docUrl"></a-input>
|
||||
<template #extra>
|
||||
查看文档地址
|
||||
<a-popover title="文档地址支持以下任一格式">
|
||||
<template #content>
|
||||
<p>格式一:http://doc.zyplayer.com/v2/api-docs</p>
|
||||
<p>格式二:http://doc.zyplayer.com/swagger-resources</p>
|
||||
<p>格式三:http://doc.zyplayer.com/swagger-ui.html</p>
|
||||
</template>
|
||||
<a>示例</a>
|
||||
</a-popover>
|
||||
</template>
|
||||
</a-form-item>
|
||||
<a-form-item label="文档内容" required name="jsonContent" v-else-if="docEdit.docType === 2">
|
||||
<a-textarea placeholder="请输入JSON格式的swagger文档内容" v-model:value="docEdit.jsonContent"></a-textarea>
|
||||
<template #extra>
|
||||
查看文档内容
|
||||
<a-popover title="文档内容说明">
|
||||
<template #content>
|
||||
<div>支持以下格式的Swagger文档内容输入,其中 {"swagger": "2.0"} 为必要属性</div>
|
||||
<div v-highlight>
|
||||
<pre><code class="lang-json">{{swaggerDocDemo}}</code></pre>
|
||||
</div>
|
||||
</template>
|
||||
<a>说明</a>
|
||||
</a-popover>
|
||||
</template>
|
||||
</a-form-item>
|
||||
<a-form-item label="开放访问" required name="openVisit">
|
||||
<a-radio-group v-model:value="docEdit.openVisit">
|
||||
@@ -167,6 +190,16 @@
|
||||
{title: '目标域名', dataIndex: 'rewriteDomain', width: 250},
|
||||
{title: '操作', dataIndex: 'operation', fixed: 'right', width: 170},
|
||||
],
|
||||
swaggerDocDemo:
|
||||
'{\n'
|
||||
+ ' "swagger": "2.0",\n'
|
||||
+ ' "info": {},\n'
|
||||
+ ' "host": "doc.zyplayer.com",\n'
|
||||
+ ' "basePath":"/",\n'
|
||||
+ ' "tags": [],\n'
|
||||
+ ' "paths": {},\n'
|
||||
+ ' "definitions": {}\n'
|
||||
+ '}'
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
let docList = ref([]);
|
||||
let docListLoading = ref(false);
|
||||
const searchDocList = async () => {
|
||||
docEdit.value = {};
|
||||
docListLoading.value = true;
|
||||
zyplayerApi.docSwaggerGlobalParamList().then(res => {
|
||||
setTimeout(() => docListLoading.value = false, 500);
|
||||
@@ -66,13 +67,16 @@
|
||||
let docEdit = ref({});
|
||||
const addDocLine = () => {
|
||||
if (docEdit.value.isEdit) {
|
||||
return;
|
||||
cancelEditDoc(docEdit.value);
|
||||
}
|
||||
let newLine = {isEdit: true};
|
||||
docList.value.push(newLine);
|
||||
docEdit.value = newLine;
|
||||
};
|
||||
const editDoc = (record) => {
|
||||
if (docEdit.value.isEdit) {
|
||||
cancelEditDoc(docEdit.value);
|
||||
}
|
||||
record.isEdit = true;
|
||||
docEdit.value = {...record};
|
||||
};
|
||||
@@ -80,6 +84,8 @@
|
||||
record.isEdit = false;
|
||||
if (!record.id) {
|
||||
docList.value = docList.value.filter(item => item !== record);
|
||||
} else {
|
||||
docList.value.forEach(item => item.isEdit = false);
|
||||
}
|
||||
docEdit.value = {};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user