文档分组显示

1.x
tanghc 6 years ago
parent f9c8a859b7
commit dc00bcad2e
  1. 17
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenResultExecutor.java
  2. 30
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenZuulConfiguration.java
  3. 31
      sop-example/sop-easyopen/src/main/java/com/gitee/easyopen/server/api/Goods2Api.java
  4. 2
      sop-example/sop-easyopen/src/main/java/com/gitee/easyopen/server/api/GoodsApi.java
  5. 28
      sop-example/sop-easyopen/src/main/java/com/gitee/easyopen/server/config/BaseSopDocController.java
  6. 9
      sop-example/sop-easyopen/src/main/java/com/gitee/easyopen/server/config/SopConfig.java
  7. 2
      sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/bookweb/controller/AlipayController.java
  8. 2
      sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/bookweb/controller/Story2Controller.java
  9. 20
      sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java
  10. 76
      sop-website/website-front/pages/doc/doc.js
  11. 14
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/DocInfo.java
  12. 1
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/DocItem.java
  13. 20
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/controller/DocController.java
  14. 6
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManager.java
  15. 119
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java
  16. 11
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocParser.java
  17. 83
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/EasyopenDocParser.java
  18. 112
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java
  19. 2
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/vo/DocBaseInfoVO.java
  20. 4
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/vo/DocInfoVO.java

