swagger文档增加文档搜索和录入示例,修改编辑问题

This commit is contained in:
暮光:城中城
2021-10-30 22:33:48 +08:00
parent c8f570fa6a
commit 9fcdfb7758
23 changed files with 133 additions and 80 deletions

View File

@@ -49,7 +49,9 @@ public class SwaggerProxyController {
@RequestMapping("/swagger-resources")
public List<SwaggerResource> swaggerResources() {
List<SwaggerResource> resourceList = new LinkedList<>();
List<SwaggerDoc> docList = swaggerDocService.getSwaggerDocList(new SwaggerDoc());
SwaggerDoc swaggerSearch = new SwaggerDoc();
swaggerSearch.setDocStatus(1);
List<SwaggerDoc> docList = swaggerDocService.getSwaggerDocList(swaggerSearch);
for (SwaggerDoc swaggerDoc : docList) {
SwaggerResource resource = new SwaggerResource();
resource.setUrl("/v2/api-docs?id=" + swaggerDoc.getId());

View File

@@ -0,0 +1 @@
import{O as a,P as e,r as t,c as o,w as s,o as l,a as n,p as r,t as c,b as g,n as f,d as i,e as u,F as d}from"./vendor.d5dc506b.js";const w={setup(){const t=a();return{swaggerDoc:e((()=>t.state.swaggerDoc)),swaggerDocInfo:e((()=>t.state.swaggerDoc.info)),methodStatistic:e((()=>t.state.methodStatistic))}}},D=["href"],I=["href"],_=["innerHTML"],m={key:1,style:{"text-align":"center"}};w.render=function(a,e,w,T,b,p){const h=t("a-form-item"),k=t("a-statistic"),y=t("a-card"),E=t("a-col"),O=t("a-row"),S=t("a-form");return l(),o(y,null,{default:s((()=>[T.swaggerDocInfo?(l(),o(S,{key:0,"label-col":{span:4},"wrapper-col":{span:20}},{default:s((()=>[n(h,{label:"标题"},{default:s((()=>[r(c(T.swaggerDocInfo.title),1)])),_:1}),n(h,{label:"版本"},{default:s((()=>[r(c(T.swaggerDocInfo.version),1)])),_:1}),T.swaggerDocInfo.contact?(l(),o(h,{key:0,label:"作者"},{default:s((()=>[r(c(T.swaggerDocInfo.contact.name)+" "+c(T.swaggerDocInfo.contact.email)+" ",1),T.swaggerDocInfo.contact.url?(l(),g("a",{key:0,href:T.swaggerDocInfo.contact.url,target:"_blank"},c(T.swaggerDocInfo.contact.url),9,D)):f("",!0)])),_:1})):f("",!0),n(h,{label:"host"},{default:s((()=>[r(c(T.swaggerDoc.host),1)])),_:1}),T.swaggerDocInfo.license?(l(),o(h,{key:1,label:"许可证"},{default:s((()=>[i("a",{href:T.swaggerDocInfo.license.url,target:"_blank"},c(T.swaggerDocInfo.license.name),9,I)])),_:1})):f("",!0),n(h,{label:"文档说明"},{default:s((()=>[i("span",{innerHTML:T.swaggerDocInfo.description},null,8,_)])),_:1}),n(h,{label:"接口统计"},{default:s((()=>[n(O,{gutter:[16,16]},{default:s((()=>[(l(),g(d,null,u(["GET","POST","PUT","DELETE","HEAD","PATCH","OPTIONS","TRACE","TOTAL"],(a=>(l(),g(d,null,[T.methodStatistic[a]?(l(),o(E,{key:0,span:6},{default:s((()=>[n(y,{size:"small"},{default:s((()=>[n(k,{title:"TOTAL"===a?"总计":a+"方法",value:T.methodStatistic[a],suffix:"个"},null,8,["title","value"])])),_:2},1024)])),_:2},1024)):f("",!0)],64)))),64))])),_:1})])),_:1})])),_:1})):(l(),g("div",m,"暂无文档信息,请先选择文档"))])),_:1})};export{w as default};

View File

@@ -1 +0,0 @@
import{r as e,c as a,w as t,o,a as s,p as l,t as n,b as r,n as c,d as g,e as f,F as i}from"./vendor.c3726933.js";const u={name:"docInfo",components:{},data:()=>({}),computed:{swaggerDoc(){return this.$store.state.swaggerDoc||{}},swaggerDocInfo(){return this.$store.state.swaggerDoc.info},methodStatistic(){return this.$store.state.methodStatistic}},mounted(){},methods:{}},d=["href"],w=["href"],D=["innerHTML"],m={key:1,style:{"text-align":"center"}};u.render=function(u,I,h,_,T,p){const b=e("a-form-item"),k=e("a-statistic"),y=e("a-card"),E=e("a-col"),S=e("a-row"),v=e("a-form");return o(),a(y,null,{default:t((()=>[p.swaggerDocInfo?(o(),a(v,{key:0,"label-col":{span:4},"wrapper-col":{span:20}},{default:t((()=>[s(b,{label:"标题"},{default:t((()=>[l(n(p.swaggerDocInfo.title),1)])),_:1}),s(b,{label:"版本"},{default:t((()=>[l(n(p.swaggerDocInfo.version),1)])),_:1}),p.swaggerDocInfo.contact?(o(),a(b,{key:0,label:"作者"},{default:t((()=>[l(n(p.swaggerDocInfo.contact.name)+" "+n(p.swaggerDocInfo.contact.email)+" ",1),p.swaggerDocInfo.contact.url?(o(),r("a",{key:0,href:p.swaggerDocInfo.contact.url,target:"_blank"},n(p.swaggerDocInfo.contact.url),9,d)):c("",!0)])),_:1})):c("",!0),s(b,{label:"host"},{default:t((()=>[l(n(p.swaggerDoc.host),1)])),_:1}),p.swaggerDocInfo.license?(o(),a(b,{key:1,label:"许可证"},{default:t((()=>[g("a",{href:p.swaggerDocInfo.license.url,target:"_blank"},n(p.swaggerDocInfo.license.name),9,w)])),_:1})):c("",!0),s(b,{label:"文档说明"},{default:t((()=>[g("span",{innerHTML:p.swaggerDocInfo.description},null,8,D)])),_:1}),s(b,{label:"接口统计"},{default:t((()=>[s(S,{gutter:[16,16]},{default:t((()=>[(o(),r(i,null,f(["GET","POST","PUT","DELETE","HEAD","PATCH","OPTIONS","TRACE","TOTAL"],(e=>(o(),r(i,null,[p.methodStatistic[e]?(o(),a(E,{key:0,span:6},{default:t((()=>[s(y,{size:"small"},{default:t((()=>[s(k,{title:"TOTAL"===e?"总计":e+"方法",value:p.methodStatistic[e],suffix:"个"},null,8,["title","value"])])),_:2},1024)])),_:2},1024)):c("",!0)],64)))),64))])),_:1})])),_:1})])),_:1})):(o(),r("div",m,"暂无文档信息,请先选择文档"))])),_:1})};export{u as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
var e=Object.defineProperty,a=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,o=(a,t,l)=>t in a?e(a,t,{enumerable:!0,configurable:!0,writable:!0,value:l}):a[t]=l;import{z as d}from"./custom.192c812b.js";import{O as i,P as n,Q as r,r as c,b as u,d as s,a as p,w as y,F as m,o as k,c as v,t as f,n as E,p as g}from"./vendor.c3726933.js";const b={setup(){i();let e=n([]),c=n(!1);const u=async()=>{c.value=!0,d.docSwaggerGlobalParamList().then((a=>{setTimeout((()=>c.value=!1),500),e.value=a.data||[]}))};let s=n({});return r((()=>{u()})),{docList:e,docListLoading:c,docEdit:s,searchDocList:u,deleteDoc:async e=>{d.docSwaggerGlobalParamUpdate({id:e.id,yn:0}).then((e=>{u()}))},editDoc:e=>{e.isEdit=!0,s.value=((e,d)=>{for(var i in d||(d={}))t.call(d,i)&&o(e,i,d[i]);if(a)for(var i of a(d))l.call(d,i)&&o(e,i,d[i]);return e})({},e)},saveEditDoc:e=>{d.docSwaggerGlobalParamUpdate(s.value).then((a=>{e.isEdit=!1,u()}))},cancelEditDoc:a=>{a.isEdit=!1,a.id||(e.value=e.value.filter((e=>e!==a))),s.value={}},addDocLine:()=>{if(s.value.isEdit)return;let a={isEdit:!0};e.value.push(a),s.value=a},docListColumns:[{title:"参数名称",dataIndex:"paramKey",width:250},{title:"参数值",dataIndex:"paramValue"},{title:"参数位置",dataIndex:"paramType",width:120},{title:"操作",dataIndex:"operation",fixed:"right",width:170}]}}},h={style:{"margin-bottom":"10px","text-align":"right"}},x=g("刷新"),C=g("新建"),_={key:1},L={key:1},w=g("Form"),D=g("Header"),I=g("Cookie"),O=g("Form"),P=g("Header"),j=g("Cookie"),S=g("取消"),T=g("保存"),U=g("编辑"),K=g("删除");b.render=function(e,a,t,l,o,d){const i=c("a-button"),n=c("a-input"),r=c("a-textarea"),g=c("a-select-option"),b=c("a-select"),V=c("a-tag"),F=c("a-popconfirm"),G=c("a-table");return k(),u(m,null,[s("div",h,[p(i,{onClick:l.searchDocList,type:"primary"},{default:y((()=>[x])),_:1},8,["onClick"]),p(i,{onClick:l.addDocLine},{default:y((()=>[C])),_:1},8,["onClick"])]),p(G,{dataSource:l.docList,columns:l.docListColumns,size:"middle",loading:l.docListLoading,pagination:!1,scroll:{x:1e3,y:"calc(100vh - 340px)"}},{bodyCell:y((({column:e,text:t,record:o})=>["paramKey"===e.dataIndex?(k(),u(m,{key:0},[o.isEdit?(k(),v(n,{key:0,placeholder:"请输入参数名称",value:l.docEdit.paramKey,"onUpdate:value":a[0]||(a[0]=e=>l.docEdit.paramKey=e)},null,8,["value"])):(k(),u("span",_,f(t),1))],64)):E("",!0),"paramValue"===e.dataIndex?(k(),u(m,{key:1},[o.isEdit?(k(),v(r,{key:0,rows:1,placeholder:"请输入参数值",value:l.docEdit.paramValue,"onUpdate:value":a[1]||(a[1]=e=>l.docEdit.paramValue=e)},null,8,["value"])):(k(),u("span",L,f(t),1))],64)):E("",!0),"paramType"===e.dataIndex?(k(),u(m,{key:2},[o.isEdit?(k(),v(b,{key:0,placeholder:"参数位置",value:l.docEdit.paramType,"onUpdate:value":a[2]||(a[2]=e=>l.docEdit.paramType=e),style:{width:"110px"}},{default:y((()=>[p(g,{value:1},{default:y((()=>[w])),_:1}),p(g,{value:2},{default:y((()=>[D])),_:1}),p(g,{value:3},{default:y((()=>[I])),_:1})])),_:1},8,["value"])):(k(),u(m,{key:1},[1===t?(k(),v(V,{key:0,color:"green"},{default:y((()=>[O])),_:1})):2===t?(k(),v(V,{key:1,color:"pink"},{default:y((()=>[P])),_:1})):3===t?(k(),v(V,{key:2,color:"pink"},{default:y((()=>[j])),_:1})):E("",!0)],64))],64)):E("",!0),"operation"===e.dataIndex?(k(),u(m,{key:3},[o.isEdit?(k(),u(m,{key:0},[p(i,{type:"link",onClick:e=>l.cancelEditDoc(o)},{default:y((()=>[S])),_:2},1032,["onClick"]),p(i,{type:"link",onClick:e=>l.saveEditDoc(o)},{default:y((()=>[T])),_:2},1032,["onClick"])],64)):(k(),u(m,{key:1},[p(i,{type:"link",onClick:e=>l.editDoc(o)},{default:y((()=>[U])),_:2},1032,["onClick"]),p(F,{title:"确定要删除吗?",onConfirm:e=>l.deleteDoc(o)},{default:y((()=>[p(i,{type:"link",danger:""},{default:y((()=>[K])),_:1})])),_:2},1032,["onConfirm"])],64))],64)):E("",!0)])),_:1},8,["dataSource","columns","loading","scroll"])],64)};export{b as default};

View File

@@ -0,0 +1 @@
var e=Object.defineProperty,a=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,o=(a,t,l)=>t in a?e(a,t,{enumerable:!0,configurable:!0,writable:!0,value:l}):a[t]=l;import{z as d}from"./custom.6e797d8c.js";import{O as i,Q as n,R as r,r as c,b as u,d as s,a as p,w as y,F as m,o as v,c as k,t as f,n as E,p as g}from"./vendor.d5dc506b.js";const b={setup(){i();let e=n([]),c=n(!1);const u=async()=>{s.value={},c.value=!0,d.docSwaggerGlobalParamList().then((a=>{setTimeout((()=>c.value=!1),500),e.value=a.data||[]}))};let s=n({});const p=a=>{a.isEdit=!1,a.id?e.value.forEach((e=>e.isEdit=!1)):e.value=e.value.filter((e=>e!==a)),s.value={}};return r((()=>{u()})),{docList:e,docListLoading:c,docEdit:s,searchDocList:u,deleteDoc:async e=>{d.docSwaggerGlobalParamUpdate({id:e.id,yn:0}).then((e=>{u()}))},editDoc:e=>{s.value.isEdit&&p(s.value),e.isEdit=!0,s.value=((e,d)=>{for(var i in d||(d={}))t.call(d,i)&&o(e,i,d[i]);if(a)for(var i of a(d))l.call(d,i)&&o(e,i,d[i]);return e})({},e)},saveEditDoc:e=>{d.docSwaggerGlobalParamUpdate(s.value).then((a=>{e.isEdit=!1,u()}))},cancelEditDoc:p,addDocLine:()=>{s.value.isEdit&&p(s.value);let a={isEdit:!0};e.value.push(a),s.value=a},docListColumns:[{title:"参数名称",dataIndex:"paramKey",width:250},{title:"参数值",dataIndex:"paramValue"},{title:"参数位置",dataIndex:"paramType",width:120},{title:"操作",dataIndex:"operation",fixed:"right",width:170}]}}},h={style:{"margin-bottom":"10px","text-align":"right"}},x=g("刷新"),C=g("新建"),_={key:1},L={key:1},w=g("Form"),D=g("Header"),I=g("Cookie"),O=g("Form"),j=g("Header"),P=g("Cookie"),S=g("取消"),T=g("保存"),U=g("编辑"),K=g("删除");b.render=function(e,a,t,l,o,d){const i=c("a-button"),n=c("a-input"),r=c("a-textarea"),g=c("a-select-option"),b=c("a-select"),V=c("a-tag"),F=c("a-popconfirm"),G=c("a-table");return v(),u(m,null,[s("div",h,[p(i,{onClick:l.searchDocList,type:"primary"},{default:y((()=>[x])),_:1},8,["onClick"]),p(i,{onClick:l.addDocLine},{default:y((()=>[C])),_:1},8,["onClick"])]),p(G,{dataSource:l.docList,columns:l.docListColumns,size:"middle",loading:l.docListLoading,pagination:!1,scroll:{x:1e3,y:"calc(100vh - 340px)"}},{bodyCell:y((({column:e,text:t,record:o})=>["paramKey"===e.dataIndex?(v(),u(m,{key:0},[o.isEdit?(v(),k(n,{key:0,placeholder:"请输入参数名称",value:l.docEdit.paramKey,"onUpdate:value":a[0]||(a[0]=e=>l.docEdit.paramKey=e)},null,8,["value"])):(v(),u("span",_,f(t),1))],64)):E("",!0),"paramValue"===e.dataIndex?(v(),u(m,{key:1},[o.isEdit?(v(),k(r,{key:0,rows:1,placeholder:"请输入参数值",value:l.docEdit.paramValue,"onUpdate:value":a[1]||(a[1]=e=>l.docEdit.paramValue=e)},null,8,["value"])):(v(),u("span",L,f(t),1))],64)):E("",!0),"paramType"===e.dataIndex?(v(),u(m,{key:2},[o.isEdit?(v(),k(b,{key:0,placeholder:"参数位置",value:l.docEdit.paramType,"onUpdate:value":a[2]||(a[2]=e=>l.docEdit.paramType=e),style:{width:"110px"}},{default:y((()=>[p(g,{value:1},{default:y((()=>[w])),_:1}),p(g,{value:2},{default:y((()=>[D])),_:1}),p(g,{value:3},{default:y((()=>[I])),_:1})])),_:1},8,["value"])):(v(),u(m,{key:1},[1===t?(v(),k(V,{key:0,color:"green"},{default:y((()=>[O])),_:1})):2===t?(v(),k(V,{key:1,color:"pink"},{default:y((()=>[j])),_:1})):3===t?(v(),k(V,{key:2,color:"pink"},{default:y((()=>[P])),_:1})):E("",!0)],64))],64)):E("",!0),"operation"===e.dataIndex?(v(),u(m,{key:3},[o.isEdit?(v(),u(m,{key:0},[p(i,{type:"link",onClick:e=>l.cancelEditDoc(o)},{default:y((()=>[S])),_:2},1032,["onClick"]),p(i,{type:"link",onClick:e=>l.saveEditDoc(o)},{default:y((()=>[T])),_:2},1032,["onClick"])],64)):(v(),u(m,{key:1},[p(i,{type:"link",onClick:e=>l.editDoc(o)},{default:y((()=>[U])),_:2},1032,["onClick"]),p(F,{title:"确定要删除吗?",onConfirm:e=>l.deleteDoc(o)},{default:y((()=>[p(i,{type:"link",danger:""},{default:y((()=>[K])),_:1})])),_:2},1032,["onConfirm"])],64))],64)):E("",!0)])),_:1},8,["dataSource","columns","loading","scroll"])],64)};export{b as default};

View File

@@ -1 +1 @@
import{b as e,o as t}from"./vendor.c3726933.js";const n={name:"SettingView",components:{},data:()=>({}),computed:{},mounted(){},methods:{}};n.render=function(n,o,d,r,a,m){return t(),e("div",null," 展示配置页面 ")};export{n as default};
import{b as e,o as t}from"./vendor.d5dc506b.js";const n={name:"SettingView",components:{},data:()=>({}),computed:{},mounted(){},methods:{}};n.render=function(n,o,d,r,a,m){return t(),e("div",null," 展示配置页面 ")};export{n as default};

View File

@@ -5,8 +5,8 @@
<link rel="icon" href="logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Swagger文档管理</title>
<script type="module" crossorigin src="assets/main.362668ae.js"></script>
<link rel="modulepreload" href="assets/vendor.c3726933.js">
<script type="module" crossorigin src="assets/main.9ed5a245.js"></script>
<link rel="modulepreload" href="assets/vendor.d5dc506b.js">
<link rel="stylesheet" href="assets/style.6e7ba32f.css">
</head>
<body>

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -1,5 +1,4 @@
import {createStore} from 'vuex'
import {createTreeViewByTag} from './SwaggerDocUtil'
export default createStore({
state() {

View File

@@ -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>

View File

@@ -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'
+ '}'
};
},
};

View File

@@ -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 = {};
};