You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/01/30 11:28:28 UTC

[dubbo-spi-extensions] 16/39: 调整UI,增加接口参数展示,缓存结构由Map改为JavaBean,修正某些名称单次拼写错误

This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 2.7.x
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git

commit 12500ac17b39f304b33e73be5adf87d508ec0b42
Author: qq213539 <21...@qq.com>
AuthorDate: Fri Nov 20 17:28:51 2020 +0800

    调整UI,增加接口参数展示,缓存结构由Map改为JavaBean,修正某些名称单次拼写错误
---
 .../core/DubboApiDocsAnnotationScanner.java        | 131 +++++++++++----------
 .../dubbo/apidocs/core/DubboApiDocsCache.java      |  31 ++---
 .../dubbo/apidocs/core/beans/ApiCacheItem.java     |  39 ++++++
 .../apidocs/core/beans/ApiParamsCacheItem.java     |  40 +++++++
 .../dubbo/apidocs/core/beans/ModuleCacheItem.java  |  26 ++++
 .../apache/dubbo/apidocs/core/beans/ParamBean.java |   2 +-
 .../core/providers/DubboDocProviderImpl.java       |   4 +-
 .../apidocs/core/providers/IDubboDocProvider.java  |   5 +-
 .../dubbo/apidocs/examples/api/ISyncDemo.java      |  10 +-
 .../apidocs/examples/api/impl/SyncDemoImpl.java    |   4 +-
 .../apidocs/controller/DubboApiDocsController.java |  70 +++++------
 ... => CallDubboServiceRequestInterfaceParam.java} |   6 +-
 .../dubbo/apidocs/utils/DubboGenericUtil.java      |  22 ++--
 .../src/main/resources/static/js/index.js          |   2 +-
 .../src/layouts/BasicLayout/index.tsx              |   6 +-
 .../dubbo-api-docs-ui/src/locales/en-US.json       |  11 +-
 .../dubbo-api-docs-ui/src/locales/zh-CN.json       |  11 +-
 .../dubbo-api-docs-ui/src/pages/ApiForm/index.tsx  | 103 ++++++++--------
 18 files changed, 318 insertions(+), 205 deletions(-)

diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index a089805..94c2e88 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -16,6 +16,9 @@
  */
 package org.apache.dubbo.apidocs.core;
 
+import org.apache.dubbo.apidocs.core.beans.ApiCacheItem;
+import org.apache.dubbo.apidocs.core.beans.ApiParamsCacheItem;
+import org.apache.dubbo.apidocs.core.beans.ModuleCacheItem;
 import org.apache.dubbo.apidocs.core.beans.HtmlTypeEnum;
 import org.apache.dubbo.apidocs.core.beans.ParamBean;
 import org.apache.dubbo.apidocs.core.providers.DubboDocProviderImpl;
@@ -44,7 +47,6 @@ import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -101,19 +103,19 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 DubboService dubboService = apiModuleClass.getAnnotation(DubboService.class);
                 async = dubboService.async();
             }
-            Map<String, Object> moduleCacheItem = new HashMap<>(4);
+            ModuleCacheItem moduleCacheItem = new ModuleCacheItem();
             DubboApiDocsCache.addApiModule(moduleAnn.apiInterface().getCanonicalName(), moduleCacheItem);
             //module name
-            moduleCacheItem.put("moduleChName", moduleAnn.value());
+            moduleCacheItem.setModuleDocName(moduleAnn.value());
             //interface name containing package path
-            moduleCacheItem.put("moduleClassName", moduleAnn.apiInterface().getCanonicalName());
+            moduleCacheItem.setModuleClassName(moduleAnn.apiInterface().getCanonicalName());
             //module version
-            moduleCacheItem.put("moduleVersion", moduleAnn.version());
+            moduleCacheItem.setModuleVersion(moduleAnn.version());
 
             Method[] apiModuleMethods = apiModuleClass.getMethods();
             // API basic information list in module cache
