main
HuangHai 3 months ago
parent 7168be9b55
commit 9cd5d1a65d

@ -56,6 +56,13 @@
<version>${minio.version}</version>
</dependency>
<!-- JApiDocs -->
<dependency>
<groupId>io.github.yedaxia</groupId>
<artifactId>japidocs</artifactId>
<version>1.4.4</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>

@ -14,6 +14,7 @@ import com.dsideal.base.Util.CommonUtil;
import com.dsideal.base.Util.ExcelCommonUtil;
import com.dsideal.base.Util.FileUtil;
import com.dsideal.base.Interceptor.*;
import io.github.yedaxia.apidocs.ApiDoc;
import net.sf.json.JSONArray;
import org.apache.commons.lang.StringUtils;
@ -21,6 +22,7 @@ import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
@ApiDoc
public class BaseController extends Controller {
//实例化model
BaseModel model = new BaseModel();

@ -0,0 +1,194 @@
package com.dsideal.base;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dsideal.base.Plugin.PostmanDocPlugin;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.ext.interceptor.GET;
import com.jfinal.ext.interceptor.POST;
import com.jfinal.kit.PropKit;
import io.github.yedaxia.apidocs.DocContext;
import io.github.yedaxia.apidocs.Docs;
import io.github.yedaxia.apidocs.DocsConfig;
import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* JApiDocs API
* <p>
* https://github.com/YeDaxia/JApiDocs
* https://japidocs.agilestudio.cn/#/zh-cn/
*
* @author zxd 2022-02-17
*/
public class JApiDocsGenerator {
private static String getHttpType(Before before) {
if (before.value().length > 0) {
for (Class<?> interceptClass : before.value()) {
if (interceptClass.equals(GET.class)) {
return "GET";
} else if (interceptClass.equals(POST.class)) {
return "POST";
}
}
}
return "UNKNOWN";
}
/**
* JAVA
* @param directory
* @return Java
*/
public static List<File> findJavaFiles(File directory) {
List<File> javaFiles = new ArrayList<>();
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
javaFiles.addAll(findJavaFiles(file)); // 递归遍历子目录
} else if (file.getName().endsWith(".java")) {
javaFiles.add(file); // 添加Java文件
}
}
}
return javaFiles;
}
/**
* Controller
*
* @param sourceJava JAVA
* @return Controller
*/
public static Map<String, String> getControllMap(String sourceJava) {
Map<String, String> res = new HashMap<>();
List<File> 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
* <p>
* 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
* <p>
* DocController@ApiDoc
* <p>
* https://japidocs.agilestudio.cn/#/zh-cn/
*/
public static void main(String[] args) {
PropKit.use("application_dev.properties");
//可以限制只生成哪个接口,数组内容为空,则表示生成全部
String[] generateInterfacesList = {};
//String[] generateInterfacesList = {"getImportTemplate","uploadExcel"};
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<String, String> 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<String> _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处理完成");
}
}

