From f020356a815bbaa5fa8867a9a906bbb83c0834a4 Mon Sep 17 00:00:00 2001 From: wanggeng <450292408@qq.com> Date: Sun, 15 Aug 2021 16:02:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=8E=A5=E5=8F=A3=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E6=A8=A1=E6=9D=BF=E4=B8=8E=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/ApiDocServiceImpl.java | 230 ++++++++++++++++-- .../resources/templates/ftl/api-template.ftl | 221 ++++++++--------- 2 files changed, 322 insertions(+), 129 deletions(-) diff --git a/cloud-common/src/main/java/com/cm/common/service/impl/ApiDocServiceImpl.java b/cloud-common/src/main/java/com/cm/common/service/impl/ApiDocServiceImpl.java index 20b24f4..6b08ae0 100644 --- a/cloud-common/src/main/java/com/cm/common/service/impl/ApiDocServiceImpl.java +++ b/cloud-common/src/main/java/com/cm/common/service/impl/ApiDocServiceImpl.java @@ -1,6 +1,8 @@ package com.cm.common.service.impl; +import com.alibaba.fastjson.JSONObject; import com.cm.common.base.AbstractService; +import com.cm.common.config.properties.SystemProperties; import com.cm.common.constants.ISystemConstant; import com.cm.common.service.IApiDocService; import com.cm.common.utils.DateUtil; @@ -53,6 +55,8 @@ public class ApiDocServiceImpl extends AbstractService implements IApiDocService private ServiceModelToSwagger2Mapper serviceModelToSwagger2Mapper; @Autowired private FreeMarkerConfigurer freeMarkerConfigurer; + @Autowired + private SystemProperties systemProperties; @PostConstruct public void init() { @@ -84,9 +88,9 @@ public class ApiDocServiceImpl extends AbstractService implements IApiDocService apiGroups.add(systemDocMap); } } - + apiDocMap.put("title", systemProperties.getTitle()); apiDocMap.put("apiGroups", apiGroups); - apiDocMap.put("author", "System"); + apiDocMap.put("author", "XXXXXX"); apiDocMap.put("date", DateUtil.getDay()); apiDocMap.put("version", "v1.0"); return apiDocMap; @@ -124,15 +128,22 @@ public class ApiDocServiceImpl extends AbstractService implements IApiDocService apiMap.put("definitions", definitions); for (Tag tag : tags) { Map apiController = new HashMap<>(); - apiController.put("name", tag.getName()); + apiController.put("name", tag.getName().indexOf("\\-") > 0 ? tag.getName().split("\\-")[1] : tag.getName()); apiController.put("description", tag.getDescription()); - apiController.put("apis", listApiMap(tag.getName(), paths)); + apiController.put("apis", listApiMap(tag.getName(), paths, definitions)); apiControllers.add(apiController); } return apiMap; } - private List> listApiMap(String apiController, Map paths) { + /** + * api列表 + * + * @param apiController + * @param paths + * @return + */ + private List> listApiMap(String apiController, Map paths, Map definitions) { List> pathMaps = new ArrayList<>(); for (Map.Entry kv : paths.entrySet()) { String apiUrl = kv.getKey(); @@ -150,8 +161,20 @@ public class ApiDocServiceImpl extends AbstractService implements IApiDocService methodOperationMap.put("description", operation.getDescription() == null ? "无" : operation.getDescription()); methodOperationMap.put("consumes", operation.getConsumes()); methodOperationMap.put("produces", operation.getProduces()); - methodOperationMap.put("parameters", listRequestParameter(operation)); - methodOperationMap.put("responses", listResponseMap(operation)); + // 请求参数 + List> parameters = listRequestParameter(operation); + methodOperationMap.put("parameters", parameters); + methodOperationMap.put("parameterRefs", listRef(parameters, definitions)); + // 请求示例 + List> parameterExamples = listExample(parameters, definitions); + methodOperationMap.put("parameterExamples", parameterExamples); + // 响应参数 + List> responses = listResponseMap(operation); + methodOperationMap.put("responses", responses); + methodOperationMap.put("responseRefs", listRef(responses, definitions)); + // 响应示例 + List> responseExamples = listExample(responses, definitions); + methodOperationMap.put("responseExamples", responseExamples); pathMaps.add(methodOperationMap); } } @@ -159,6 +182,12 @@ public class ApiDocServiceImpl extends AbstractService implements IApiDocService return pathMaps; } + /** + * 请求参数 + * + * @param operation + * @return + */ private List> listRequestParameter(Operation operation) { List> requestParameterList = new ArrayList<>(); List parameters = operation.getParameters(); @@ -175,23 +204,31 @@ public class ApiDocServiceImpl extends AbstractService implements IApiDocService requestParameter.put("type", type); requestParameter.put("source", parameter); requestParameter.put("access", parameter.getAccess()); + String ref = "无"; + String simpleRef = "无"; if (parameter instanceof BodyParameter) { BodyParameter bodyParameter = (BodyParameter) parameter; Model schema = bodyParameter.getSchema(); requestParameter.put("schemaClass", schema.getClass()); if (schema instanceof RefModel) { RefModel refModel = (RefModel) schema; - requestParameter.put("ref", refModel.get$ref()); - requestParameter.put("simpleRef", refModel.getSimpleRef()); + ref = refModel.get$ref(); + simpleRef = refModel.getSimpleRef(); } } + requestParameter.put("ref", ref); + requestParameter.put("simpleRef", simpleRef); requestParameterList.add(requestParameter); - - } return requestParameterList; } + /** + * 响应结果 + * + * @param operation + * @return + */ private List> listResponseMap(Operation operation) { Map responses = operation.getResponses(); List> responseMaps = new ArrayList<>(); @@ -202,26 +239,187 @@ public class ApiDocServiceImpl extends AbstractService implements IApiDocService responseMap.put("code", code); responseMap.put("description", response.getDescription()); Property schema = response.getSchema(); + String ref = "无"; + String simpleRef = "无"; + String type = "无"; if (schema != null) { responseMap.put("schemaClass", schema.getClass()); - responseMap.put("type", schema.getType()); + type = schema.getType(); if (schema instanceof ArrayProperty) { ArrayProperty arrayProperty = (ArrayProperty) schema; Property items = arrayProperty.getItems(); if (items instanceof RefProperty) { RefProperty refProperty = (RefProperty) items; - responseMap.put("ref", refProperty.get$ref()); - responseMap.put("simpleRef", refProperty.getSimpleRef()); + ref = refProperty.get$ref(); + simpleRef = refProperty.getSimpleRef(); } } else if (schema instanceof RefProperty) { RefProperty refProperty = (RefProperty) schema; - responseMap.put("ref", refProperty.get$ref()); - responseMap.put("simpleRef", refProperty.getSimpleRef()); + ref = refProperty.get$ref(); + simpleRef = refProperty.getSimpleRef(); } } + responseMap.put("ref", ref); + responseMap.put("simpleRef", simpleRef); + responseMap.put("type", StringUtils.equals(type, "ref") ? "object" : type); responseMaps.add(responseMap); } return responseMaps; } + /** + * 引用对象列表 + * + * @param listParameter + * @param definitions + * @return + */ + private List> listRef(List> listParameter, Map definitions) { + List> refs = new ArrayList<>(); + for (Map parameter : listParameter) { + if (StringUtils.equals(parameter.get("ref").toString(), "无")) { + continue; + } + String simpleRef = parameter.get("simpleRef").toString(); + setRef(refs, simpleRef, definitions); + } + return refs; + } + + /** + * 设置引用 + * + * @param refs + * @param simpleRef + * @param definitions + */ + private void setRef(List> refs, String simpleRef, Map definitions) { + for (Map.Entry definitionKV : definitions.entrySet()) { + if (StringUtils.equals(definitionKV.getKey(), simpleRef)) { + Model model = definitionKV.getValue(); + if (model instanceof ModelImpl) { + ModelImpl modelImpl = (ModelImpl) model; + Map modelProperties = model.getProperties(); + if (modelProperties == null) { + return; + } + + Map requestParameterRef = new HashMap<>(); + // 这里提前添加为了保证递归时的顺序 + refs.add(requestParameterRef); + requestParameterRef.put("class", model.getClass()); + requestParameterRef.put("name", definitionKV.getKey()); + requestParameterRef.put("type", modelImpl.getType()); + requestParameterRef.put("modelProperties", modelProperties); + List> modelPropertiesList = new ArrayList<>(); + // 这里提前添加为了保证递归时的顺序 + requestParameterRef.put("modelPropertiesList", modelPropertiesList); + for (Map.Entry modelPropertiesKV : modelProperties.entrySet()) { + Property modelPropertiesValue = modelPropertiesKV.getValue(); + Map modelPropertiesMap = new HashMap<>(); + modelPropertiesMap.put("name", modelPropertiesKV.getKey()); + modelPropertiesMap.put("description", StringUtils.isBlank(modelPropertiesValue.getDescription()) ? "无" : modelPropertiesValue.getDescription()); + modelPropertiesMap.put("type", modelPropertiesValue.getType()); + modelPropertiesMap.put("example", modelPropertiesValue.getExample() == null ? "无" : modelPropertiesValue); + modelPropertiesMap.put("class", modelPropertiesValue.getClass()); + modelPropertiesList.add(modelPropertiesMap); + // 递归完成引用类的构建 + RefProperty subRefProperty = getRefProperty(modelPropertiesValue); + String subSimpleRef = "无"; + if (subRefProperty != null) { + subSimpleRef = subRefProperty.getSimpleRef(); + // 相同引用不递归处理 + if (!StringUtils.equals(simpleRef, subSimpleRef)) { + setRef(refs, subSimpleRef, definitions); + } + } + modelPropertiesMap.put("simpleRef", subSimpleRef); + } + } + return; + } + } + } + + /** + * 获取对象示例 + * + * @param listParameter + * @param definitions + * @return + */ + private List> listExample(List> listParameter, Map definitions) { + List> exampleList = new ArrayList<>(); + for (Map parameter : listParameter) { + if (StringUtils.equals(parameter.get("ref").toString(), "无")) { + continue; + } + String simpleRef = parameter.get("simpleRef").toString(); + Map exampleMap = new HashMap<>(); + exampleMap.put("simpleRef", simpleRef); + // 得到对象示例 + Map example = new HashMap<>(); + setExample(example, simpleRef, definitions); + // 带格式的JSON输出 + exampleMap.put("example", JSONObject.toJSONString(example)); + exampleList.add(exampleMap); + } + return exampleList; + } + + private void setExample(Map exampleMap, String simpleRef, Map definitions) { + for (Map.Entry definitionKV : definitions.entrySet()) { + if (StringUtils.equals(definitionKV.getKey(), simpleRef)) { + Model model = definitionKV.getValue(); + if (model instanceof ModelImpl) { + Map modelProperties = model.getProperties(); + if (modelProperties == null) { + return; + } + for (Map.Entry modelPropertiesKV : modelProperties.entrySet()) { + Property modelPropertiesValue = modelPropertiesKV.getValue(); + exampleMap.put(modelPropertiesKV.getKey(), ""); + // 递归完成引用类的构建 + RefProperty subRefProperty = getRefProperty(modelPropertiesValue); + if (subRefProperty != null) { + String subSimpleRef = subRefProperty.getSimpleRef(); + // 相同引用不递归处理 + if (!StringUtils.equals(simpleRef, subSimpleRef)) { + Map subExampleMap = new HashMap<>(); + if (StringUtils.equals(modelPropertiesValue.getType(), "array")) { + List> subExampleList = new ArrayList<>(); + subExampleList.add(subExampleMap); + exampleMap.put(modelPropertiesKV.getKey(), subExampleList); + } else { + exampleMap.put(modelPropertiesKV.getKey(), subExampleMap); + } + setExample(subExampleMap, subSimpleRef, definitions); + } + } + } + } + return; + } + } + } + + /** + * 获取引用属性 + * + * @param modelPropertiesValue + * @return + */ + private RefProperty getRefProperty(Property modelPropertiesValue) { + RefProperty subRefProperty = null; + if (modelPropertiesValue instanceof ArrayProperty) { + ArrayProperty arrayProperty = (ArrayProperty) modelPropertiesValue; + Property items = arrayProperty.getItems(); + if (items instanceof RefProperty) { + subRefProperty = (RefProperty) items; + } + } else if (modelPropertiesValue instanceof RefProperty) { + subRefProperty = (RefProperty) modelPropertiesValue; + } + return subRefProperty; + } } diff --git a/cloud-common/src/main/resources/templates/ftl/api-template.ftl b/cloud-common/src/main/resources/templates/ftl/api-template.ftl index 204a870..8f742c2 100644 --- a/cloud-common/src/main/resources/templates/ftl/api-template.ftl +++ b/cloud-common/src/main/resources/templates/ftl/api-template.ftl @@ -94,17 +94,7 @@ - X - - - - - - - - - - XXX + ${title} @@ -385,7 +375,7 @@ - 功能说明 + ${api.summary} @@ -409,7 +399,7 @@ - 描述:${api.summary} + 功能描述 @@ -748,6 +738,7 @@ + <#list api.parameterRefs as parameterRef> @@ -756,26 +747,12 @@ - - - - - - X - - XX - - - - - - - 对象属性 + ${parameterRef.name}对象属性 @@ -819,7 +796,7 @@ - 名称 + 属性名 @@ -906,11 +883,12 @@ - 示例 + 构造对象 + <#list parameterRef.modelPropertiesList as modelProperties> @@ -930,6 +908,14 @@ + + + + + + + ${modelProperties.name} + @@ -947,6 +933,14 @@ + + + + + + + ${modelProperties.description} + @@ -964,6 +958,14 @@ + + + + + + + ${modelProperties.type} + @@ -981,10 +983,21 @@ + + + + + + + ${modelProperties.simpleRef} + + + + <#list api.parameterExamples as parameterExample> @@ -1004,14 +1017,7 @@ - 请求 - - - - - - - 示例 + ${parameterExample.simpleRef} 示例 @@ -1043,10 +1049,19 @@ + + + + + + + ${parameterExample.example} + + @@ -1137,7 +1152,7 @@ - 原因 + 说明 @@ -1165,7 +1180,7 @@ - 名称 + 返回值 @@ -1193,7 +1208,7 @@ - 响应类型` + 返回类型` @@ -1271,7 +1286,7 @@ - xxx + ${response.simpleRef} @@ -1295,13 +1310,14 @@ - object + ${response.type} + <#list api.responseRefs as responseRef> @@ -1315,21 +1331,7 @@ - X - - - - - - - XXX - - - - - - - 属性 + ${responseRef.name}对象属性 @@ -1428,7 +1430,7 @@ - 类型 + 参数类型 @@ -1456,11 +1458,13 @@ - 示例 + 数据类型 + <#if (responseRef.modelPropertiesList)??> + <#list responseRef.modelPropertiesList as modelProperties> @@ -1479,6 +1483,14 @@ + + + + + + + ${modelProperties.name} + @@ -1495,6 +1507,14 @@ + + + + + + + ${modelProperties.description} + @@ -1511,6 +1531,14 @@ + + + + + + + ${modelProperties.type} + @@ -1527,10 +1555,22 @@ + + + + + + + ${modelProperties.simpleRef} + + + + + <#list api.responseExamples as responseExample> @@ -1550,7 +1590,7 @@ - 请求失败示例 + ${responseExample.simpleRef}示例 @@ -1581,64 +1621,19 @@ - - - - - - - - - - - - - - - - - - - - - - - - 请求成功示例 - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + + - + ${responseExample.example} + +