-            List<Map<String, Object>> moduleApiList = new ArrayList<>(apiModuleMethods.length);
-            moduleCacheItem.put("moduleApiList", moduleApiList);
+            List<ApiCacheItem> moduleApiList = new ArrayList<>(apiModuleMethods.length);
+            moduleCacheItem.setModuleApiList(moduleApiList);
             for (Method method : apiModuleMethods) {
                 if (method.isAnnotationPresent(ApiDoc.class)) {
                     processApiDocAnnotation(method, moduleApiList, moduleAnn, async, moduleCacheItem);
@@ -123,48 +125,53 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
         log.info("================= Dubbo API Docs-- doc annotations scanning and processing completed ================");
     }
 
-    private void processApiDocAnnotation(Method method, List<Map<String, Object>> moduleApiList, ApiModule moduleAnn,
-                                         boolean async, Map<String, Object> moduleCacheItem) {
+    private void processApiDocAnnotation(Method method, List<ApiCacheItem> moduleApiList, ApiModule moduleAnn,
+                                         boolean async, ModuleCacheItem moduleCacheItem) {
         ApiDoc dubboApi = method.getAnnotation(ApiDoc.class);
 
         // API basic information in API list in module
-        Map<String, Object> apiListItem = new HashMap<>(4);
+        ApiCacheItem apiListItem = new ApiCacheItem();
         moduleApiList.add(apiListItem);
         //API method name
-        apiListItem.put("apiName", method.getName());
+        apiListItem.setApiName(method.getName());
         //API name
-        apiListItem.put("apiChName", dubboApi.value());
+        apiListItem.setApiDocName(dubboApi.value());
         // API description
-        apiListItem.put("description", dubboApi.description());
+        apiListItem.setDescription(dubboApi.description());
         //API version
-        apiListItem.put("apiVersion", dubboApi.version());
+        apiListItem.setApiVersion(dubboApi.version());
         //Description of API return data
-        apiListItem.put("apiRespDec", dubboApi.responseClassDescription());
+        apiListItem.setApiRespDec(dubboApi.responseClassDescription());
 
         // Interface parameters and response information
-        Map<String, Object> apiParamsAndResp = new HashMap<>(2);
+        ApiCacheItem apiParamsAndResp = new ApiCacheItem();
         DubboApiDocsCache.addApiParamsAndResp(
                 moduleAnn.apiInterface().getCanonicalName() + "." + method.getName(), apiParamsAndResp);
 
         Class<?>[] argsClass = method.getParameterTypes();
         Annotation[][] argsAnns = method.getParameterAnnotations();
         Parameter[] parameters = method.getParameters();
-        List<Map<String, Object>> paramList = new ArrayList<>(argsClass.length);
-        apiParamsAndResp.put("async", async);
-        apiParamsAndResp.put("apiName", method.getName());
-        apiParamsAndResp.put("apiChName", dubboApi.value());
-        apiParamsAndResp.put("apiVersion", dubboApi.version());
-        apiParamsAndResp.put("apiRespDec", dubboApi.responseClassDescription());
-        apiParamsAndResp.put("apiModelClass", moduleCacheItem.get("moduleClassName"));
-        apiParamsAndResp.put("params", paramList);
-        apiParamsAndResp.put("response", ClassTypeUtil.calss2Json(method.getGenericReturnType(), method.getReturnType()));
+        List<ApiParamsCacheItem> paramList = new ArrayList<>(argsClass.length);
+        apiParamsAndResp.setAsync(async);
+        apiParamsAndResp.setApiName(method.getName());
+        apiParamsAndResp.setApiDocName(dubboApi.value());
+        apiParamsAndResp.setApiVersion(dubboApi.version());
+        apiParamsAndResp.setApiRespDec(dubboApi.responseClassDescription());
+        apiParamsAndResp.setApiModelClass(moduleCacheItem.getModuleClassName());
+        apiParamsAndResp.setParams(paramList);
+        apiParamsAndResp.setResponse(ClassTypeUtil.calss2Json(method.getGenericReturnType(), method.getReturnType()));
+        StringBuilder methodParamInfoSb = new StringBuilder();
         for (int i = 0; i < argsClass.length; i++) {
             Class<?> argClass = argsClass[i];
+            methodParamInfoSb.append("[").append(i).append("]").append(argClass.getCanonicalName());
+            if (i + 1 < argsClass.length) {
+                methodParamInfoSb.append(" | ");
+            }
             Annotation[] argAnns = argsAnns[i];
-            Map<String, Object> prarmListItem = new HashMap<>(2);
-            paramList.add(prarmListItem);
-            prarmListItem.put("prarmType", argClass.getCanonicalName());
-            prarmListItem.put("prarmIndex", i);
+            ApiParamsCacheItem paramListItem = new ApiParamsCacheItem();
+            paramList.add(paramListItem);
+            paramListItem.setParamType(argClass.getCanonicalName());
+            paramListItem.setParamIndex(i);
             RequestParam requestParam = null;
             // Handling @RequestParam annotations on parameters
             for (Annotation ann : argAnns) {
@@ -177,27 +184,27 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 // Not a basic type, handling properties in method parameters
                 List<ParamBean> apiParamsList = processField(argClass);
                 if (apiParamsList != null && !apiParamsList.isEmpty()) {
-                    prarmListItem.put("prarmInfo", apiParamsList);
+                    paramListItem.setParamInfo(apiParamsList);
                 }
             } else {
                 // Is the basic type
                 Parameter methodParameter = parameters[i];
-                prarmListItem.put("name", methodParameter.getName());
-                prarmListItem.put("htmlType", paramBean.getHtmlType().name());
-                prarmListItem.put("allowableValues", paramBean.getAllowableValues());
+                paramListItem.setName(methodParameter.getName());
+                paramListItem.setHtmlType(paramBean.getHtmlType().name());
+                paramListItem.setAllowableValues(paramBean.getAllowableValues());
                 if (requestParam != null) {
-
                     // Handling requestparam annotations on parameters
-                    prarmListItem.put("nameCh", requestParam.value());
-                    prarmListItem.put("description", requestParam.description());
-                    prarmListItem.put("example", requestParam.example());
-                    prarmListItem.put("defaultValue", requestParam.defaultValue());
-                    prarmListItem.put("required", requestParam.required());
+                    paramListItem.setDocName(requestParam.value());
+                    paramListItem.setDescription(requestParam.description());
+                    paramListItem.setExample(requestParam.example());
+                    paramListItem.setDefaultValue(requestParam.defaultValue());
+                    paramListItem.setRequired(requestParam.required());
                 } else {
-                    prarmListItem.put("required", false);
+                    paramListItem.setRequired(false);
                 }
             }
         }
+        apiParamsAndResp.setMethodParamInfo(methodParamInfoSb.toString());
     }
 
     /**
@@ -217,7 +224,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             if (field.isAnnotationPresent(RequestParam.class)) {
                 // Handling @RequestParam annotations on properties
                 requestParam = field.getAnnotation(RequestParam.class);
-                paramBean.setNameCh(requestParam.value());
+                paramBean.setDocName(requestParam.value());
                 paramBean.setRequired(requestParam.required());
                 paramBean.setDescription(requestParam.description());
                 paramBean.setExample(requestParam.example());
@@ -246,63 +253,63 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
      *
      * @param classType  classType
      * @param annotation annotation
-     * @param prarm      prarm
+     * @param param      param
      * @return org.apache.dubbo.apidocs.core.beans.ParamBean
      */
-    private ParamBean processHtmlType(Class<?> classType, RequestParam annotation, ParamBean prarm) {
-        if (prarm == null) {
-            prarm = new ParamBean();
+    private ParamBean processHtmlType(Class<?> classType, RequestParam annotation, ParamBean param) {
+        if (param == null) {
+            param = new ParamBean();
         }
         if (annotation != null) {
-            prarm.setAllowableValues(annotation.allowableValues());
+            param.setAllowableValues(annotation.allowableValues());
         }
         // Is there any allowed values
-        boolean hasAllowableValues = (prarm.getAllowableValues() != null && prarm.getAllowableValues().length > 0);
+        boolean hasAllowableValues = (param.getAllowableValues() != null && param.getAllowableValues().length > 0);
         // Processed or not
         boolean processed = false;
         if (Integer.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
+            param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
         } else if (Byte.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.TEXT_BYTE);
+            param.setHtmlType(HtmlTypeEnum.TEXT_BYTE);
             processed = true;
         } else if (Long.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
+            param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
         } else if (Double.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
+            param.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
             processed = true;
         } else if (Float.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
+            param.setHtmlType(HtmlTypeEnum.NUMBER_DECIMAL);
             processed = true;
         } else if (String.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.TEXT);
+            param.setHtmlType(HtmlTypeEnum.TEXT);
             processed = true;
         } else if (Character.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.TEXT_CHAR);
+            param.setHtmlType(HtmlTypeEnum.TEXT_CHAR);
             processed = true;
         } else if (Short.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
+            param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
         }
         if (processed) {
             // Processed, time to return
             if (hasAllowableValues) {
                 // Allowed values has value, change to select
-                prarm.setHtmlType(HtmlTypeEnum.SELECT);
+                param.setHtmlType(HtmlTypeEnum.SELECT);
             }
-            return prarm;
+            return param;
         }
 
         // haven't dealt with it. Go on
         if (Boolean.class.isAssignableFrom(classType)) {
-            prarm.setHtmlType(HtmlTypeEnum.SELECT);
+            param.setHtmlType(HtmlTypeEnum.SELECT);
             // Boolean can only be true / false. No matter what the previous allowed value is, it is forced to replace
-            prarm.setAllowableValues(new String[]{"true", "false"});
+            param.setAllowableValues(new String[]{"true", "false"});
             processed = true;
         } else if (Enum.class.isAssignableFrom(classType)) {
             // process enum
-            prarm.setHtmlType(HtmlTypeEnum.SELECT);
+            param.setHtmlType(HtmlTypeEnum.SELECT);
             if (!hasAllowableValues) {
                 // If there is no optional value, it is taken from the enumeration.
                 //TODO If there is an optional value, it is necessary
@@ -318,12 +325,12 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                     log.error("", e);
                 }
-                prarm.setAllowableValues(enumAllowableValues);
+                param.setAllowableValues(enumAllowableValues);
             }
             processed = true;
         }
         if (processed) {
-            return prarm;
+            return param;
         }
         return null;
     }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