@ -1,19 +1,34 @@
package com.gitee.sop.gatewaycommon.easyopen;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.gatewaycommon.message.Error;
import com.gitee.sop.gatewaycommon.result.ApiResult;
import com.gitee.sop.gatewaycommon.result.ResultExecutor;
import com.gitee.sop.gatewaycommon.zuul.result.ZuulResultExecutor;
import com.netflix.zuul.context.RequestContext;
import java.util.Optional;
/**
* @author tanghc
*/
public class EasyopenResultExecutor implements ResultExecutor<RequestContext, String> {
boolean onlyReturnData;
public EasyopenResultExecutor(boolean onlyReturnData) {
this.onlyReturnData = onlyReturnData;
}
@Override
public String mergeResult(RequestContext request, String serviceResult) {
return serviceResult;
if (onlyReturnData) {
JSONObject jsonObject = JSON.parseObject(serviceResult);
return Optional.ofNullable(jsonObject.getString("data")).orElse("{}");
} else {
return serviceResult;
}
}
@Override

@ -10,15 +10,29 @@ import com.gitee.sop.gatewaycommon.zuul.configuration.BaseZuulConfiguration;
*/
public class EasyopenZuulConfiguration extends BaseZuulConfiguration {
static {
ParamNames.APP_KEY_NAME = "app_key";
ParamNames.API_NAME = "name";
ParamNames.SIGN_TYPE_NAME = "sign_type";
ParamNames.APP_AUTH_TOKEN_NAME = "access_token";
public EasyopenZuulConfiguration() {
ApiConfig apiConfig = ApiContext.getApiConfig();
apiConfig.setSigner(new EasyopenSigner());
apiConfig.setZuulResultExecutor(new EasyopenResultExecutor());
apiConfig.setMergeResult(false);
if (compatibilityModel()) {
ParamNames.APP_KEY_NAME = "app_key";
ParamNames.API_NAME = "name";
ParamNames.SIGN_TYPE_NAME = "sign_type";
ParamNames.APP_AUTH_TOKEN_NAME = "access_token";
apiConfig.setSigner(new EasyopenSigner());
apiConfig.setZuulResultExecutor(new EasyopenResultExecutor(false));
apiConfig.setMergeResult(false);
} else {
apiConfig.setZuulResultExecutor(new EasyopenResultExecutor(true));
}
}
/**
* 是否是兼容模式
* @return 返回true返回true可兼容之前的easyopen接口
*/
public boolean compatibilityModel() {
return true;
}
}

@ -0,0 +1,31 @@
package com.gitee.easyopen.server.api;
import com.gitee.easyopen.annotation.Api;
import com.gitee.easyopen.annotation.ApiService;
import com.gitee.easyopen.doc.annotation.ApiDoc;
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
import com.gitee.easyopen.server.api.param.GoodsParam;
import com.gitee.easyopen.server.api.result.Goods;
import java.math.BigDecimal;
/**
* 业务类
*
* @author tanghc
*/
@ApiService
@ApiDoc("库存接口")
public class Goods2Api {
@Api(name = "store.get")
@ApiDocMethod(description = "获取库存")
Goods getGoods(GoodsParam param) {
Goods goods = new Goods();
goods.setId(1L);
goods.setGoods_name("苹果iPhoneX");
goods.setPrice(new BigDecimal(8000));
return goods;
}
}

@ -15,7 +15,7 @@ import java.math.BigDecimal;
* @author tanghc
*/
@ApiService
@ApiDoc("商品模块")
@ApiDoc("商品接口")
public class GoodsApi {
@Api(name = "goods.get")

@ -0,0 +1,28 @@
package com.gitee.easyopen.server.config;
import com.gitee.easyopen.doc.ApiDocHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;
public abstract class BaseSopDocController {
public abstract String getDocTitle();
@RequestMapping("/v2/api-docs")
@ResponseBody
public Map<String, Object> getDocInfo() {
Map<String, Object> context = this.getContext();
context.put("easyopen", "1.16.3");
context.put("apiModules", ApiDocHolder.getApiDocBuilder().getApiModules());
context.put("title", getDocTitle());
return context;
}
public Map<String, Object> getContext() {
return new HashMap<>(8);
}
}

@ -2,10 +2,19 @@ package com.gitee.easyopen.server.config;
import com.gitee.sop.servercommon.configuration.EasyopenServiceConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
/**
* @author tanghc
*/
@Configuration
public class SopConfig extends EasyopenServiceConfiguration {
@Controller
public static class SopDocController extends BaseSopDocController {
@Override
public String getDocTitle() {
return "商品API";
}
}
}

@ -3,6 +3,7 @@ package com.gitee.sop.bookweb.controller;
import com.gitee.sop.bookweb.controller.param.StoryParam;
import com.gitee.sop.servercommon.annotation.ApiMapping;
import com.gitee.sop.story.api.domain.Story;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
@ -16,6 +17,7 @@ import java.util.Date;
* @author tanghc
*/
@RestController
@Api(tags = "故事接口")
public class AlipayController {
@ApiMapping(value = "alipay.story.get")

@ -3,6 +3,7 @@ package com.gitee.sop.bookweb.controller;
import com.gitee.sop.servercommon.annotation.ApiAbility;
import com.gitee.sop.servercommon.annotation.ApiMapping;
import com.gitee.sop.story.api.domain.Story;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
@ApiAbility // 放在这里,下面所有的接口都具备接口提供能力
@RestController
@RequestMapping("story2")
@Api(tags = "故事接口2")
public class Story2Controller{
@RequestMapping("getStory4")

@ -1,28 +1,20 @@
package com.gitee.sop.gateway.config;
import com.gitee.sop.gateway.entity.IsvInfo;
/**
* 使用Spring Cloud Zuul推荐使用
*
* 注意下面两个只能使用一个
*/
import com.gitee.sop.gateway.manager.ManagerInitializer;
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
import com.gitee.sop.gatewaycommon.bean.ApiContext;
import com.gitee.sop.gatewaycommon.easyopen.EasyopenZuulConfiguration;
import com.gitee.sop.gatewaycommon.manager.IsvRoutePermissionManager;
import com.gitee.sop.gatewaycommon.secret.IsvManager;
import com.gitee.sop.gatewaycommon.zuul.configuration.AlipayZuulConfiguration;
import com.gitee.sop.gatewaycommon.zuul.configuration.TaobaoZuulConfiguration;
import com.gitee.sop.gatewaycommon.zuul.filter.PreLimitFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* 使用Spring Cloud Zuul推荐使用
*
* 注意下面两个只能使用一个
*/
/**
* 开通支付宝开放平台能力
* @author tanghc

@ -7,43 +7,53 @@ layui.use(['element', 'form'], function(){ //加载code模块
function initDocModules() {
$.getJSON(SopConfig.url + '/doc/getDocBaseInfo', function (baseInfo) {
var html = [];
var modules = baseInfo.docModuleVOList;
for (var i = 0; i < modules.length; i++) {
var docDefinition = modules[i];
var module = docDefinition.module;
var docInfoList = baseInfo.docInfoList;
for (var i = 0; i < docInfoList.length; i++) {
var docInfo = docInfoList[i];
var selected = i === 0 ? 'selected="selected"' : '';
html.push('<option value="' + module + '" ' + selected + '>' + module + '</option>');
var title = docInfo.title;
html.push('<option value="' + title + '" ' + selected + '>' + title + '</option>');
}
$('#moduleList').html(html.join(''));
$('.url-prod').text(baseInfo.urlProd);
form.render('select');
if (modules && modules.length > 0) {
selectModule(modules[0].module);
if (docInfoList && docInfoList.length > 0) {
selectDocInfo(docInfoList[0].title);
}
$('.url-prod').text(baseInfo.urlProd);
})
}
function selectModule(docModule) {
$.getJSON(SopConfig.url + '/doc/module/' + docModule, function (module) {
var docItems = module.docItems;
var html = ['<li><h2>' + docModule + '</h2></li>'];
for (var i = 0; i < docItems.length; i++) {
var docItem = docItems[i];
docItemStore[docItem.nameVersion] = docItem;
/*
<li class="site-tree-noicon layui-this">
<a href="/">
<cite>统一收单交易退款查询</cite>
</a>
</li>
*/
var selectedClass = i === 0 ? 'layui-this' : '';
html.push('<li class="site-tree-noicon ' + selectedClass + '">');
html.push('<a href="#" nameversion="'+docItem.nameVersion+'"><cite>'+docItem.summary+'</cite></a>')
function selectDocInfo(title) {
$.getJSON(SopConfig.url + '/doc/docinfo/' + title, function (docInfo) {
var moduleList = docInfo.docModuleList;
var html = [];
var firstItem;
for (var j = 0; j < moduleList.length; j++) {
var module = moduleList[j];
var docItems = module.docItems;
html.push('<li><h2>' + module.module + '</h2></li>');
for (var i = 0; i < docItems.length; i++) {
var docItem = docItems[i];
var first = j == 0 && j == 0;
if (first) {
firstItem = docItem;
}
docItemStore[docItem.nameVersion] = docItem;
/*
<li class="site-tree-noicon layui-this">
<a href="/">
<cite>统一收单交易退款查询</cite>
</a>
</li>
*/
html.push('<li class="site-tree-noicon" nameversion="'+docItem.nameVersion+'">');
html.push('<a href="#"><cite>'+docItem.summary+'</cite></a>')
}
}
$('#docItemTree').html(html.join(''));
if (docItems && docItems.length > 0) {
var firstItem = docItems[0];
if (firstItem) {
selectDocItem(firstItem.nameVersion);
}
})
@ -51,12 +61,11 @@ layui.use(['element', 'form'], function(){ //加载code模块
function initEvent() {
form.on('select(moduleListFilter)', function (data) {
selectModule(data.value);
selectDocInfo(data.value);
})
$('#docItemTree').on('click', 'a', function () {
var $tagA = $(this);
selectDocItem($tagA.attr('nameversion'));
$tagA.parent().addClass('layui-this').siblings().removeClass('layui-this');
$('#docItemTree').on('click', 'li', function () {
var $li = $(this);
selectDocItem($li.attr('nameversion'));
})
}
@ -70,6 +79,9 @@ layui.use(['element', 'form'], function(){ //加载code模块
createRequestParameter(docItem);
createResponseParameter(docItem);
createResponseCode(docItem);
var $li = $('#docItemTree').find('li[nameversion="'+nameVersion+'"]');
$li.addClass('layui-this').siblings().removeClass('layui-this');
}
function createRequestParameter(docItem) {

@ -0,0 +1,14 @@
package com.gitee.sop.websiteserver.bean;
import lombok.Data;
import java.util.List;
/**
* @author tanghc
*/
@Data
public class DocInfo {
private String title;
private List<DocModule> docModuleList;
}

@ -9,6 +9,7 @@ import java.util.List;
*/
@Data
public class DocItem {
private String module;
private String name;
private String version;
private String summary;

@ -1,10 +1,10 @@
package com.gitee.sop.websiteserver.controller;
import com.gitee.sop.websiteserver.bean.DocInfo;
import com.gitee.sop.websiteserver.bean.DocItem;
import com.gitee.sop.websiteserver.bean.DocModule;
import com.gitee.sop.websiteserver.manager.DocManager;
import com.gitee.sop.websiteserver.vo.DocBaseInfoVO;
import com.gitee.sop.websiteserver.vo.DocModuleVO;
import com.gitee.sop.websiteserver.vo.DocInfoVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -38,11 +38,11 @@ public class DocController {
@GetMapping("/getDocBaseInfo")
public DocBaseInfoVO getDocBaseInfo() {
List<DocModuleVO> docModuleVOList = docManager.listAll()
List<DocInfoVO> docInfoList = docManager.listAll()
.stream()
.map(docModule -> {
DocModuleVO vo = new DocModuleVO();
BeanUtils.copyProperties(docModule, vo);
.map(docInfo -> {
DocInfoVO vo = new DocInfoVO();
BeanUtils.copyProperties(docInfo, vo);
return vo;
})
.collect(Collectors.toList());
@ -50,13 +50,13 @@ public class DocController {
DocBaseInfoVO baseInfoVO = new DocBaseInfoVO();
baseInfoVO.setUrlTest(urlTest);
baseInfoVO.setUrlProd(urlProd);
baseInfoVO.setDocModuleVOList(docModuleVOList);
baseInfoVO.setDocInfoList(docInfoList);
return baseInfoVO;
}
@GetMapping("/module/{module}")
public DocModule getDocModule(@PathVariable("module") String module) {
return docManager.getByTitle(module);
@GetMapping("/docinfo/{title}")
public DocInfo getDocModule(@PathVariable("title") String title) {
return docManager.getByTitle(title);
}
@GetMapping("/item/{method}/{version}/")

@ -1,6 +1,6 @@
package com.gitee.sop.websiteserver.manager;
import com.gitee.sop.websiteserver.bean.DocModule;
import com.gitee.sop.websiteserver.bean.DocInfo;
import com.gitee.sop.websiteserver.bean.DocItem;
import java.util.Collection;
@ -14,7 +14,7 @@ public interface DocManager {
DocItem get(String method, String version);
DocModule getByTitle(String title);
DocInfo getByTitle(String title);
Collection<DocModule> listAll();
Collection<DocInfo> listAll();
}

@ -1,11 +1,9 @@
package com.gitee.sop.websiteserver.manager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.websiteserver.bean.DocInfo;
import com.gitee.sop.websiteserver.bean.DocItem;
import com.gitee.sop.websiteserver.bean.DocModule;
import com.gitee.sop.websiteserver.bean.DocParameter;
import com.gitee.sop.websiteserver.bean.EurekaApplication;
import com.gitee.sop.websiteserver.bean.EurekaApps;
import com.gitee.sop.websiteserver.bean.EurekaInstance;
@ -30,9 +28,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -42,8 +37,8 @@ import java.util.stream.Collectors;
@Slf4j
public class DocManagerImpl implements DocManager {
// key:module
Map<String, DocModule> docDefinitionMap = new HashMap<>();
// key:title
Map<String, DocInfo> docDefinitionMap = new HashMap<>();
// key: name+version
Map<String, DocItem> docItemMap = new HashMap<>();
@ -53,6 +48,9 @@ public class DocManagerImpl implements DocManager {
RestTemplate restTemplate = new RestTemplate();
DocParser swaggerDocParser = new SwaggerDocParser();
DocParser easyopenDocParser = new EasyopenDocParser();
@Autowired
private Environment environment;
@ -68,97 +66,46 @@ public class DocManagerImpl implements DocManager {
ServiceInfoVO serviceInfoVo = entry.getValue().get(0);
loadDocInfo(serviceInfoVo);
}
Map<String, DocItem> itemMap = docDefinitionMap.values()
.stream()
.map(DocModule::getDocItems)
.flatMap(docItems -> docItems.stream())
.collect(Collectors.toMap(DocItem::getNameVersion, Function.identity()));
this.docItemMap.putAll(itemMap);
// Map<String, DocItem> itemMap = docDefinitionMap.values()
// .stream()
// .map(DocInfo::getDocModuleList)
// .map(list->{
// for (DocModule docModule : list) {
//
// }
// })
// .map(DocModule::getDocItems)
// .flatMap(docItems -> docItems.stream())
// .collect(Collectors.toMap(DocItem::getNameVersion, Function.identity()));
// this.docItemMap.putAll(itemMap);
} catch (IOException e) {
log.error("加载失败", e);
}
}
private void loadDocInfo(ServiceInfoVO serviceInfoVo) {
protected void loadDocInfo(ServiceInfoVO serviceInfoVo) {
String url = "http://" + serviceInfoVo.getIpAddr() + ":" + serviceInfoVo.getServerPort() + "/v2/api-docs";
try {
ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class);
String docInfoJson = entity.getBody();
DocModule docDefinition = this.parseDocJson(docInfoJson);
docDefinitionMap.put(docDefinition.getModule(), docDefinition);
JSONObject docRoot = JSON.parseObject(docInfoJson);
DocParser docParser = this.buildDocParser(docRoot);
DocInfo docInfo = docParser.parseJson(docRoot);
docDefinitionMap.put(docInfo.getTitle(), docInfo);
} catch (RestClientException e) {
// 这里报错可能是因为有些微服务没有配置swagger文档,导致404访问不到
// 这里catch跳过即可
log.warn("读取文档失败, url:{}", url, e);
}
}
private DocModule parseDocJson(String docInfoJson) {
JSONObject docRoot = JSON.parseObject(docInfoJson);
String title = docRoot.getJSONObject("info").getString("title");
List<DocItem> docItems = new ArrayList<>();
JSONObject paths = docRoot.getJSONObject("paths");
Set<String> pathNameSet = paths.keySet();
for (String pathName : pathNameSet) {
JSONObject pathInfo = paths.getJSONObject(pathName);
Set<String> pathSet = pathInfo.keySet();
Optional<String> first = pathSet.stream().findFirst();
if (first.isPresent()) {
String path = first.get();
JSONObject docInfo = pathInfo.getJSONObject(path);
DocItem docItem = buildDocItem(docInfo, docRoot);
docItems.add(docItem);
}
log.warn("读取文档失败, url:{}, msg:{}", url, e.getMessage());
}
DocModule docDefinition = new DocModule();
docDefinition.setModule(title);
docDefinition.setDocItems(docItems);
return docDefinition;
}
private DocItem buildDocItem(JSONObject docInfo, JSONObject docRoot) {
DocItem docItem = new DocItem();
docItem.setName(docInfo.getString("sop_name"));
docItem.setVersion(docInfo.getString("sop_version"));
docItem.setSummary(docInfo.getString("summary"));
docItem.setDescription(docInfo.getString("description"));
Optional<JSONArray> parametersOptional = Optional.ofNullable(docInfo.getJSONArray("parameters"));
JSONArray parameters = parametersOptional.orElse(new JSONArray());
List<DocParameter> docParameterList = parameters.toJavaList(DocParameter.class);
docItem.setRequestParameters(docParameterList);
List<DocParameter> responseParameterList = this.buildResponseParameterList(docInfo, docRoot);
docItem.setResponseParameters(responseParameterList);
return docItem;
}
private List<DocParameter> buildResponseParameterList(JSONObject docInfo, JSONObject docRoot) {
String responseRef = getResponseRef(docInfo);
List<DocParameter> respParameterList = new ArrayList<>();
if (StringUtils.isNotBlank(responseRef)) {
JSONObject responseObject = docRoot.getJSONObject("definitions").getJSONObject(responseRef);
JSONObject properties = responseObject.getJSONObject("properties");
Set<String> fieldNames = properties.keySet();
for (String fieldName : fieldNames) {
JSONObject fieldInfo = properties.getJSONObject(fieldName);
DocParameter respParam = fieldInfo.toJavaObject(DocParameter.class);
respParam.setName(fieldName);
respParameterList.add(respParam);
}
protected DocParser buildDocParser(JSONObject rootDoc) {
Object easyopen = rootDoc.get("easyopen");
if (easyopen != null) {
return easyopenDocParser;
} else {
return swaggerDocParser;
}
return respParameterList;
}
private String getResponseRef(JSONObject docInfo) {
String ref = Optional.ofNullable(docInfo.getJSONObject("responses"))
.flatMap(jsonObject -> Optional.of(jsonObject.getJSONObject("200")))
.flatMap(jsonObject -> Optional.of(jsonObject.getJSONObject("schema")))
.flatMap(jsonObject -> Optional.of(jsonObject.getString("originalRef")))
.orElse("");
return ref;
}
@Override
@ -167,12 +114,12 @@ public class DocManagerImpl implements DocManager {
}
@Override
public DocModule getByTitle(String title) {
public DocInfo getByTitle(String title) {
return docDefinitionMap.get(title);
}
@Override
public Collection<DocModule> listAll() {
public Collection<DocInfo> listAll() {
return docDefinitionMap.values();
}
@ -200,7 +147,7 @@ public class DocManagerImpl implements DocManager {
return listMap;
}
private String requestEurekaServer(EurekaUri eurekaUri, String... args) throws IOException {
protected String requestEurekaServer(EurekaUri eurekaUri, String... args) throws IOException {
Request request = eurekaUri.getRequest(this.eurekaUrl, args);
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {

@ -0,0 +1,11 @@
package com.gitee.sop.websiteserver.manager;
import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.websiteserver.bean.DocInfo;
/**
* @author tanghc
*/
public interface DocParser {
DocInfo parseJson(JSONObject docRoot);
}

@ -0,0 +1,83 @@
package com.gitee.sop.websiteserver.manager;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.websiteserver.bean.DocInfo;
import com.gitee.sop.websiteserver.bean.DocItem;
import com.gitee.sop.websiteserver.bean.DocModule;
import com.gitee.sop.websiteserver.bean.DocParameter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author tanghc
*/
public class EasyopenDocParser implements DocParser {
@Override
public DocInfo parseJson(JSONObject docRoot) {
String title = docRoot.getString("title");
List<DocItem> docItems = new ArrayList<>();
JSONArray apiModules = docRoot.getJSONArray("apiModules");
for (int i = 0; i < apiModules.size(); i++) {
JSONObject module = apiModules.getJSONObject(i);
JSONArray moduleItems = module.getJSONArray("moduleItems");
for (int k = 0; k < moduleItems.size(); k++) {
JSONObject docInfo = moduleItems.getJSONObject(k);
DocItem docItem = buildDocItem(docInfo);
docItem.setModule(module.getString("name"));
docItems.add(docItem);
}
}
List<DocModule> docModuleList = docItems.stream()
.collect(Collectors.groupingBy(DocItem::getModule))
.entrySet()
.stream()
.map(entry -> {
DocModule docModule = new DocModule();
docModule.setModule(entry.getKey());
docModule.setDocItems(entry.getValue());
return docModule;
})
.collect(Collectors.toList());
DocInfo docInfo = new DocInfo();
docInfo.setTitle(title);
docInfo.setDocModuleList(docModuleList);
return docInfo;
}
protected DocItem buildDocItem(JSONObject docInfo) {
DocItem docItem = new DocItem();
docItem.setName(docInfo.getString("name"));
docItem.setVersion(docInfo.getString("version"));
docItem.setSummary(docInfo.getString("description"));
docItem.setDescription(docInfo.getString("description"));
List<DocParameter> docParameterList = this.buildParameterList(docInfo, "paramDefinitions");
docItem.setRequestParameters(docParameterList);
List<DocParameter> responseParameterList = this.buildParameterList(docInfo, "resultDefinitions");
docItem.setResponseParameters(responseParameterList);
return docItem;
}
protected List<DocParameter> buildParameterList(JSONObject docInfo, String key) {
JSONArray params = docInfo.getJSONArray(key);
if (params == null) {
return Collections.emptyList();
}
List<DocParameter> docParameterList = new ArrayList<>();
for (int i = 0; i < params.size(); i++) {
JSONObject jsonObject = params.getJSONObject(i);
DocParameter docParameter = jsonObject.toJavaObject(DocParameter.class);
docParameter.setType(jsonObject.getString("dataType"));
docParameterList.add(docParameter);
}
return docParameterList;
}
}

@ -0,0 +1,112 @@
package com.gitee.sop.websiteserver.manager;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.websiteserver.bean.DocInfo;
import com.gitee.sop.websiteserver.bean.DocItem;
import com.gitee.sop.websiteserver.bean.DocModule;
import com.gitee.sop.websiteserver.bean.DocParameter;
import org.apache.commons.lang.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author tanghc
*/
public class SwaggerDocParser implements DocParser {
@Override
public DocInfo parseJson(JSONObject docRoot) {
String title = docRoot.getJSONObject("info").getString("title");
List<DocItem> docItems = new ArrayList<>();
JSONObject paths = docRoot.getJSONObject("paths");
Set<String> pathNameSet = paths.keySet();
for (String pathName : pathNameSet) {
JSONObject pathInfo = paths.getJSONObject(pathName);
Set<String> pathSet = pathInfo.keySet();
Optional<String> first = pathSet.stream().findFirst();
if (first.isPresent()) {
String path = first.get();
JSONObject docInfo = pathInfo.getJSONObject(path);
DocItem docItem = buildDocItem(docInfo, docRoot);
docItems.add(docItem);
}
}
List<DocModule> docModuleList = docItems.stream()
.collect(Collectors.groupingBy(DocItem::getModule))
.entrySet()
.stream()
.map(entry -> {
DocModule docModule = new DocModule();
docModule.setModule(entry.getKey());
docModule.setDocItems(entry.getValue());
return docModule;
})
.collect(Collectors.toList());
DocInfo docInfo = new DocInfo();
docInfo.setTitle(title);
docInfo.setDocModuleList(docModuleList);
return docInfo;
}
protected DocItem buildDocItem(JSONObject docInfo, JSONObject docRoot) {
DocItem docItem = new DocItem();
docItem.setName(docInfo.getString("sop_name"));
docItem.setVersion(docInfo.getString("sop_version"));
docItem.setSummary(docInfo.getString("summary"));
docItem.setDescription(docInfo.getString("description"));
String moduleName = this.buildModuleName(docInfo, docRoot);
docItem.setModule(moduleName);
Optional<JSONArray> parametersOptional = Optional.ofNullable(docInfo.getJSONArray("parameters"));
JSONArray parameters = parametersOptional.orElse(new JSONArray());
List<DocParameter> docParameterList = parameters.toJavaList(DocParameter.class);
docItem.setRequestParameters(docParameterList);
List<DocParameter> responseParameterList = this.buildResponseParameterList(docInfo, docRoot);
docItem.setResponseParameters(responseParameterList);
return docItem;
}
protected String buildModuleName(JSONObject docInfo, JSONObject docRoot) {
String title = docRoot.getJSONObject("info").getString("title");
JSONArray tags = docInfo.getJSONArray("tags");
if (tags != null && tags.size() > 0) {
return tags.getString(0);
}
return title;
}
protected List<DocParameter> buildResponseParameterList(JSONObject docInfo, JSONObject docRoot) {
String responseRef = getResponseRef(docInfo);
List<DocParameter> respParameterList = new ArrayList<>();
if (StringUtils.isNotBlank(responseRef)) {
JSONObject responseObject = docRoot.getJSONObject("definitions").getJSONObject(responseRef);
JSONObject properties = responseObject.getJSONObject("properties");
Set<String> fieldNames = properties.keySet();
for (String fieldName : fieldNames) {
JSONObject fieldInfo = properties.getJSONObject(fieldName);
DocParameter respParam = fieldInfo.toJavaObject(DocParameter.class);
respParam.setName(fieldName);
respParameterList.add(respParam);
}
}
return respParameterList;
}
protected String getResponseRef(JSONObject docInfo) {
String ref = Optional.ofNullable(docInfo.getJSONObject("responses"))
.flatMap(jsonObject -> Optional.of(jsonObject.getJSONObject("200")))
.flatMap(jsonObject -> Optional.of(jsonObject.getJSONObject("schema")))
.flatMap(jsonObject -> Optional.of(jsonObject.getString("originalRef")))
.orElse("");
return ref;
}
}

@ -11,5 +11,5 @@ import java.util.List;
public class DocBaseInfoVO {
private String urlTest;
private String urlProd;
private List<DocModuleVO> docModuleVOList;
private List<DocInfoVO> docInfoList;
}

@ -6,6 +6,6 @@ import lombok.Data;
* @author tanghc
*/
@Data
public class DocModuleVO {
private String module;
public class DocInfoVO {
private String title;
}
Loading…
Cancel
Save