@ -8,9 +8,6 @@ import com.dsideal.base.Util.CommonUtil;
import com.dsideal.base.Menu.Model.MenuModel;
import com.dsideal.base.Util.JwtUtil;
import com.dsideal.base.Util.RetKit;
import com.dsideal.base.fay.tree.domain.MenuBean;
import com.dsideal.base.fay.tree.service.IFayTreeNode;
import com.dsideal.base.fay.tree.util.FayTreeUtil;
import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.ext.interceptor.GET;
@ -102,47 +99,7 @@ public class MenuController extends Controller {
renderJson(CommonUtil.renderJsonForLayUI(dt, dt.size()));
}
/**
*
*
* 2018-12-22
*/
@Before({GET.class})
public void selectMenuByPerson() {
//当前登录的人员
int identity_id = Integer.parseInt(getCookie("identity_id").trim());
String person_id = getCookie("person_id").trim();
//获取单位管理员菜单
if (identity_id < 5) { //1,2,3,4
Page<Record> page = model.selectBureauMenuByPersonId(identity_id, person_id);
List<IFayTreeNode> list = new ArrayList<>();
for (int i = 0; i < page.getList().size(); i++) {
Record r = page.getList().get(i);
MenuBean m = new MenuBean(r.getStr("menu_id"), r.getStr("parent_id"), r.getStr("menu_name"),
r.getStr("url"), r.getStr("type"));
list.add(m);
}
Object data = FayTreeUtil.getTreeInJsonObject(list);
//如果是超级管理员,那么应该有配置菜单的功能返回,或者默认就必须有这个返回
Kv kv = Kv.by("success", true);
kv.set("data", data);
renderJson(kv);
return;
}
//5,6 角色,就是教师,学生
List<Record> menu_list = model.selectMenuByPersonId(person_id);
List<IFayTreeNode> list = new ArrayList<>();
for (int i = 0; i < menu_list.size(); i++) {
Record r = menu_list.get(i);
MenuBean m = new MenuBean(r.getStr("menu_id"), r.getStr("parent_id"), r.getStr("menu_name"),
r.getStr("url"), r.getStr("type"));
list.add(m);
}
Object data = FayTreeUtil.getTreeInJsonObject(list);
Kv kv = Kv.by("success", true);
kv.set("data", data);
renderJson(kv);
}
/**
*

@ -0,0 +1,48 @@
package com.dsideal.base.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<ControllerNode> 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<String, Object> 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");
}
}

@ -1,80 +0,0 @@
package com.dsideal.base.fay.tree.domain;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.annotation.JSONField;
import com.dsideal.base.fay.tree.service.IFayTreeNode;
public class FayTreeNode {
@JSONField(ordinal=1)
private String nodeId;
@JSONField(ordinal=3)
private String parentNodeId;
private FayTreeNode parent;
private IFayTreeNode treeObject;
@JSONField(ordinal=6)
private List<FayTreeNode> children = new ArrayList<FayTreeNode>();
private List<FayTreeNode> allChildren = new ArrayList<FayTreeNode>();
public FayTreeNode(IFayTreeNode obj){
this.nodeId = obj.getNodeId();
this.parentNodeId = obj.getNodeParentId();
this.treeObject = obj;
}
public void addChild(FayTreeNode treeNode){
this.children.add(treeNode);
}
public void removeChild(FayTreeNode treeNode){
this.children.remove(treeNode);
}
public String getNodeId() {
return nodeId;
}
public void setNodeId(String nodeId) {
this.nodeId = nodeId;
}
public String getParentNodeId() {
return parentNodeId;
}
public void setParentNodeId(String parentNodeId) {
this.parentNodeId = parentNodeId;
}
public FayTreeNode getParent() {
return parent;
}
public void setParent(FayTreeNode parent) {
this.parent = parent;
}
public List<FayTreeNode> getChildren() {
if(children == null || children.isEmpty()) return null;
return children;
}
public void setChildren(List<FayTreeNode> children) {
this.children = children;
}
public IFayTreeNode getTreeObject() {
return treeObject;
}
public void setTreeObject(IFayTreeNode treeObject) {
this.treeObject = treeObject;
}
public List<FayTreeNode> getAllChildren() {
if(this.allChildren.isEmpty()){
for(FayTreeNode treeNode : this.children){
this.allChildren.add(treeNode);
this.allChildren.addAll(treeNode.getAllChildren());
}
}
return this.allChildren;
}
}

@ -1,69 +0,0 @@
package com.dsideal.base.fay.tree.domain;
import com.dsideal.base.fay.tree.service.IFayTreeNode;
public class MenuBean implements IFayTreeNode {
private String menu_id;
private String parentId;
private String menu_name;
private String url;
private String memo;
public MenuBean(String menu_id, String parentId, String menu_name, String url, String type) {
this.menu_id = menu_id;
this.parentId = parentId;
this.menu_name = menu_name;
this.url = url;
this.memo = type;
}
@Override
public String getNodeId() {
return this.menu_id;
}
@Override
public String getNodeParentId() {
return this.parentId;
}
public String getMenu_id() {
return menu_id;
}
public void setMenu_id(String menu_id) {
this.menu_id = menu_id;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getMenu_name() {
return menu_name;
}
public void setMenu_name(String menu_name) {
this.menu_name = menu_name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
}

@ -1,11 +0,0 @@
package com.dsideal.base.fay.tree.service;
import java.util.List;
import com.dsideal.base.fay.tree.domain.FayTreeNode;
public interface IFayTree {
List<FayTreeNode> getTree();
List<FayTreeNode> getRoot();
FayTreeNode getFayTreeNode(String nodeId);
}

@ -1,6 +0,0 @@
package com.dsideal.base.fay.tree.service;
public interface IFayTreeNode {
String getNodeId();
String getNodeParentId();
}

@ -1,84 +0,0 @@
package com.dsideal.base.fay.tree.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import com.dsideal.base.fay.tree.domain.FayTreeNode;
import com.dsideal.base.fay.tree.service.IFayTree;
import com.dsideal.base.fay.tree.service.IFayTreeNode;
public class FayTree implements IFayTree {
private HashMap<String, FayTreeNode> treeNodesMap = new LinkedHashMap<String, FayTreeNode>();
private List<FayTreeNode> treeNodesList = new ArrayList<FayTreeNode>();
public FayTree(List<IFayTreeNode> list){
initTreeNodeMap(list);
initTreeNodeList();
}
private void initTreeNodeMap(List<IFayTreeNode> list){
FayTreeNode treeNode = null;
for(IFayTreeNode item : list){
treeNode = new FayTreeNode(item);
treeNodesMap.put(treeNode.getNodeId(), treeNode);
}
Iterator<FayTreeNode> iter = treeNodesMap.values().iterator();
FayTreeNode parentTreeNode = null;
while(iter.hasNext()){
treeNode = iter.next();
if(treeNode.getParentNodeId() == null || treeNode.getParentNodeId() == ""){
continue;
}
parentTreeNode = treeNodesMap.get(treeNode.getParentNodeId());
if(parentTreeNode != null){
treeNode.setParent(parentTreeNode);
parentTreeNode.addChild(treeNode);
}
}
}
private void initTreeNodeList(){
if(treeNodesList.size() > 0){
return;
}
if(treeNodesMap.size() == 0){
return;
}
Iterator<FayTreeNode> iter = treeNodesMap.values().iterator();
FayTreeNode treeNode = null;
while(iter.hasNext()){
treeNode = iter.next();
if(treeNode.getParent() == null){
this.treeNodesList.add(treeNode);
this.treeNodesList.addAll(treeNode.getAllChildren());
}
}
}
@Override
public List<FayTreeNode> getTree() {
return this.treeNodesList;
}
@Override
public List<FayTreeNode> getRoot() {
List<FayTreeNode> rootList = new ArrayList<FayTreeNode>();
if (this.treeNodesList.size() > 0) {
for (FayTreeNode node : treeNodesList) {
if (node.getParent() == null)
rootList.add(node);
}
}
return rootList;
}
@Override
public FayTreeNode getFayTreeNode(String nodeId) {
return this.treeNodesMap.get(nodeId);
}
}

@ -1,27 +0,0 @@
package com.dsideal.base.fay.tree.util;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.dsideal.base.fay.tree.service.IFayTreeNode;
import com.dsideal.base.fay.tree.service.impl.FayTree;
public class FayTreeUtil {
public static Object getTreeInJsonObject(List<? extends IFayTreeNode> list){
if(list == null || list.isEmpty()){
return new ArrayList<>();
}
FayTree tree = new FayTree(new ArrayList<>(list));
SimplePropertyPreFilter filter = new SimplePropertyPreFilter(); // 构造方法里,也可以直接传需要序列化的属性名字
filter.getExcludes().add("parent");
filter.getExcludes().add("allChildren");
filter.getExcludes().add("parentNodeId");
filter.getExcludes().add("nodeId");
String treeJsonString = JSONObject.toJSONString(tree.getRoot(), filter);
Object data = JSONObject.parse(treeJsonString);
return data;
}
}
Loading…
Cancel
Save