index 5f028ed..36304f2 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsCache.java
@@ -16,6 +16,8 @@
  */
 package org.apache.dubbo.apidocs.core;
 
+import org.apache.dubbo.apidocs.core.beans.ApiCacheItem;
+import org.apache.dubbo.apidocs.core.beans.ModuleCacheItem;
 import org.apache.dubbo.apidocs.utils.ClassTypeUtil;
 
 import com.alibaba.fastjson.JSON;
@@ -36,7 +38,7 @@ public class DubboApiDocsCache {
     /**
      * module cache.
      */
-    private static Map<String, Map<String, Object>> apiModulesCache = new ConcurrentHashMap<>(16);
+    private static Map<String, ModuleCacheItem> apiModulesCache = new ConcurrentHashMap<>(16);
     /**
      * module cache.
      */
@@ -45,32 +47,32 @@ public class DubboApiDocsCache {
     /**
      * API details cache in module.
      */
-    private static Map<String, Map<String, Object>> apiParamsAndRespCache = new ConcurrentHashMap<>(16);
+    private static Map<String, ApiCacheItem> apiParamsAndRespCache = new ConcurrentHashMap<>(16);
     /**
      * API details cache in module.
      */
     private static Map<String, String> apiParamsAndRespStrCache = new ConcurrentHashMap<>(16);
 
-    private static List<Map<String, Object>> allApiModuleInfo = null;
+    private static List<ModuleCacheItem> allApiModuleInfo = null;
 
     private static String basicApiModuleInfo = null;
 
-    public static void addApiModule(String key, Map<String, Object> moduleCacheItem) {
+    public static void addApiModule(String key, ModuleCacheItem moduleCacheItem) {
         apiModulesCache.put(key, moduleCacheItem);
     }
 
-    public static void addApiParamsAndResp(String key, Map<String, Object> apiParamsAndResp) {
+    public static void addApiParamsAndResp(String key, ApiCacheItem apiParamsAndResp) {
         apiParamsAndRespCache.put(key, apiParamsAndResp);
     }
 
-    public static Map<String, Object> getApiModule(String key) {
+    public static ModuleCacheItem getApiModule(String key) {
         return apiModulesCache.get(key);
     }
 
     public static String getApiModuleStr(String key) {
         String result = apiModulesStrCache.get(key);
         if (result == null) {
-            Map<String, Object> temp = apiModulesCache.get(key);
+            ModuleCacheItem temp = apiModulesCache.get(key);
             if (temp != null) {
                 result = JSON.toJSONString(temp, ClassTypeUtil.FAST_JSON_FEATURES);
                 apiModulesStrCache.put(key, result);
@@ -79,14 +81,14 @@ public class DubboApiDocsCache {
         return result;
     }
 
-    public static Map<String, Object> getApiParamsAndResp(String key) {
+    public static ApiCacheItem getApiParamsAndResp(String key) {
         return apiParamsAndRespCache.get(key);
     }
 
     public static String getApiParamsAndRespStr(String key) {
         String result = apiParamsAndRespStrCache.get(key);
         if (result == null) {
-            Map<String, Object> temp = apiParamsAndRespCache.get(key);
+            ApiCacheItem temp = apiParamsAndRespCache.get(key);
             if (temp != null) {
                 result = JSON.toJSONString(temp, ClassTypeUtil.FAST_JSON_FEATURES);
                 apiParamsAndRespStrCache.put(key, result);
@@ -97,7 +99,7 @@ public class DubboApiDocsCache {
 
     public static String getBasicApiModuleInfo() {
         if (basicApiModuleInfo == null) {
-            List<Map<String, Object>> tempList = new ArrayList<>(apiModulesCache.size());
+            List<ModuleCacheItem> tempList = new ArrayList<>(apiModulesCache.size());
             apiModulesCache.forEach((k, v) -> {
                 tempList.add(v);
             });
@@ -106,17 +108,10 @@ public class DubboApiDocsCache {
         return basicApiModuleInfo;
     }
 
-    public static List<Map<String, Object>> getAllApiModuleInfo() {
+    public static List<ModuleCacheItem> getAllApiModuleInfo() {
         if (allApiModuleInfo == null) {
             allApiModuleInfo = new ArrayList<>(apiModulesCache.size());
             apiModulesCache.forEach((k, v) -> {
-                List<Map<String, Object>> apiList = (List<Map<String, Object>>) v.get("moduleApiList");
-                if ( null != apiList && !apiList.isEmpty()) {
-                    for (Map<String, Object> apiInfo : apiList) {
-                        Map<String, Object> apiParams = getApiParamsAndResp(v.get("moduleClassName") + "." + apiInfo.get("apiName"));
-                        apiInfo.putAll(apiParams);
-                    }
-                }
                 allApiModuleInfo.add(v);
             });
         }
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
new file mode 100644
index 0000000..4732cef
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiCacheItem.java
@@ -0,0 +1,39 @@
+package org.apache.dubbo.apidocs.core.beans;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * api cache item.
+ *
+ * @author klw(213539 @ qq.com)
+ * @date 2020/11/20 16:22
+ */
+@Getter
+@Setter
+public class ApiCacheItem {
+
+    private Boolean async;
+
+    private String apiName;
+
+    private String apiDocName;
+
+    private String apiVersion;
+
+    private String description;
+
+    private String apiRespDec;
+
+    private String apiModelClass;
+
+    private List<ApiParamsCacheItem> params;
+
+    private String response;
+
+    private String methodParamInfo;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
new file mode 100644
index 0000000..89880fe
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ApiParamsCacheItem.java
@@ -0,0 +1,40 @@
+package org.apache.dubbo.apidocs.core.beans;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * api params cache item.
+ *
+ * @author klw(213539 @ qq.com)
+ * @date 2020/11/20 16:46
+ */
+@Getter
+@Setter
+public class ApiParamsCacheItem {
+
+    private String name;
+
+    private String docName;
+
+    private String htmlType;
+
+    private String[] allowableValues;
+
+    private String paramType;
+
+    private Integer paramIndex;
+
+    private List<ParamBean> paramInfo;
+
+    private String description;
+
+    private String example;
+
+    private String defaultValue;
+
+    private Boolean required;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
new file mode 100644
index 0000000..cdf8b61
--- /dev/null
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ModuleCacheItem.java
@@ -0,0 +1,26 @@
+package org.apache.dubbo.apidocs.core.beans;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * api module cache item.
+ *
+ * @author klw(213539 @ qq.com)
+ * @date 2020/11/20 15:21
+ */
+@Getter
+@Setter
+public class ModuleCacheItem {
+
+    private String moduleDocName;
+
+    private String moduleClassName;
+
+    private String moduleVersion;
+
+    private List<ApiCacheItem> moduleApiList;
+
+}
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
index abac9a8..02206ec 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/beans/ParamBean.java
@@ -39,7 +39,7 @@ public class ParamBean {
     /**
      * parameter name, for display.
      */
-    private String nameCh;
+    private String docName;
 
     /**
      * required.
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
index 5179765..92b24ca 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/DubboDocProviderImpl.java
@@ -17,12 +17,12 @@
 package org.apache.dubbo.apidocs.core.providers;
 
 import org.apache.dubbo.apidocs.core.DubboApiDocsCache;
+import org.apache.dubbo.apidocs.core.beans.ModuleCacheItem;
 import org.apache.dubbo.config.annotation.DubboService;
 
 import lombok.extern.slf4j.Slf4j;
 
 import java.util.List;
-import java.util.Map;
 
 /**
  * The api implementation of Dubbo doc.
@@ -39,7 +39,7 @@ public class DubboDocProviderImpl implements IDubboDocProvider {
     }
 
     @Override
-    public List<Map<String, Object>> apiModuleListAndApiInfo() {
+    public List<ModuleCacheItem> apiModuleListAndApiInfo() {
         return DubboApiDocsCache.getAllApiModuleInfo();
     }
 
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
index 1e7af23..92bb416 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/providers/IDubboDocProvider.java
@@ -16,8 +16,9 @@
  */
 package org.apache.dubbo.apidocs.core.providers;
 
+import org.apache.dubbo.apidocs.core.beans.ModuleCacheItem;
+
 import java.util.List;
-import java.util.Map;
 
 /**
  * The api used by Dubbo doc, get the parsed API information.
@@ -40,7 +41,7 @@ public interface IDubboDocProvider {
      * @param
      * @return java.lang.String
      */
-    List<Map<String, Object>> apiModuleListAndApiInfo();
+    List<ModuleCacheItem> apiModuleListAndApiInfo();
 
     /**
      * Get module information according to the complete class name of Dubbo provider interface.
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
index 59064a0..9cf5255 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/src/main/java/org/apache/dubbo/apidocs/examples/api/ISyncDemo.java
@@ -45,19 +45,19 @@ public interface ISyncDemo {
     /**
      * request and response parameters are Strings
      * @Date 2020/2/4 0:02
-     * @param: prarm1
-     * @param: prarm2
+     * @param: param1
+     * @param: param2
      * @return java.lang.String
      */
-    String demoApi2(String prarm1, String prarm2);
+    String demoApi2(String param1, String param2);
 
     /**
      * Without Dubbo doc annotation, no document will be generated
      * @Date 2020/2/4 0:22
-     * @param: prarm1
+     * @param: param1
      * @return java.lang.String
      */
-    String demoApi3(String prarm1);
+    String demoApi3(String param1);
 
     /**
      * Nonparametric method with Dubbo doc annotation
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
index 07f13b5..fd21ef4 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/src/main/java/org/apache/dubbo/apidocs/examples/api/impl/SyncDemoImpl.java
@@ -56,13 +56,13 @@ public class SyncDemoImpl implements ISyncDemo {
 
     @ApiDoc(value = "request and response parameters are Strings", responseClassDescription="A string")
     @Override
-    public String demoApi2(@RequestParam(value = "Parameter 1", required = true) String prarm1, String prarm2) {
+    public String demoApi2(@RequestParam(value = "Parameter 1", required = true) String param1, String param2) {
         log.info(" called demoApi2");
         return "demoApi2";
     }
 
     @Override
-    public String demoApi3(String prarm1) {
+    public String demoApi3(String param1) {
         return null;
     }
 
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
index a4f5da1..0e84797 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/DubboApiDocsController.java
@@ -18,7 +18,7 @@ package org.apache.dubbo.apidocs.controller;
 
 import org.apache.dubbo.apidocs.controller.vo.ApiInfoRequest;
 import org.apache.dubbo.apidocs.controller.vo.CallDubboServiceRequest;
-import org.apache.dubbo.apidocs.controller.vo.CallDubboServiceRequestInterfacePrarm;
+import org.apache.dubbo.apidocs.controller.vo.CallDubboServiceRequestInterfaceParam;
 import org.apache.dubbo.apidocs.editor.CustomDateEditor;
 import org.apache.dubbo.apidocs.editor.CustomLocalDateEditor;
 import org.apache.dubbo.apidocs.editor.CustomLocalDateTimeEditor;
@@ -91,49 +91,49 @@ public class DubboApiDocsController {
 
     @ApiOperation(value = "request dubbo api", notes = "request dubbo api", httpMethod = "POST", produces = "application/json")
     @PostMapping("/requestDubbo")
-    public Mono<String> callDubboService(CallDubboServiceRequest dubboCfg, @RequestBody List<CallDubboServiceRequestInterfacePrarm> methodPrarms){
-        String[] prarmTypes = null;
-        Object[] prarmValues = null;
-        if(CollectionUtils.isNotEmpty(methodPrarms)){
-            prarmTypes = new String[methodPrarms.size()];
-            prarmValues = new Object[methodPrarms.size()];
-            for(int i = 0; i < methodPrarms.size(); i++){
-                CallDubboServiceRequestInterfacePrarm prarm = methodPrarms.get(i);
-                prarmTypes[i] = prarm.getPrarmType();
-                Object prarmValue = prarm.getPrarmValue();
-                if(isBaseType(prarm.getPrarmType()) && null != prarmValue){
-                    if(prarmValue instanceof Map){
-                        Map<?, ?> tempMap = (Map<?, ?>) prarmValue;
+    public Mono<String> callDubboService(CallDubboServiceRequest dubboCfg, @RequestBody List<CallDubboServiceRequestInterfaceParam> methodParams){
+        String[] paramTypes = null;
+        Object[] paramValues = null;
+        if(CollectionUtils.isNotEmpty(methodParams)){
+            paramTypes = new String[methodParams.size()];
+            paramValues = new Object[methodParams.size()];
+            for(int i = 0; i < methodParams.size(); i++){
+                CallDubboServiceRequestInterfaceParam param = methodParams.get(i);
+                paramTypes[i] = param.getParamType();
+                Object paramValue = param.getParamValue();
+                if(isBaseType(param.getParamType()) && null != paramValue){
+                    if(paramValue instanceof Map){
+                        Map<?, ?> tempMap = (Map<?, ?>) paramValue;
                         if(!tempMap.isEmpty()) {
                             this.emptyString2Null(tempMap);
-                            prarmValues[i] = tempMap.values().stream().findFirst().orElse(null);
+                            paramValues[i] = tempMap.values().stream().findFirst().orElse(null);
                         }
                     } else {
-                        prarmValues[i] = emptyString2Null(prarmValue);
+                        paramValues[i] = emptyString2Null(paramValue);
                     }
                 } else {
-                    this.emptyString2Null(prarmValue);
-                    prarmValues[i] = prarmValue;
+                    this.emptyString2Null(paramValue);
+                    paramValues[i] = paramValue;
                 }
             }
         }
-        if (null == prarmTypes) {
-            prarmTypes = new String[0];
+        if (null == paramTypes) {
+            paramTypes = new String[0];
         }
-        if (null == prarmValues) {
-            prarmValues = new Object[0];
+        if (null == paramValues) {
+            paramValues = new Object[0];
         }
         CompletableFuture<Object> future = DubboGenericUtil.invoke(dubboCfg.getRegistryCenterUrl(), dubboCfg.getInterfaceClassName(),
-                dubboCfg.getMethodName(), dubboCfg.isAsync(), prarmTypes, prarmValues);
+                dubboCfg.getMethodName(), dubboCfg.isAsync(), paramTypes, paramValues);
         return Mono.fromFuture(future).map( o -> JSON.toJSONString(o, CLASS_NAME_PRE_FILTER));
     }
 
-    private Object emptyString2Null(Object prarmValue){
-        if(null != prarmValue) {
-            if (prarmValue instanceof String && StringUtils.isBlank((String) prarmValue)) {
+    private Object emptyString2Null(Object paramValue){
+        if(null != paramValue) {
+            if (paramValue instanceof String && StringUtils.isBlank((String) paramValue)) {
                 return null;
-            } else if (prarmValue instanceof Map) {
-                Map<String, Object> tempMap = (Map<String, Object>) prarmValue;
+            } else if (paramValue instanceof Map) {
+                Map<String, Object> tempMap = (Map<String, Object>) paramValue;
                 tempMap.forEach((k, v) -> {
                     if (v != null && v instanceof String && StringUtils.isBlank((String) v)) {
                         tempMap.put(k, null);
@@ -143,7 +143,7 @@ public class DubboApiDocsController {
                 });
             }
         }
-        return prarmValue;
+        return paramValue;
     }
 
     @ApiOperation(value = "Get basic information of all modules, excluding API parameter information", notes = "Get basic information of all modules, excluding API parameter information", httpMethod = "GET", produces = "application/json")
@@ -166,12 +166,12 @@ public class DubboApiDocsController {
         req.setMethodName("apiParamsResponseInfo");
         req.setAsync(false);
 
-        List<CallDubboServiceRequestInterfacePrarm> methodPrarms = new ArrayList<>(1);
-        CallDubboServiceRequestInterfacePrarm prarm = new CallDubboServiceRequestInterfacePrarm();
-        prarm.setPrarmType(String.class.getName());
-        prarm.setPrarmValue(apiInfoRequest.getApiName());
-        methodPrarms.add(prarm);
-        return callDubboService(req, methodPrarms);
+        List<CallDubboServiceRequestInterfaceParam> methodParams = new ArrayList<>(1);
+        CallDubboServiceRequestInterfaceParam param = new CallDubboServiceRequestInterfaceParam();
+        param.setParamType(String.class.getName());
+        param.setParamValue(apiInfoRequest.getApiName());
+        methodParams.add(param);
+        return callDubboService(req, methodParams);
     }
 
     private static boolean isBaseType(String typeStr) {
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfacePrarm.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
similarity index 91%
rename from dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfacePrarm.java
rename to dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
index 3cf6d0f..44f3bce 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfacePrarm.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/controller/vo/CallDubboServiceRequestInterfaceParam.java
@@ -27,12 +27,12 @@ import lombok.Setter;
  */
 @Getter
 @Setter
-public class CallDubboServiceRequestInterfacePrarm {
+public class CallDubboServiceRequestInterfaceParam {
 
     @ApiParam(value = "Parameter type (full package path), such as: java.lang.String", required = true)
-    private String prarmType;
+    private String paramType;
 
     @ApiParam(value = "Parameter value", required = true)
-    private Object prarmValue;
+    private Object paramValue;
 
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
index 613d79d..1c085bc 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/java/org/apache/dubbo/apidocs/utils/DubboGenericUtil.java
@@ -127,22 +127,22 @@ public class DubboGenericUtil {
      * @param: methodName
      * @param: async  Whether the provider is asynchronous is to directly return the {@link CompletableFuture}
      * returned by the provider, not to wrap it as {@link CompletableFuture}
-     * @param: prarmTypes
-     * @param: prarmValues
+     * @param: paramTypes
+     * @param: paramValues
      * @return java.util.concurrent.CompletableFuture<java.lang.Object>
      */
     public static CompletableFuture<Object> invoke(String address, String interfaceName,
-                                                  String methodName, boolean async, String[] prarmTypes,
-                                                  Object[] prarmValues) {
+                                                  String methodName, boolean async, String[] paramTypes,
+                                                  Object[] paramValues) {
         CompletableFuture future = null;
         ReferenceConfig<GenericService> reference = getReferenceConfig(address, interfaceName);
         if (null != reference) {
             GenericService genericService = reference.get();
             if (null != genericService) {
                 if(async){
-                    future = genericService.$invokeAsync(methodName, prarmTypes, prarmValues);
+                    future = genericService.$invokeAsync(methodName, paramTypes, paramValues);
                 } else {
-                    future = CompletableFuture.supplyAsync(() -> genericService.$invoke(methodName, prarmTypes, prarmValues), executor);
+                    future = CompletableFuture.supplyAsync(() -> genericService.$invoke(methodName, paramTypes, paramValues), executor);
                 }
             }
         }
@@ -155,18 +155,18 @@ public class DubboGenericUtil {
      * @param: address
      * @param: interfaceName
      * @param: methodName
-     * @param: prarmTypes
-     * @param: prarmValues
+     * @param: paramTypes
+     * @param: paramValues
      * @return java.lang.Object
      */
     public static Object invokeSync(String address, String interfaceName,
-                                                   String methodName, String[] prarmTypes,
-                                                   Object[] prarmValues) {
+                                                   String methodName, String[] paramTypes,
+                                                   Object[] paramValues) {
         ReferenceConfig<GenericService> reference = getReferenceConfig(address, interfaceName);
         if (null != reference) {
             GenericService genericService = reference.get();
             if (null != genericService) {
-                return genericService.$invoke(methodName, prarmTypes, prarmValues);
+                return genericService.$invoke(methodName, paramTypes, paramValues);
             }
         }
         return null;
diff --git a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
index a7ab576..496947b 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
+++ b/dubbo-api-docs/dubbo-api-docs-ui-server/src/main/resources/static/js/index.js
@@ -109,4 +109,4 @@ var t;return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
- */var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,a=r?Symbol.for("react.portal"):60106,i=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,u=r?Symbol.for("react.profiler"):60114,l=r?Symbol.for("react.provider"):60109,c=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,p=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,v=r?S [...]
\ No newline at end of file
+ */var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,a=r?Symbol.for("react.portal"):60106,i=r?Symbol.for("react.fragment"):60107,s=r?Symbol.for("react.strict_mode"):60108,u=r?Symbol.for("react.profiler"):60114,l=r?Symbol.for("react.provider"):60109,c=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,p=r?Symbol.for("react.concurrent_mode"):60111,d=r?Symbol.for("react.forward_ref"):60112,h=r?Symbol.for("react.suspense"):60113,v=r?S [...]
\ No newline at end of file
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/index.tsx b/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/index.tsx
index beeacc4..255eb95 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/index.tsx
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/layouts/BasicLayout/index.tsx
@@ -52,7 +52,7 @@ export default function BasicLayout(props: {
     if(response && response != ''){
       const menuData = JSON.parse(response);
       menuData.sort((a,b) => {
-        return a.moduleChName > b.moduleChName;
+        return a.moduleDocName > b.moduleDocName;
       });
       for(let i = 0; i < menuData.length; i++){
         const menu = menuData[i];
@@ -60,7 +60,7 @@ export default function BasicLayout(props: {
           return a.apiName > b.apiName;
         });
         const menu2 = {
-          name: menu.moduleChName,
+          name: menu.moduleDocName,
           path: '',
           icon: 'cascades',
           children: new Array(),
@@ -69,7 +69,7 @@ export default function BasicLayout(props: {
         for(let j = 0; j < menuItems.length; j++){
           const menuItem = menuItems[j];
           const menuItem2 = {
-            name: menuItem.apiChName,
+            name: menuItem.apiDocName,
             path: `/apiForm?apiName=${menu.moduleClassName}.${menuItem.apiName}&dubboIp=${dubboIp}&dubboPort=${dubboPort}`,
           };
           menu2.children.push(menuItem2);
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json
index 7548477..d220b43 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/en-US.json
@@ -11,16 +11,17 @@
     "api404Err": "Interface name is incorrect, interface parameters and response information are not found",
     "apiRespDecShowLabel": "Api Info",
     "apiNameShowLabel": "Api Name",
+    "apiMethodParamInfoLabel": "Api method parameters",
     "apiVersionShowLabel": "Api Version",
     "apiDescriptionShowLabel": "Api Description",
     "isAsyncFormLabel": "Whether to call asynchronously (this parameter cannot be modified, according to whether to display asynchronously defined by the interface)",
     "apiModuleFormLabel": "Api module (this parameter cannot be modified)",
     "apiFunctionNameFormLabel": "Api function name(this parameter cannot be modified)",
     "registryCenterUrlFormLabel": "Registry address. If it is empty, Dubbo provider IP and port will be used for direct connection",
-    "prarmNameLabel": "Parameter name",
-    "prarmPathLabel": "Parameter path",
-    "prarmDescriptionLabel": "Description",
-    "prarmRequiredLabel": "This parameter is required",
+    "paramNameLabel": "Parameter name",
+    "paramPathLabel": "Parameter path",
+    "paramDescriptionLabel": "Description",
+    "paramRequiredLabel": "This parameter is required",
     "doTestBtn": "Do Test",
     "responseLabel": "Response",
     "responseExampleLabel": "Response Example",
@@ -29,6 +30,6 @@
     "requireTip": "There are required items not filled in",
     "requestApiErrorTip": "There is an exception in the request interface. Please check the submitted data, especially the JSON class data and the enumeration part",
     "unsupportedHtmlTypeTip": "Temporarily unsupported HTML type"
-    
+
   }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json
index b008bc6..41c8e37 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/locales/zh-CN.json
@@ -11,16 +11,17 @@
     "api404Err": "接口名称不正确,没有查找到接口参数和响应信息",
     "apiRespDecShowLabel": "接口说明",
     "apiNameShowLabel": "接口名称",
+    "apiMethodParamInfoLabel": "接口参数",
     "apiVersionShowLabel": "接口版本",
     "apiDescriptionShowLabel": "接口描述",
     "isAsyncFormLabel": "是否异步调用(此参数不可修改,根据接口定义的是否异步显示)",
     "apiModuleFormLabel": "接口模块(此参数不可修改)",
     "apiFunctionNameFormLabel": "接口方法名(此参数不可修改)",
     "registryCenterUrlFormLabel": "注册中心地址, 如果为空将使用Dubbo 提供者Ip和端口进行直连",
-    "prarmNameLabel": "参数名",
-    "prarmPathLabel": "参数位置",
-    "prarmDescriptionLabel": "说明",
-    "prarmRequiredLabel": "该参数为必填",
+    "paramNameLabel": "参数名",
+    "paramPathLabel": "参数位置",
+    "paramDescriptionLabel": "说明",
+    "paramRequiredLabel": "该参数为必填",
     "doTestBtn": "测试",
     "responseLabel": "响应",
     "responseExampleLabel": "响应示例",
@@ -29,6 +30,6 @@
     "requireTip": "有未填写的必填项",
     "requestApiErrorTip": "请求接口发生异常,请检查提交的数据,特别是JSON类数据和其中的枚举部分",
     "unsupportedHtmlTypeTip": "暂不支持的HTML类型"
-    
+
   }
 }
diff --git a/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx b/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx
index 8a9cf2d..3c80855 100644
--- a/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx
+++ b/dubbo-api-docs/dubbo-api-docs-ui/src/pages/ApiForm/index.tsx
@@ -128,10 +128,10 @@ class ApiForm extends React.Component {
           var formItem = new Map();
           formItem.set('name', paramItem.name);
           formItem.set('htmlType', paramItem.htmlType);
-          formItem.set('paramType', paramItem.prarmType);
-          formItem.set('javaType', paramItem.prarmType);
-          formItem.set('paramIndex', paramItem.prarmIndex);
-          formItem.set('nameCh', paramItem.nameCh);
+          formItem.set('paramType', paramItem.paramType);
+          formItem.set('javaType', paramItem.paramType);
+          formItem.set('paramIndex', paramItem.paramIndex);
+          formItem.set('docName', paramItem.docName);
           formItem.set('description', paramItem.description);
           formItem.set('example', paramItem.example);
           formItem.set('defaultValue', paramItem.defaultValue);
@@ -140,22 +140,22 @@ class ApiForm extends React.Component {
           formsArray.push(formItem);
         } else {
           // No htmltype, that's an object
-          var prarmInfoArray = paramItem.prarmInfo;
-          for(var j = 0; j < prarmInfoArray.length; j++){
-            var prarmInfoItem = prarmInfoArray[j];
+          var paramInfoArray = paramItem.paramInfo;
+          for(var j = 0; j < paramInfoArray.length; j++){
+            var paramInfoItem = paramInfoArray[j];
             var formItem = new Map();
-            formItem.set('name', prarmInfoItem.name);
-            formItem.set('htmlType', prarmInfoItem.htmlType);
-            formItem.set('paramType', paramItem.prarmType);
-            formItem.set('javaType', prarmInfoItem.javaType);
-            formItem.set('paramIndex', paramItem.prarmIndex);
-            formItem.set('nameCh', prarmInfoItem.nameCh);
-            formItem.set('description', prarmInfoItem.description);
-            formItem.set('example', prarmInfoItem.example);
-            formItem.set('defaultValue', prarmInfoItem.defaultValue);
-            formItem.set('allowableValues', prarmInfoItem.allowableValues);
-            formItem.set('subParamsJson', prarmInfoItem.subParamsJson);
-            formItem.set('required', prarmInfoItem.required);
+            formItem.set('name', paramInfoItem.name);
+            formItem.set('htmlType', paramInfoItem.htmlType);
+            formItem.set('paramType', paramItem.paramType);
+            formItem.set('javaType', paramInfoItem.javaType);
+            formItem.set('paramIndex', paramItem.paramIndex);
+            formItem.set('docName', paramInfoItem.docName);
+            formItem.set('description', paramInfoItem.description);
+            formItem.set('example', paramInfoItem.example);
+            formItem.set('defaultValue', paramInfoItem.defaultValue);
+            formItem.set('allowableValues', paramInfoItem.allowableValues);
+            formItem.set('subParamsJson', paramInfoItem.subParamsJson);
+            formItem.set('required', paramInfoItem.required);
             formsArray.push(formItem);
           }
         }
@@ -166,7 +166,7 @@ class ApiForm extends React.Component {
             <Form.Item
               key='formItemAsync'
               label={this.state.locale.isAsyncFormLabel}>
-              <Select 
+              <Select
                 id='formItemAsync'
                 name='formItemAsync'
                 style={{ marginLeft: 5, width: '100px' }}
@@ -218,21 +218,21 @@ class ApiForm extends React.Component {
                 return (
                   <div key={'formDiv' + index} style={{ marginTop: 20 }}>
                     <div style={{ width: '1000px', height:'220px' }}>
-                      <div style={{ float: 'left', border: '2px solid rgb(228 224 224)', 
+                      <div style={{ float: 'left', border: '2px solid rgb(228 224 224)',
                             width: '400px', height: '100%', overflowY: 'auto', overflowX: 'hidden'}}>
                         <Timeline>
-                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.prarmNameLabel} content={item.get('name')} state="process"/>
-                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.prarmPathLabel} content={item.get('paramType') + "#" + item.get('name')} state="process"/>
-                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.prarmDescriptionLabel} content={item.get('description')} state="process"/>
+                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.paramNameLabel} content={item.get('name')} state="process"/>
+                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.paramPathLabel} content={item.get('paramType') + "#" + item.get('name')} state="process"/>
+                          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.paramDescriptionLabel} content={item.get('description')} state="process"/>
                         </Timeline>
                       </div>
                       <div style={{float: "left"}}>
-                        <Form.Item 
-                          help={item.get('required') ? this.state.locale.prarmRequiredLabel : ''}
+                        <Form.Item
+                          help={item.get('required') ? this.state.locale.paramRequiredLabel : ''}
                           key={'formItem' + index}
                           required={item.get('required')}
                           style={{padding: '5px'}}
-                          label={item.get('nameCh')}
+                          label={item.get('docName')}
                         >
                         {
                           this.buildFormItem(item)
@@ -279,14 +279,14 @@ class ApiForm extends React.Component {
             </div>
           </div>
         </div>
-        
+
       );
     } else {
       return (
         <h1>{this.state.locale.LoadingLabel}</h1>
       );
     }
-    
+
   }
 
   buildResponseInfoView(){
@@ -309,13 +309,13 @@ class ApiForm extends React.Component {
         throw 'dataNotJson';
       }
       return (
-        <ReactJson 
+        <ReactJson
         style={{ marginLeft: 5, minWidth: '580px' }}
-          name={false} 
+          name={false}
           theme='apathy'
           iconStyle='square'
           displayDataTypes={true}
-          src={responseInfoJsonObj} 
+          src={responseInfoJsonObj}
         />
       );
     } catch (e) {
@@ -345,13 +345,13 @@ class ApiForm extends React.Component {
         throw 'dataNotJson';
       }
       return (
-        <ReactJson 
+        <ReactJson
           style={{ marginLeft: 5, minWidth: '580px' }}
-          name={false} 
+          name={false}
           theme='apathy'
           iconStyle='square'
           displayDataTypes={true}
-          src={this.state.responseData} 
+          src={this.state.responseData}
         />
       );
     } catch (e) {
@@ -388,9 +388,9 @@ class ApiForm extends React.Component {
     tempMap.forEach((value, key) => {
       var postDataItem = {};
       postData[key.split('@@')[1]] = postDataItem;
-      postDataItem['prarmType'] = key.split('@@')[0];
+      postDataItem['paramType'] = key.split('@@')[0];
       var postDataItemValue = {};
-      postDataItem['prarmValue'] = postDataItemValue;
+      postDataItem['paramValue'] = postDataItemValue;
       value.forEach(element => {
         var elementName = element.name.split('@@')[3];
         if(element.tagName == 'TEXTAREA'){
@@ -420,7 +420,7 @@ class ApiForm extends React.Component {
         registryCenterUrl: registryCenterUrl
       },
       headers: {
-        'Content-Type': 'application/json; charset=UTF-8' 
+        'Content-Type': 'application/json; charset=UTF-8'
       },
       data: JSON.stringify(postData),
     }).catch(error => {
@@ -437,10 +437,13 @@ class ApiForm extends React.Component {
   showApiInfo(){
     return (
       <div>
-        <h1>{this.state.locale.apiNameShowLabel}: <span>{this.state.apiInfoData.apiChName + '(' + this.state.apiName + ')'}</span></h1>
-        <h1>{this.state.locale.apiRespDecShowLabel}: <span>{this.state.apiInfoData.apiRespDec}</span></h1>
-        <h1>{this.state.locale.apiVersionShowLabel}: <span>{this.state.apiInfoData.apiVersion}</span></h1>
-        <h1>{this.state.locale.apiDescriptionShowLabel}: <span>{this.state.apiInfoData.apiDescription}</span></h1>
+        <Timeline>
+          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.apiNameShowLabel} content={this.state.apiInfoData.apiDocName + '(' + this.state.apiName + ')'} state="success" />
+          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.apiMethodParamInfoLabel} content={this.state.apiInfoData.methodParamInfo} state="success" />
+          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.apiRespDecShowLabel} content={this.state.apiInfoData.apiRespDec} state="success" />
+          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.apiVersionShowLabel} content={this.state.apiInfoData.apiVersion} state="success" />
+          <Timeline.Item style={{wordBreak: 'break-word'}} title={this.state.locale.apiDescriptionShowLabel} content={this.state.apiInfoData.apiDescription} state="success" />
+        </Timeline>
       </div>
     );
   }
@@ -508,7 +511,7 @@ class ApiForm extends React.Component {
 
   buildReactJson(item){
     return (
-      <ReactJson 
+      <ReactJson
         onEdit={o => {
           console.log(o);
         }}
@@ -517,9 +520,9 @@ class ApiForm extends React.Component {
         }}
         onDelete={o => {
           console.log(o);
-        }} 
-        name={false} 
-        src={[{'abc': 123, 'cde': 'wdsfasdf'},{'abc': 123, 'cde': 'wdsfasdf'}]} 
+        }}
+        name={false}
+        src={[{'abc': 123, 'cde': 'wdsfasdf'},{'abc': 123, 'cde': 'wdsfasdf'}]}
       />
     )
   }
@@ -550,7 +553,7 @@ class ApiForm extends React.Component {
       dataSource.push(dsItem);
     }
     return (
-      <Select 
+      <Select
         name={item.get('paramType') + '@@' + item.get('paramIndex') + '@@' + item.get('javaType') + "@@" + item.get('name')}
         className={'dubbo-doc-form-item-class'}
         style={{ marginLeft: 5, width: '400px' }}
@@ -572,7 +575,7 @@ class ApiForm extends React.Component {
         break;
       case 'NUMBER_INTEGER':
         return this.buildNumberInteger(item);
-        break;  
+        break;
       case 'NUMBER_DECIMAL':
         return this.buildNumberDecimal(item);
         break;
@@ -608,9 +611,9 @@ class ApiForm extends React.Component {
           </div>
         </Loading>
       </div>
-     
+
     );
   }
 };
 
-export default ApiForm;
\ No newline at end of file
+export default ApiForm;