support html api doc
This commit is contained in:
parent
07e7a7aa6a
commit
fee078b72a
|
@ -4,6 +4,9 @@ import com.power.common.util.CollectionUtil;
|
|||
import com.power.common.util.DateTimeUtil;
|
||||
import com.power.common.util.FileUtil;
|
||||
import com.power.common.util.StringUtil;
|
||||
import com.power.doc.constants.GlobalConstants;
|
||||
import com.power.doc.constants.Language;
|
||||
import com.power.doc.constants.TemplateVariable;
|
||||
import com.power.doc.model.ApiConfig;
|
||||
import com.power.doc.model.ApiDoc;
|
||||
import com.power.doc.model.ApiErrorCode;
|
||||
|
@ -12,10 +15,11 @@ import org.beetl.core.Template;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static com.power.doc.constants.GlobalConstants.FILE_SEPARATOR;
|
||||
import static com.power.doc.constants.GlobalConstants.*;
|
||||
|
||||
/**
|
||||
* use to create markdown doc
|
||||
*
|
||||
* @author yu 2019/09/20
|
||||
*/
|
||||
public class ApiDocBuilder {
|
||||
|
@ -42,6 +46,12 @@ public class ApiDocBuilder {
|
|||
if (StringUtil.isEmpty(config.getOutPath())) {
|
||||
throw new RuntimeException("doc output path can't be null or empty");
|
||||
}
|
||||
if (null != config.getLanguage()) {
|
||||
System.setProperty(GlobalConstants.DOC_LANGUAGE, config.getLanguage().getCode());
|
||||
} else {
|
||||
//default is chinese
|
||||
System.setProperty(GlobalConstants.DOC_LANGUAGE, Language.CHINESE.getCode());
|
||||
}
|
||||
SourceBuilder sourceBuilder = new SourceBuilder(config);
|
||||
List<ApiDoc> apiDocList = sourceBuilder.getControllerApiData();
|
||||
if (config.isAllInOne()) {
|
||||
|
@ -62,10 +72,10 @@ public class ApiDocBuilder {
|
|||
FileUtil.mkdirs(outPath);
|
||||
SourceBuilder sourceBuilder = new SourceBuilder(true);
|
||||
ApiDoc doc = sourceBuilder.getSingleControllerApiData(controllerName);
|
||||
Template mapper = BeetlTemplateUtil.getByName("ApiDoc.btl");
|
||||
mapper.binding("desc", doc.getDesc());
|
||||
mapper.binding("name", doc.getName());
|
||||
mapper.binding("list", doc.getList());//类名
|
||||
Template mapper = BeetlTemplateUtil.getByName(API_DOC_TPL);
|
||||
mapper.binding(TemplateVariable.DESC.getVariable(), doc.getDesc());
|
||||
mapper.binding(TemplateVariable.NAME.getVariable(), doc.getName());
|
||||
mapper.binding(TemplateVariable.LIST.getVariable(), doc.getList());//类名
|
||||
FileUtil.writeFileNotAppend(mapper.render(), outPath + FILE_SEPARATOR + doc.getName() + "Api.md");
|
||||
}
|
||||
|
||||
|
@ -78,10 +88,10 @@ public class ApiDocBuilder {
|
|||
private static void buildApiDoc(List<ApiDoc> apiDocList, String outPath) {
|
||||
FileUtil.mkdirs(outPath);
|
||||
for (ApiDoc doc : apiDocList) {
|
||||
Template mapper = BeetlTemplateUtil.getByName("ApiDoc.btl");
|
||||
mapper.binding("desc", doc.getDesc());
|
||||
mapper.binding("name", doc.getName());
|
||||
mapper.binding("list", doc.getList());//类名
|
||||
Template mapper = BeetlTemplateUtil.getByName(API_DOC_TPL);
|
||||
mapper.binding(TemplateVariable.DESC.getVariable(), doc.getDesc());
|
||||
mapper.binding(TemplateVariable.NAME.getVariable(), doc.getName());
|
||||
mapper.binding(TemplateVariable.LIST.getVariable(), doc.getList());//类名
|
||||
FileUtil.nioWriteFile(mapper.render(), outPath + FILE_SEPARATOR + doc.getName() + "Api.md");
|
||||
}
|
||||
}
|
||||
|
@ -95,9 +105,9 @@ public class ApiDocBuilder {
|
|||
String outPath = config.getOutPath();
|
||||
FileUtil.mkdirs(outPath);
|
||||
Template tpl = BeetlTemplateUtil.getByName("AllInOne.btl");
|
||||
tpl.binding("apiDocList", apiDocList);
|
||||
tpl.binding("errorCodeList", config.getErrorCodes());
|
||||
tpl.binding("revisionLogList", config.getRevisionLogs());
|
||||
tpl.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocList);
|
||||
tpl.binding(TemplateVariable.ERROR_CODE_LIST.getVariable(), config.getErrorCodes());
|
||||
tpl.binding(TemplateVariable.VERSION_LIST.getVariable(), config.getRevisionLogs());
|
||||
String version = DateTimeUtil.long2Str(System.currentTimeMillis(), "yyyyMMddHHmm");
|
||||
FileUtil.nioWriteFile(tpl.render(), outPath + FILE_SEPARATOR + "AllInOne-V" + version + ".md");
|
||||
}
|
||||
|
@ -110,9 +120,9 @@ public class ApiDocBuilder {
|
|||
*/
|
||||
private static void buildErrorCodeDoc(List<ApiErrorCode> errorCodeList, String outPath) {
|
||||
if (CollectionUtil.isNotEmpty(errorCodeList)) {
|
||||
Template mapper = BeetlTemplateUtil.getByName("ErrorCodeList.btl");
|
||||
mapper.binding("list", errorCodeList);//类名
|
||||
FileUtil.nioWriteFile(mapper.render(), outPath + FILE_SEPARATOR + "ErrorCodeList.md");
|
||||
Template mapper = BeetlTemplateUtil.getByName(ERROR_CODE_LIST_TPL);
|
||||
mapper.binding(TemplateVariable.LIST.getVariable(), errorCodeList);//类名
|
||||
FileUtil.nioWriteFile(mapper.render(), outPath + FILE_SEPARATOR + ERROR_CODE_LIST_MD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,26 @@
|
|||
package com.power.doc.builder;
|
||||
|
||||
import com.power.common.util.CollectionUtil;
|
||||
import com.power.common.util.DateTimeUtil;
|
||||
import com.power.common.util.FileUtil;
|
||||
import com.power.common.util.StringUtil;
|
||||
import com.power.doc.constants.GlobalConstants;
|
||||
import com.power.doc.constants.Language;
|
||||
import com.power.doc.constants.TemplateVariable;
|
||||
import com.power.doc.model.ApiConfig;
|
||||
import com.power.doc.model.ApiDoc;
|
||||
import com.power.doc.model.ApiErrorCode;
|
||||
import com.power.doc.utils.BeetlTemplateUtil;
|
||||
import com.power.doc.utils.MarkDownUtil;
|
||||
import org.beetl.core.Template;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import static com.power.doc.constants.GlobalConstants.FILE_SEPARATOR;
|
||||
import static com.power.doc.constants.GlobalConstants.*;
|
||||
|
||||
/**
|
||||
* @author yu 2019/9/20.
|
||||
* @since 1.7+
|
||||
*/
|
||||
public class HtmlApiDocBuilder {
|
||||
|
||||
|
@ -27,27 +34,44 @@ public class HtmlApiDocBuilder {
|
|||
if (StringUtil.isEmpty(config.getOutPath())) {
|
||||
throw new RuntimeException("doc output path can't be null or empty");
|
||||
}
|
||||
if (null != config.getLanguage()) {
|
||||
System.setProperty(GlobalConstants.DOC_LANGUAGE, config.getLanguage().getCode());
|
||||
} else {
|
||||
//default is chinese
|
||||
System.setProperty(GlobalConstants.DOC_LANGUAGE, Language.CHINESE.getCode());
|
||||
}
|
||||
SourceBuilder sourceBuilder = new SourceBuilder(config);
|
||||
List<ApiDoc> apiDocList = sourceBuilder.getControllerApiData();
|
||||
buildIndex(apiDocList, config.getOutPath());
|
||||
buildIndex(apiDocList, config);
|
||||
copyCss(config.getOutPath());
|
||||
buildApiDoc(apiDocList, config.getOutPath());
|
||||
buildErrorCodeDoc(config.getErrorCodes(), config.getOutPath());
|
||||
}
|
||||
|
||||
private static void copyCss(String outPath) {
|
||||
Template indexCssTemplate = BeetlTemplateUtil.getByName("index.css");
|
||||
Template mdCssTemplate = BeetlTemplateUtil.getByName("markdown.css");
|
||||
FileUtil.nioWriteFile(indexCssTemplate.render(), outPath + FILE_SEPARATOR + "index.css");
|
||||
FileUtil.nioWriteFile(mdCssTemplate.render(), outPath + FILE_SEPARATOR + "markdown.css");
|
||||
Template indexCssTemplate = BeetlTemplateUtil.getByName(INDEX_CSS_TPL);
|
||||
Template mdCssTemplate = BeetlTemplateUtil.getByName(MARKDOWN_CSS_TPL);
|
||||
FileUtil.nioWriteFile(indexCssTemplate.render(), outPath + FILE_SEPARATOR + INDEX_CSS_TPL);
|
||||
FileUtil.nioWriteFile(mdCssTemplate.render(), outPath + FILE_SEPARATOR + MARKDOWN_CSS_TPL);
|
||||
}
|
||||
|
||||
private static void buildIndex(List<ApiDoc> apiDocList, String outPath) {
|
||||
FileUtil.mkdirs(outPath);
|
||||
Template indexTemplate = BeetlTemplateUtil.getByName("Index.btl");
|
||||
private static void buildIndex(List<ApiDoc> apiDocList, ApiConfig config) {
|
||||
FileUtil.mkdirs(config.getOutPath());
|
||||
Template indexTemplate = BeetlTemplateUtil.getByName(INDEX_TPL);
|
||||
ApiDoc doc = apiDocList.get(0);
|
||||
String homePage = doc.getName();
|
||||
indexTemplate.binding("home", homePage);
|
||||
indexTemplate.binding("apiDocList", apiDocList);
|
||||
FileUtil.nioWriteFile(indexTemplate.render(), outPath + FILE_SEPARATOR + "api.html");
|
||||
String homePage = doc.getAlias();
|
||||
indexTemplate.binding(TemplateVariable.HOME_PAGE.getVariable(), homePage);
|
||||
indexTemplate.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocList);
|
||||
if (null != config.getLanguage()) {
|
||||
if (Language.CHINESE.code.equals(config.getLanguage().getCode())) {
|
||||
indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), "A. 错误码列表");
|
||||
} else {
|
||||
indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), "A. Error Code List");
|
||||
}
|
||||
} else {
|
||||
indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), "A. 错误码列表");
|
||||
}
|
||||
FileUtil.nioWriteFile(indexTemplate.render(), config.getOutPath() + FILE_SEPARATOR + "api.html");
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,12 +83,41 @@ public class HtmlApiDocBuilder {
|
|||
*/
|
||||
private static void buildApiDoc(List<ApiDoc> apiDocList, String outPath) {
|
||||
FileUtil.mkdirs(outPath);
|
||||
Template htmlApiDoc;
|
||||
for (ApiDoc doc : apiDocList) {
|
||||
Template mapper = BeetlTemplateUtil.getByName("ApiDoc.btl");
|
||||
mapper.binding("desc", doc.getDesc());
|
||||
mapper.binding("name", doc.getName());
|
||||
mapper.binding("list", doc.getList());//类名
|
||||
FileUtil.nioWriteFile(mapper.render(), outPath + FILE_SEPARATOR + doc.getName() + "Api.md");
|
||||
Template apiTemplate = BeetlTemplateUtil.getByName(API_DOC_TPL);
|
||||
apiTemplate.binding(TemplateVariable.DESC.getVariable(), doc.getDesc());
|
||||
apiTemplate.binding(TemplateVariable.NAME.getVariable(), doc.getName());
|
||||
apiTemplate.binding(TemplateVariable.LIST.getVariable(), doc.getList());//类名
|
||||
|
||||
String html = MarkDownUtil.toHtml(apiTemplate.render());
|
||||
htmlApiDoc = BeetlTemplateUtil.getByName(HTML_API_DOC_TPL);
|
||||
htmlApiDoc.binding(TemplateVariable.HTML.getVariable(), html);
|
||||
htmlApiDoc.binding(TemplateVariable.TITLE.getVariable(),doc.getName());
|
||||
htmlApiDoc.binding(TemplateVariable.CREATE_TIME.getVariable(), DateTimeUtil.long2Str(System.currentTimeMillis()
|
||||
, DateTimeUtil.DATE_FORMAT_SECOND));
|
||||
FileUtil.nioWriteFile(htmlApiDoc.render(), outPath + FILE_SEPARATOR + doc.getAlias() + ".html");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建错误码列表
|
||||
*
|
||||
* @param errorCodeList 错误列表
|
||||
* @param outPath
|
||||
*/
|
||||
private static void buildErrorCodeDoc(List<ApiErrorCode> errorCodeList, String outPath) {
|
||||
if (CollectionUtil.isNotEmpty(errorCodeList)) {
|
||||
Template error = BeetlTemplateUtil.getByName(ERROR_CODE_LIST_TPL);
|
||||
error.binding(TemplateVariable.LIST.getVariable(), errorCodeList);//类名
|
||||
String errorHtml = MarkDownUtil.toHtml(error.render());
|
||||
Template errorCodeDoc = BeetlTemplateUtil.getByName(HTML_API_DOC_TPL);
|
||||
errorCodeDoc.binding(TemplateVariable.TITLE.getVariable(),"error code");
|
||||
errorCodeDoc.binding(TemplateVariable.HTML.getVariable(), errorHtml);
|
||||
errorCodeDoc.binding(TemplateVariable.CREATE_TIME.getVariable(), DateTimeUtil.long2Str(System.currentTimeMillis()
|
||||
, DateTimeUtil.DATE_FORMAT_SECOND));
|
||||
FileUtil.nioWriteFile(errorCodeDoc.render(), outPath + FILE_SEPARATOR + "error_code.html");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
package com.power.doc.builder;
|
||||
|
||||
import com.power.common.util.CollectionUtil;
|
||||
import com.power.common.util.JsonFormatUtil;
|
||||
import com.power.common.util.StringUtil;
|
||||
import com.power.common.util.UrlUtil;
|
||||
import com.power.common.util.*;
|
||||
import com.power.doc.constants.AnnotationConstants;
|
||||
import com.power.doc.constants.DocTags;
|
||||
import com.power.doc.constants.GlobalConstants;
|
||||
|
@ -48,6 +45,7 @@ public class SourceBuilder {
|
|||
private String packageMatch;
|
||||
private List<ApiReqHeader> headers;
|
||||
private String appUrl;
|
||||
private AesInfo aesInfo;
|
||||
|
||||
/**
|
||||
* if isStrict value is true,it while check all method
|
||||
|
@ -75,6 +73,7 @@ public class SourceBuilder {
|
|||
this.appUrl = config.getServerUrl();
|
||||
}
|
||||
|
||||
aesInfo = config.getAesInfo();
|
||||
this.packageMatch = config.getPackageFilters();
|
||||
this.isStrict = config.isStrict();
|
||||
loadJavaFiles(config.getSourcePaths());
|
||||
|
@ -154,22 +153,32 @@ public class SourceBuilder {
|
|||
|
||||
public List<ApiDoc> getControllerApiData() {
|
||||
List<ApiDoc> apiDocList = new ArrayList<>();
|
||||
int order = 0;
|
||||
for (JavaClass cls : javaClasses) {
|
||||
if (checkController(cls)) {
|
||||
String controllerName = cls.getName();
|
||||
if (StringUtil.isNotEmpty(packageMatch)) {
|
||||
if (DocUtil.isMatch(packageMatch, cls.getCanonicalName())) {
|
||||
order++;
|
||||
List<ApiMethodDoc> apiMethodDocs = buildControllerMethod(cls);
|
||||
ApiDoc apiDoc = new ApiDoc();
|
||||
apiDoc.setDesc(cls.getComment());
|
||||
apiDoc.setOrder(order);
|
||||
apiDoc.setName(controllerName);
|
||||
apiDoc.setAlias(controllerName);
|
||||
this.handControllerAlias(apiDoc);
|
||||
apiDoc.setDesc(cls.getComment());
|
||||
apiDoc.setList(apiMethodDocs);
|
||||
apiDocList.add(apiDoc);
|
||||
}
|
||||
} else {
|
||||
order++;
|
||||
List<ApiMethodDoc> apiMethodDocs = buildControllerMethod(cls);
|
||||
ApiDoc apiDoc = new ApiDoc();
|
||||
apiDoc.setOrder(order);
|
||||
apiDoc.setAlias(MD6Util.md6(controllerName));
|
||||
apiDoc.setName(controllerName);
|
||||
apiDoc.setAlias(controllerName);
|
||||
this.handControllerAlias(apiDoc);
|
||||
apiDoc.setDesc(cls.getComment());
|
||||
apiDoc.setList(apiMethodDocs);
|
||||
apiDocList.add(apiDoc);
|
||||
|
@ -215,11 +224,14 @@ public class SourceBuilder {
|
|||
}
|
||||
List<JavaMethod> methods = cls.getMethods();
|
||||
List<ApiMethodDoc> methodDocList = new ArrayList<>(methods.size());
|
||||
int methodOrder = 0;
|
||||
for (JavaMethod method : methods) {
|
||||
if (StringUtil.isEmpty(method.getComment()) && isStrict) {
|
||||
throw new RuntimeException("Unable to find comment for method " + method.getName() + " in " + cls.getCanonicalName());
|
||||
}
|
||||
methodOrder++;
|
||||
ApiMethodDoc apiMethodDoc = new ApiMethodDoc();
|
||||
apiMethodDoc.setOrder(methodOrder);
|
||||
apiMethodDoc.setDesc(method.getComment());
|
||||
List<JavaAnnotation> annotations = method.getAnnotations();
|
||||
String url = null;
|
||||
|
@ -644,7 +656,7 @@ public class SourceBuilder {
|
|||
}
|
||||
}
|
||||
if (DocClassUtil.isPrimitive(typeName)) {
|
||||
return DocUtil.jsonValueByType(typeName);
|
||||
return DocUtil.jsonValueByType(typeName).replace("\"", "");
|
||||
}
|
||||
StringBuilder data0 = new StringBuilder();
|
||||
JavaClass cls = builder.getClassByName(typeName);
|
||||
|
@ -1102,4 +1114,22 @@ public class SourceBuilder {
|
|||
}
|
||||
return fieldList;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle controller name
|
||||
*
|
||||
* @param apiDoc ApiDoc
|
||||
*/
|
||||
private void handControllerAlias(ApiDoc apiDoc) {
|
||||
if (null != aesInfo && StringUtil.isNotEmpty(aesInfo.getKey())
|
||||
&& StringUtil.isNotEmpty(aesInfo.getVector())) {
|
||||
String name = AESUtil.encodeByCBC(apiDoc.getName(), aesInfo.getKey(), aesInfo.getVector());
|
||||
int length = name.length();
|
||||
if (name.length() < 32) {
|
||||
apiDoc.setAlias(name);
|
||||
} else {
|
||||
apiDoc.setAlias(name.substring(length - 32, length));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,22 @@ package com.power.doc.constants;
|
|||
public class GlobalConstants {
|
||||
|
||||
public static final String FILE_SEPARATOR = System.getProperty("file.separator");
|
||||
|
||||
public static final String DOC_LANGUAGE = "smart-doc_language";
|
||||
|
||||
public static final String API_DOC_TPL = "ApiDoc.btl";
|
||||
|
||||
public static final String HTML_API_DOC_TPL = "HtmlApiDoc.btl";
|
||||
|
||||
public static final String ERROR_CODE_LIST_TPL = "ErrorCodeList.btl";
|
||||
|
||||
public static final String ERROR_CODE_LIST_MD = "ErrorCodeList.md";
|
||||
|
||||
public static final String INDEX_TPL = "Index.btl";
|
||||
|
||||
public static final String INDEX_CSS_TPL = "index.css";
|
||||
|
||||
public static final String MARKDOWN_CSS_TPL = "markdown.css";
|
||||
/**
|
||||
* controller注解全名称
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package com.power.doc.constants;
|
||||
|
||||
/**
|
||||
* 语言支持
|
||||
* @author yu 2019/9/21.
|
||||
*/
|
||||
public enum Language {
|
||||
ENGLISH("en-US"),
|
||||
CHINESE("zh-CN");
|
||||
|
||||
public String code;
|
||||
|
||||
Language(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getCode(){
|
||||
return this.code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.power.doc.constants;
|
||||
|
||||
/**
|
||||
* @author yu 2019/9/21.
|
||||
*/
|
||||
public enum TemplateVariable {
|
||||
DESC("desc"),
|
||||
NAME("name"),
|
||||
LIST("list"),
|
||||
API_DOC_LIST("apiDocList"),
|
||||
ERROR_CODE_LIST("errorCodeList"),
|
||||
VERSION_LIST("revisionLogList"),
|
||||
HOME_PAGE("homePage"),
|
||||
HTML("html"),
|
||||
TITLE("title"),
|
||||
ERROR_LIST_TITLE("errorListTitle"),
|
||||
CREATE_TIME("createTime");
|
||||
|
||||
|
||||
|
||||
private String variable;
|
||||
|
||||
TemplateVariable(String variable) {
|
||||
this.variable = variable;
|
||||
}
|
||||
|
||||
public String getVariable(){
|
||||
return this.variable;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.power.doc.model;
|
||||
|
||||
/**
|
||||
* aes加密信息
|
||||
* @since 1.7+
|
||||
* @author yu 2019/9/21.
|
||||
*/
|
||||
public class AesInfo {
|
||||
|
||||
/**
|
||||
* aes加密key
|
||||
*/
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 加密初始向量
|
||||
*/
|
||||
private String vector;
|
||||
|
||||
public static AesInfo create() {
|
||||
return new AesInfo();
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public AesInfo setKey(String key) {
|
||||
this.key = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getVector() {
|
||||
return vector;
|
||||
}
|
||||
|
||||
public AesInfo setVector(String vector) {
|
||||
this.vector = vector;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.power.doc.model;
|
||||
|
||||
import com.power.common.util.CollectionUtil;
|
||||
import com.power.doc.constants.Language;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -66,6 +67,19 @@ public class ApiConfig {
|
|||
*/
|
||||
private List<RevisionLog> revisionLogs;
|
||||
|
||||
/**
|
||||
* @since 1.7+
|
||||
* aes加密信息
|
||||
*/
|
||||
private AesInfo aesInfo;
|
||||
|
||||
/**
|
||||
* 语言
|
||||
* @since 1.7+
|
||||
*/
|
||||
private Language language;
|
||||
|
||||
|
||||
public String getServerUrl() {
|
||||
return serverUrl;
|
||||
}
|
||||
|
@ -147,4 +161,19 @@ public class ApiConfig {
|
|||
this.revisionLogs = CollectionUtil.asList(revisionLogs);
|
||||
}
|
||||
|
||||
public AesInfo getAesInfo() {
|
||||
return aesInfo;
|
||||
}
|
||||
|
||||
public void setAesInfo(AesInfo aesInfo) {
|
||||
this.aesInfo = aesInfo;
|
||||
}
|
||||
|
||||
public Language getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(Language language) {
|
||||
this.language = language;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,23 @@ import java.util.List;
|
|||
|
||||
public class ApiDoc {
|
||||
|
||||
/**
|
||||
* @since 1.7+
|
||||
* 文档顺序
|
||||
*/
|
||||
public int order;
|
||||
|
||||
/**
|
||||
* 类名
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* @since 1.7+
|
||||
* md5加密后的文件名(用于处理html)
|
||||
*/
|
||||
private String alias;
|
||||
|
||||
/**
|
||||
* 方法文档列表
|
||||
*/
|
||||
|
@ -44,5 +55,19 @@ public class ApiDoc {
|
|||
this.desc = desc;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
public void setAlias(String alias) {
|
||||
this.alias = alias;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@ import java.io.Serializable;
|
|||
*/
|
||||
public class ApiMethodDoc implements Serializable {
|
||||
|
||||
/**
|
||||
* @since 1.7+
|
||||
*/
|
||||
private int order;
|
||||
|
||||
private String desc;
|
||||
|
||||
private String url;
|
||||
|
@ -97,4 +102,12 @@ public class ApiMethodDoc implements Serializable {
|
|||
public void setHeaders(String headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,18 @@ public class ApiReqHeader {
|
|||
*/
|
||||
private String desc;
|
||||
|
||||
/**
|
||||
* @since 1.7.0
|
||||
* 请求有是否必须
|
||||
*/
|
||||
private boolean required;
|
||||
|
||||
/**
|
||||
* @since 1.7.0
|
||||
* 起始版本
|
||||
*/
|
||||
private String since = "-";
|
||||
|
||||
public static ApiReqHeader header() {
|
||||
return new ApiReqHeader();
|
||||
}
|
||||
|
@ -52,4 +64,22 @@ public class ApiReqHeader {
|
|||
this.desc = desc;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isRequired() {
|
||||
return required;
|
||||
}
|
||||
|
||||
public ApiReqHeader setRequired(boolean required) {
|
||||
this.required = required;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSince() {
|
||||
return since;
|
||||
}
|
||||
|
||||
public ApiReqHeader setSince(String since) {
|
||||
this.since = since;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.power.common.util.DateTimeUtil;
|
|||
import com.power.common.util.IDCardUtil;
|
||||
import com.power.common.util.RandomUtil;
|
||||
import com.power.common.util.StringUtil;
|
||||
import com.power.doc.constants.GlobalConstants;
|
||||
import com.thoughtworks.qdox.model.JavaAnnotation;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -17,7 +18,7 @@ import java.util.*;
|
|||
*/
|
||||
public class DocUtil {
|
||||
|
||||
private static Faker faker = new Faker(new Locale("zh-CN"));
|
||||
private static Faker faker = new Faker(new Locale(System.getProperty(GlobalConstants.DOC_LANGUAGE)));
|
||||
|
||||
private static Faker enFaker = new Faker(new Locale("en-US"));
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package com.power.doc.utils;
|
||||
|
||||
import com.vladsch.flexmark.ext.tables.TablesExtension;
|
||||
import com.vladsch.flexmark.html.HtmlRenderer;
|
||||
import com.vladsch.flexmark.parser.Parser;
|
||||
import com.vladsch.flexmark.parser.ParserEmulationProfile;
|
||||
import com.vladsch.flexmark.util.ast.Node;
|
||||
import com.vladsch.flexmark.util.data.MutableDataSet;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @since 1.7+
|
||||
* @author yu 2019/9/21.
|
||||
*/
|
||||
public class MarkDownUtil {
|
||||
|
||||
/**
|
||||
* markdown to html
|
||||
*
|
||||
* @param content markdown contents
|
||||
* @return parse html contents
|
||||
*/
|
||||
public static String toHtml(String content) {
|
||||
MutableDataSet options = new MutableDataSet();
|
||||
options.setFrom(ParserEmulationProfile.MARKDOWN);
|
||||
// enable table parse!
|
||||
options.set(Parser.EXTENSIONS, Arrays.asList(TablesExtension.create()));
|
||||
|
||||
Parser parser = Parser.builder(options).build();
|
||||
HtmlRenderer renderer = HtmlRenderer.builder(options).build();
|
||||
|
||||
Node document = parser.parse(content);
|
||||
return renderer.render(document);
|
||||
}
|
||||
|
||||
}
|
|
@ -27,16 +27,16 @@ for(doc in api.list){
|
|||
<%if(isNotEmpty(doc.headers)){%>
|
||||
**Request-headers:**
|
||||
|
||||
Name | Type|Description
|
||||
---|---|---
|
||||
Header | Type|Description|Required|Since
|
||||
---|---|---|---|----
|
||||
${doc.headers}
|
||||
<%}%>
|
||||
|
||||
<%if(isNotEmpty(doc.requestParams)){%>
|
||||
**Request-parameters:**
|
||||
|
||||
Parameter | Type|Description|Required
|
||||
---|---|---|---
|
||||
Parameter | Type|Description|Required|Since
|
||||
---|---|---|---|---
|
||||
${doc.requestParams}
|
||||
<%}%>
|
||||
|
||||
|
@ -49,8 +49,8 @@ ${doc.requestUsage}
|
|||
<%if(isNotEmpty(doc.responseParams)){%>
|
||||
**Response-fields:**
|
||||
|
||||
Field | Type|Description
|
||||
---|---|---
|
||||
Field | Type|Description|Since
|
||||
---|---|---|---
|
||||
${doc.responseParams}
|
||||
<%}%>
|
||||
|
||||
|
|
|
@ -4,17 +4,17 @@
|
|||
for(doc in list){
|
||||
%>
|
||||
## ${doc.desc}
|
||||
**URL:** ${doc.url}
|
||||
**URL:** `${doc.url}`
|
||||
|
||||
**Type:** ${doc.type}
|
||||
**Type:** `${doc.type}`
|
||||
|
||||
**Content-Type:** ${doc.contentType}
|
||||
**Content-Type:** `${doc.contentType}`
|
||||
|
||||
<%if(isNotEmpty(doc.headers)){%>
|
||||
**Request-headers:**
|
||||
|
||||
Name | Type|Description
|
||||
---|---|---
|
||||
Header | Type|Description|Required|Since
|
||||
---|---|---|---|----
|
||||
${doc.headers}
|
||||
<%}%>
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width initial-scale=1'>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<link rel="stylesheet" href="markdown.css"/>
|
||||
<title>${title}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="markdown-body">
|
||||
${html}
|
||||
<footer class="page-footer">
|
||||
<span class="copyright">Generated by smart-doc at ${createTime}</span>
|
||||
<span class="footer-modification">Suggestions, contact, support and error reporting on
|
||||
<a href="https://gitee.com/sunyurepository/smart-doc" target="_blank">Gitee</a> or
|
||||
<a href="https://github.com/shalousun/smart-doc" target="_blank">Github</a>
|
||||
</span>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -3,38 +3,45 @@
|
|||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width initial-scale=1'>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<link rel="stylesheet" href="index.css"/>
|
||||
<title>api doc</title>
|
||||
</head>
|
||||
<div class="book without-animation with-summary font-size-2 font-family-1">
|
||||
<div class="book-summary">
|
||||
<div id="book-search-input"><input type="text" placeholder="Type to search"></div>
|
||||
<nav role="navigation">
|
||||
<ul class="summary">
|
||||
<li><a href="${home}.html" target="_blank" class="custom-link">Home</a></li>
|
||||
<li><ul id="reference">API Reference</ul></li>
|
||||
<li class="divider"></li>
|
||||
<%
|
||||
for(api in apiDocList){
|
||||
%>
|
||||
<li class="chapter " data-level="${api.name}" data-path="${api.name}.html">
|
||||
<a href="${api.name}.html" target="book_iframe">${api.desc}</a>
|
||||
<li class="chapter " data-level="${api.alias}" data-path="${api.alias}.html">
|
||||
<a href="${api.alias}.html" target="book_iframe">${api.order}. ${api.desc}</a>
|
||||
<ul class="articles">
|
||||
<%
|
||||
for(doc in api.list){
|
||||
%>
|
||||
<li class="chapter " data-level="${api.name}" data-path="${api.name}.html">
|
||||
<a href="${api.name}.html" target="book_frame">${doc.desc}</a></li>
|
||||
<li class="chapter " data-level="${api.alias}" data-path="${api.alias}.html">
|
||||
<a href="${api.alias}.html" target="book_iframe">${api.order}.${doc.order} ${doc.desc}</a></li>
|
||||
<%}%>
|
||||
</ul>
|
||||
</li>
|
||||
<%}%>
|
||||
<li class="chapter " data-level="error_code" data-path="error_code.html">
|
||||
<a href="error_code.html" target="book_iframe">${errorListTitle}</a>
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="https://www.gitbook.com" target="blank" class="gitbook-link">Published with GitBook</a>
|
||||
<li class="footer_link"><a href="https://github.com/shalousun/smart-doc" target="blank" class="gitbook-link">Created by smart-doc</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div id="book-body" class="book-body" height="100%">
|
||||
<iframe src="TestControllerApi.html" frameborder="0" id="book_iframe" name="book_frame" width="100%"></iframe>
|
||||
<iframe src="${homePage}.html" frameborder="0" id="book_iframe" name="book_iframe" width="100%"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
@ -43,6 +50,7 @@
|
|||
ifm.height = document.documentElement.clientHeight
|
||||
}
|
||||
changeFrameHeight();
|
||||
setInterval(function(){changeFrameHeight(); }, 500);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1 +1,228 @@
|
|||
.book-summary{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;position:absolute;top:0;left:-300px;bottom:0;z-index:1;overflow-y:auto;width:300px;color:#364149;background:#fafafa;border-right:1px solid rgba(0,0,0,.07);-webkit-transition:left 250ms ease;-moz-transition:left 250ms ease;-o-transition:left 250ms ease;transition:left 250ms ease}.book-summary ul.summary{list-style:none;margin:0;padding:0;-webkit-transition:top .5s ease;-moz-transition:top .5s ease;-o-transition:top .5s ease;transition:top .5s ease}.book-summary ul.summary li{list-style:none}.book-summary ul.summary li.header{padding:10px 15px;padding-top:20px;text-transform:uppercase;color:#939da3}.book-summary ul.summary li.divider{height:1px;margin:7px 0;overflow:hidden;background:rgba(0,0,0,.07)}.book-summary ul.summary li i.fa-check{display:none;position:absolute;right:9px;top:16px;font-size:9px;color:#3c3}.book-summary ul.summary li.done>a{color:#364149;font-weight:400}.book-summary ul.summary li.done>a i{display:inline}.book-summary ul.summary li a,.book-summary ul.summary li span{display:block;padding:10px 15px;border-bottom:0;color:#364149;background:0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;position:relative}.book-summary ul.summary li a:hover{text-decoration:underline}.book-summary ul.summary li a:focus{outline:0}.book-summary ul.summary li.active>a{color:#008cff;background:0;text-decoration:none}.book-summary ul.summary li ul{padding-left:20px}@media(max-width:600px){.book-summary{width:calc(100% - 60px);bottom:0;left:-100%}}.book.with-summary .book-summary{left:0}.book.without-animation .book-summary{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.book{position:relative;width:100%;height:100%}@media(min-width:600px){.book.with-summary .book-body{left:300px}}@media(max-width:600px){.book.with-summary{overflow:hidden}.book.with-summary .book-body{-webkit-transform:translate(calc(100% - 60px),0);-moz-transform:translate(calc(100% - 60px),0);-ms-transform:translate(calc(100% - 60px),0);-o-transform:translate(calc(100% - 60px),0);transform:translate(calc(100% - 60px),0)}}.book.without-animation .book-body{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.book-body{position:absolute;top:0;right:0;left:0;bottom:0;overflow-y:auto;color:#000;background:#fff;-webkit-transition:left 250ms ease;-moz-transition:left 250ms ease;-o-transition:left 250ms ease;transition:left 250ms ease}@media(max-width:1240px){.book-body{-webkit-transition:-webkit-transform 250ms ease;-moz-transition:-moz-transform 250ms ease;-o-transition:-o-transform 250ms ease;transition:transform 250ms ease;padding-bottom:20px}}#book-search-input{padding:6px;background:0;transition:top .5s ease;border-bottom:1px solid rgba(0,0,0,.07);border-top:1px solid rgba(0,0,0,.07);margin-bottom:10px;margin-top:-1px}#book-search-input input,#book-search-input input:focus,#book-search-input input:hover{width:100%;background:0;border:1px solid transparent;box-shadow:none;outline:0;line-height:22px;padding:7px 7px;color:inherit}a{text-decoration:none}body,html{height:100%}html{font-size:62.5%}body{margin:0}body{text-rendering:optimizeLegibility;font-smoothing:antialiased;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:.2px;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
|
||||
.book-summary {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -300px;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
overflow-y: auto;
|
||||
width: 300px;
|
||||
color: #364149;
|
||||
background: #fafafa;
|
||||
border-right: 1px solid rgba(0, 0, 0, .07);
|
||||
-webkit-transition: left 250ms ease;
|
||||
-moz-transition: left 250ms ease;
|
||||
-o-transition: left 250ms ease;
|
||||
transition: left 250ms ease
|
||||
}
|
||||
|
||||
.book-summary ul.summary {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-webkit-transition: top .5s ease;
|
||||
-moz-transition: top .5s ease;
|
||||
-o-transition: top .5s ease;
|
||||
transition: top .5s ease
|
||||
}
|
||||
|
||||
.book-summary ul.summary li {
|
||||
list-style: none
|
||||
}
|
||||
|
||||
.book-summary ul.summary li.header {
|
||||
padding: 10px 15px;
|
||||
padding-top: 20px;
|
||||
text-transform: uppercase;
|
||||
color: #939da3
|
||||
}
|
||||
|
||||
.book-summary ul.summary li.divider {
|
||||
height: 1px;
|
||||
margin: 7px 0;
|
||||
overflow: hidden;
|
||||
background: rgba(0, 0, 0, .07)
|
||||
}
|
||||
|
||||
.book-summary ul.summary li i.fa-check {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 9px;
|
||||
top: 16px;
|
||||
font-size: 9px;
|
||||
color: #3c3
|
||||
}
|
||||
|
||||
.book-summary ul.summary li.done > a {
|
||||
color: #364149;
|
||||
font-weight: 400
|
||||
}
|
||||
|
||||
.book-summary ul.summary li.done > a i {
|
||||
display: inline
|
||||
}
|
||||
|
||||
.book-summary ul.summary li a, .book-summary ul.summary li span {
|
||||
display: block;
|
||||
padding: 10px 15px;
|
||||
border-bottom: 0;
|
||||
color: #364149;
|
||||
background: 0;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.book-summary ul.summary li a:hover {
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
.book-summary ul.summary li a:focus {
|
||||
outline: 0
|
||||
}
|
||||
|
||||
.book-summary ul.summary li.active > a {
|
||||
color: #008cff;
|
||||
background: 0;
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.book-summary ul.summary li ul {
|
||||
padding-left: 20px
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.book-summary {
|
||||
width: calc(100% - 60px);
|
||||
bottom: 0;
|
||||
left: -100%
|
||||
}
|
||||
}
|
||||
|
||||
.book.with-summary .book-summary {
|
||||
left: 0
|
||||
}
|
||||
|
||||
.book.without-animation .book-summary {
|
||||
-webkit-transition: none !important;
|
||||
-moz-transition: none !important;
|
||||
-o-transition: none !important;
|
||||
transition: none !important
|
||||
}
|
||||
|
||||
.book {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%
|
||||
}
|
||||
|
||||
@media (min-width: 600px) {
|
||||
.book.with-summary .book-body {
|
||||
left: 300px
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.book.with-summary {
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.book.with-summary .book-body {
|
||||
-webkit-transform: translate(calc(100% - 60px), 0);
|
||||
-moz-transform: translate(calc(100% - 60px), 0);
|
||||
-ms-transform: translate(calc(100% - 60px), 0);
|
||||
-o-transform: translate(calc(100% - 60px), 0);
|
||||
transform: translate(calc(100% - 60px), 0)
|
||||
}
|
||||
}
|
||||
|
||||
.book.without-animation .book-body {
|
||||
-webkit-transition: none !important;
|
||||
-moz-transition: none !important;
|
||||
-o-transition: none !important;
|
||||
transition: none !important
|
||||
}
|
||||
|
||||
.book-body {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
overflow-y: auto;
|
||||
color: #000;
|
||||
background: #fff;
|
||||
-webkit-transition: left 250ms ease;
|
||||
-moz-transition: left 250ms ease;
|
||||
-o-transition: left 250ms ease;
|
||||
transition: left 250ms ease
|
||||
}
|
||||
|
||||
@media (max-width: 1240px) {
|
||||
.book-body {
|
||||
-webkit-transition: -webkit-transform 250ms ease;
|
||||
-moz-transition: -moz-transform 250ms ease;
|
||||
-o-transition: -o-transform 250ms ease;
|
||||
transition: transform 250ms ease;
|
||||
padding-bottom: 20px
|
||||
}
|
||||
}
|
||||
|
||||
#book-search-input {
|
||||
padding: 6px;
|
||||
background: 0;
|
||||
transition: top .5s ease;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .07);
|
||||
border-top: 1px solid rgba(0, 0, 0, .07);
|
||||
margin-bottom: 10px;
|
||||
margin-top: -1px
|
||||
}
|
||||
|
||||
#book-search-input input, #book-search-input input:focus, #book-search-input input:hover {
|
||||
width: 100%;
|
||||
background: 0;
|
||||
border: 1px solid transparent;
|
||||
box-shadow: none;
|
||||
outline: 0;
|
||||
line-height: 22px;
|
||||
padding: 7px 7px;
|
||||
color: inherit
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
body, html {
|
||||
height: 100%
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 62.5%
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0
|
||||
}
|
||||
|
||||
body {
|
||||
text-rendering: optimizeLegibility;
|
||||
font-smoothing: antialiased;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
letter-spacing: .2px;
|
||||
text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%
|
||||
}
|
||||
|
||||
#reference {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.footer_link {
|
||||
margin-bottom: 45px;
|
||||
}
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue