files = findJavaFiles(new File(sourceJava));
+ for (File file : files) {
+ String className = file.getAbsolutePath().replace("\\", "/").replace(sourceJava + "/", "");
+ className = className.replace("/", ".");
+ className = className.replace(".java", "");
+ try {
+ // 去掉.class后缀并加载类
+ Class> cls = Class.forName(className);
+ if (Controller.class.isAssignableFrom(cls) && !Modifier.isAbstract(cls.getModifiers())) {
+ // 获取类上的所有方法
+ Method[] methods = cls.getDeclaredMethods();
+ for (Method method : methods) {
+ // 检查方法上是否有@Before注解
+ var before = method.getAnnotation(Before.class);
+ if (before != null) {
+ String httpType = getHttpType(before);
+ res.put(cls.getSimpleName() + "." + method.getName(), httpType);
+ }
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ return res;
+ }
+
+ /**
+ * JApiDocs 生成器
+ * 如果报错,做如下检查:
+ * 1 javadoc @param 后是否有注释
+ * 2 src.main.java 目录中非 .java 扩展名文件的内容要 // 注释起来
+ * 3 删除 config.setDocsPath 目录中的文件,再生成试试
+ *
+ * 如果生成的 api 文档不是预期的,作如下检查:
+ * 1 必须在 configRoute(Routes me) 中已该方式 me.add("/xx/yy", xx.class, "/"); 定义 Controller
+ * 2 在需要生成 api 的 Controller 中添加 @ApiDoc 注解
+ * 3 如果要忽略某 action,在 action 上添加 @Ignore
+ * https://jfinal.com/share/2528
+ *
+ * 在需要生成Doc文档的Controller类上面加上@ApiDoc注解
+ *
+ * https://japidocs.agilestudio.cn/#/zh-cn/
+ */
+ public static void main(String[] args) {
+ //可以限制只生成哪个接口,数组内容为空,则表示生成全部
+ //String[] generateInterfacesList = {"getWxTj"};
+ String[] generateInterfacesList = {};
+ String projectPath = System.getProperty("user.dir");
+ projectPath = projectPath.replace("\\", "/");
+ String projectName = projectPath.substring(projectPath.lastIndexOf("/") + 1);
+ DocsConfig config = new DocsConfig();
+ String sourceJava = projectPath + "/src/main/java";
+ config.setProjectPath(sourceJava); // root project path
+ config.setProjectName(projectName); // project name
+ String version = "v1.0";
+ config.setApiVersion(version); // api version
+ String docPath = projectPath + "/Doc";
+ config.setDocsPath(docPath); // api docs target path
+ config.addPlugin(new PostmanDocPlugin());
+ config.setAutoGenerate(Boolean.FALSE); // auto generate
+ config.setMvcFramework("JFinal");
+ Docs.buildHtmlDocs(config); // execute to generate
+
+ // 获取项目路径
+ Map map = getControllMap(sourceJava);
+ //修正一下 postman 的请求方式
+ String docFileName = String.format("%s-%s-api-docs.json", DocContext.getDocsConfig().getProjectName(), DocContext.getDocsConfig().getApiVersion());
+ String jsonPath = docPath + "/" + version + "/" + docFileName;
+ String jsonContent = FileUtil.readUtf8String(jsonPath);
+ JSONObject jo = JSONObject.parseObject(jsonContent);
+ //第一层item
+ for (Object item : jo.getJSONArray("item")) {
+ JSONObject j2 = (JSONObject) item;
+ //Controller类名
+ String className = j2.getString("name");
+ //第二层item
+ for (Object o : j2.getJSONArray("item")) {
+ JSONObject j3 = (JSONObject) o;
+ JSONObject jRequest = j3.getJSONObject("request");
+ String x = jRequest.getJSONObject("url").getString("raw");
+ x = x.substring(x.lastIndexOf("/") + 1);
+ jRequest.put("method", map.get(className + "." + x));
+ }
+ }
+ //限制只生成哪个接口
+ Set _set = new HashSet<>();
+ Collections.addAll(_set, generateInterfacesList);
+
+ // 获取JSONArray
+ jo = jo.getJSONArray("item").getJSONObject(0);
+ JSONArray jsonArray = jo.getJSONArray("item");
+
+ if (!_set.isEmpty()) {
+ // 遍历JSONArray
+ for (int i = 0; i < jsonArray.size(); i++) {
+ // 获取当前的JSONObject
+ JSONObject obj = jsonArray.getJSONObject(i);
+ JSONObject jRequest = obj.getJSONObject("request");
+ // 检查条件,例如,如果名字不是"John",则删除这个条目
+ String x = jRequest.getJSONObject("url").getString("raw");
+ x = x.substring(x.lastIndexOf("/") + 1);
+ if (!_set.contains(x)) {
+ // 从JSONArray中移除当前条目
+ jsonArray.remove(i);
+ // 由于移除操作会改变数组的长度和索引,所以i需要减1以保持正确的索引位置
+ i--;
+ }
+ }
+ // 将修改后的JSONArray重新设置回JSONObject
+ jo.put("item", jsonArray);
+ }
+ //美化JSON格式化保存
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ String jsonString = gson.toJson(jo);
+ FileUtil.writeUtf8String(jsonString, jsonPath);
+ System.out.println("恭喜,文档JSON处理完成!");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/dsideal/QingLong/Plugin/PostmanDocPlugin.java b/src/main/java/com/dsideal/QingLong/Plugin/PostmanDocPlugin.java
new file mode 100644
index 00000000..999b9c54
--- /dev/null
+++ b/src/main/java/com/dsideal/QingLong/Plugin/PostmanDocPlugin.java
@@ -0,0 +1,48 @@
+package com.dsideal.QingLong.Plugin;
+
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import io.github.yedaxia.apidocs.DocContext;
+import io.github.yedaxia.apidocs.IPluginSupport;
+import io.github.yedaxia.apidocs.Resources;
+import io.github.yedaxia.apidocs.Utils;
+import io.github.yedaxia.apidocs.parser.ControllerNode;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class PostmanDocPlugin implements IPluginSupport {
+ public PostmanDocPlugin() {
+ }
+
+ public void execute(List controllerNodeList) {
+ FileWriter docFileWriter = null;
+
+ try {
+ Template ctrlTemplate = this.getDocTpl();
+
+ String docFileName = String.format("%s-%s-api-docs.json", DocContext.getDocsConfig().getProjectName(), DocContext.getDocsConfig().getApiVersion());
+ File docFile = new File(DocContext.getDocPath(), docFileName);
+ docFileWriter = new FileWriter(docFile);
+ Map data = new HashMap();
+ data.put("controllerNodes", controllerNodeList);
+ data.put("currentApiVersion", DocContext.getCurrentApiVersion());
+ data.put("projectName", DocContext.getDocsConfig().getProjectName());
+ data.put("i18n", DocContext.getI18n());
+ ctrlTemplate.process(data, docFileWriter);
+
+ } catch (IOException | TemplateException var10) {
+ var10.printStackTrace();
+ } finally {
+ Utils.closeSilently(docFileWriter);
+ }
+ }
+
+ private Template getDocTpl() throws IOException {
+ return Resources.getFreemarkerTemplate("postman-doc.json.ftl");
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/postman-doc.json.ftl b/src/main/resources/postman-doc.json.ftl
new file mode 100644
index 00000000..4ce6ceee
--- /dev/null
+++ b/src/main/resources/postman-doc.json.ftl
@@ -0,0 +1,37 @@
+{
+"info": {
+"_postman_id": "",
+"name": "${projectName}",
+"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
+},
+"item": [
+<#list controllerNodes as controller>
+ {
+ "name": "${controller.description}",
+ "item": [
+ <#list controller.requestNodes as reqNode>
+ {
+ "name": "${reqNode.description}",
+ "request": {
+ "url": {
+ "raw": "{{domain}}${reqNode.url}",
+ "query": [
+ <#if reqNode.paramNodes?size != 0>
+ <#list reqNode.paramNodes as paramNode>
+ {
+ "key": "${paramNode.name}",
+ "value": "",
+ "description": "${paramNode.description}"
+ }<#if paramNode_has_next>,#if>
+ #list>
+ #if>
+ ]
+ }
+ }
+ }<#if reqNode_has_next>,#if>
+ #list>
+ ]
+ }<#if controller_has_next>,#if>
+#list>
+]
+}
\ No newline at end of file