|
|
package com.ruoyi;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.collection.ListUtil;
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
import cn.hutool.core.io.resource.ResourceUtil;
|
|
|
import cn.hutool.core.util.ArrayUtil;
|
|
|
import cn.hutool.core.util.ClassUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.ruoyi.common.annotation.Info;
|
|
|
import lombok.Data;
|
|
|
import org.apache.velocity.VelocityContext;
|
|
|
import org.apache.velocity.app.VelocityEngine;
|
|
|
import org.junit.jupiter.api.Disabled;
|
|
|
import org.junit.jupiter.api.DisplayName;
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
import org.springframework.data.annotation.Id;
|
|
|
|
|
|
import java.io.File;
|
|
|
import java.io.StringWriter;
|
|
|
import java.lang.reflect.Field;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.List;
|
|
|
import java.util.Set;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@Info
|
|
|
public class MongoGenerator {
|
|
|
|
|
|
/**
|
|
|
* 输出的类的根包,扫描的实体类为该包下的mongo子包下
|
|
|
*/
|
|
|
private String packageName = "com.ruoyi.jobs";
|
|
|
|
|
|
/**
|
|
|
* 模块名,类的简单名称会先去掉前面的模块名
|
|
|
*/
|
|
|
private String moduleName = "jobs";
|
|
|
|
|
|
@Test
|
|
|
@Disabled
|
|
|
@DisplayName("mongodb代码生成")
|
|
|
public void generate() throws Exception {
|
|
|
|
|
|
List<BaseInfo> entityList = scan(); //所有编写了@Info的实体类
|
|
|
// List<BaseInfo> entityList = scan("JobsTag1");//编写了@Info的实体类中的某些类
|
|
|
|
|
|
System.out.println(new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(entityList));
|
|
|
generate(entityList);
|
|
|
System.out.println("完成");
|
|
|
}
|
|
|
|
|
|
public void generate(List<BaseInfo> entityList) throws Exception {
|
|
|
|
|
|
File[] fs = getOutPath();
|
|
|
|
|
|
/**
|
|
|
* 工程根
|
|
|
*/
|
|
|
File root = fs[0];
|
|
|
/**
|
|
|
* java包根目录
|
|
|
*/
|
|
|
File javaRoot = fs[1];
|
|
|
|
|
|
for (BaseInfo entity : entityList) {
|
|
|
|
|
|
|
|
|
String code = generate("query.vm", entity, entityList);
|
|
|
new File(javaRoot, "mongo/query").mkdirs();
|
|
|
FileUtil.writeString(code, new File(javaRoot, "mongo/query/" + entity.toUpperName() + "Query.java"), "UTF-8");
|
|
|
|
|
|
code = generate("api.vm", entity, entityList);
|
|
|
new File(javaRoot, "api").mkdirs();
|
|
|
FileUtil.writeString(code, new File(javaRoot, "api/" + entity.toUpperName() + "Api.java"), "UTF-8");
|
|
|
|
|
|
|
|
|
code = generate("api.js.vm", entity, entityList);
|
|
|
new File(root, "admin-ui/src/views/" + moduleName + "/api").mkdirs();
|
|
|
FileUtil.writeString(code, new File(root, "admin-ui/src/views/" + moduleName + "/api/" + entity.toSimpleLowerName() + ".js"), "UTF-8");
|
|
|
|
|
|
code = generate("index.vue.vm", entity, entityList);
|
|
|
new File(root, "admin-ui/src/views/" + moduleName + "/" + entity.toSimpleLowerName()).mkdirs();
|
|
|
FileUtil.writeString(code, new File(root, "admin-ui/src/views/" + moduleName + "/" + entity.toSimpleLowerName() + "/index.vue"), "UTF-8");
|
|
|
|
|
|
code = generate("WAdd.vue.vm", entity, entityList);
|
|
|
new File(root, "admin-ui/src/views/" + moduleName + "/" + entity.toSimpleLowerName() + "/components").mkdirs();
|
|
|
FileUtil.writeString(code, new File(root, "admin-ui/src/views/" + moduleName + "/" + entity.toSimpleLowerName() + "/components/WAdd.vue"), "UTF-8");
|
|
|
|
|
|
code = generate("WEdit.vue.vm", entity, entityList);
|
|
|
FileUtil.writeString(code, new File(root, "admin-ui/src/views/" + moduleName + "/" + entity.toSimpleLowerName() + "/components/WEdit.vue"), "UTF-8");
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
String code = generate("sql.vm", null, entityList);
|
|
|
FileUtil.writeString(code, new File(root, moduleName + "-menu.sql"), "UTF-8");
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 使用模板引擎生成代码
|
|
|
*
|
|
|
* @param template
|
|
|
* @param entity
|
|
|
* @param list
|
|
|
* @return
|
|
|
* @throws Exception
|
|
|
*/
|
|
|
public String generate(String template, BaseInfo entity, List<BaseInfo> list) throws Exception {
|
|
|
VelocityEngine ve = new VelocityEngine();
|
|
|
ve.init();
|
|
|
|
|
|
VelocityContext context = new VelocityContext();
|
|
|
context.put("package", packageName);
|
|
|
context.put("entity", entity);
|
|
|
context.put("list", list);
|
|
|
context.put("moduleName", moduleName);
|
|
|
StringWriter writer = new StringWriter();
|
|
|
|
|
|
template = ResourceUtil.readUtf8Str("classpath:/generator/" + template);
|
|
|
|
|
|
ve.evaluate(context, writer, this.getClass().getName(), template);
|
|
|
|
|
|
return writer.toString();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取输出的java包源目录
|
|
|
*
|
|
|
* @return
|
|
|
*/
|
|
|
public File[] getOutPath() {
|
|
|
Set<String> paths = ClassUtil.getClassPaths(packageName);
|
|
|
if (CollUtil.isEmpty(paths) || paths.size() != 1) {
|
|
|
throw new RuntimeException("不能确定java包源目录");
|
|
|
}
|
|
|
String path = paths.iterator().next();
|
|
|
File file = new File(path.replace("/target/classes/", "/src/main/java/"));
|
|
|
File root = new File(path.substring(0, path.indexOf("/target/classes/"))).getParentFile();
|
|
|
|
|
|
|
|
|
return new File[]{root, file};
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 扫描获取包下需要生成的实体信息
|
|
|
*
|
|
|
* @param includes 包含的类名,不填表示扫描所有
|
|
|
* @return
|
|
|
*/
|
|
|
public List<BaseInfo> scan(String... includes) {
|
|
|
Info defaultInfo = MongoGenerator.class.getAnnotation(Info.class);
|
|
|
List<BaseInfo> entityList = ListUtil.list(true);
|
|
|
|
|
|
ClassUtil.scanPackageByAnnotation(packageName + ".mongo", Info.class).stream().filter(c -> {
|
|
|
if (ArrayUtil.isEmpty(includes)) {
|
|
|
return true;
|
|
|
} else {
|
|
|
return ArrayUtil.indexOf(includes, c.getSimpleName()) > -1;
|
|
|
}
|
|
|
}).forEach(entityClazz -> {
|
|
|
BaseInfo entityInfo = loadByInfo(entityClazz.getAnnotation(Info.class));
|
|
|
entityList.add(entityInfo);
|
|
|
entityInfo.setClazz(entityClazz);
|
|
|
entityInfo.setJavaName(entityClazz.getSimpleName());
|
|
|
entityInfo.setModuleName(moduleName);
|
|
|
|
|
|
entityInfo.all = Arrays.stream(entityClazz.getDeclaredFields()).map(field -> {
|
|
|
BaseInfo info = null;
|
|
|
if (field.isAnnotationPresent(Info.class)) {
|
|
|
info = loadByInfo(field.getAnnotation(Info.class));
|
|
|
} else {
|
|
|
info = loadByInfo(defaultInfo);
|
|
|
}
|
|
|
info.setClazz(field.getType());
|
|
|
info.setJavaName(field.getName());
|
|
|
info.setIsId(field.isAnnotationPresent(Id.class));
|
|
|
info.setModuleName(moduleName);
|
|
|
return info;
|
|
|
}).sorted((a, b) -> a.order - b.order).collect(Collectors.toList());
|
|
|
entityInfo.cols = entityInfo.all.stream().filter(a -> !a.isId).collect(Collectors.toList());
|
|
|
entityInfo.id = entityInfo.all.stream().filter(a -> a.isId).findFirst().get();
|
|
|
});
|
|
|
return entityList;
|
|
|
}
|
|
|
|
|
|
public BaseInfo loadByInfo(Info info) {
|
|
|
BaseInfo base = new BaseInfo();
|
|
|
base.setAdd(info.add());
|
|
|
base.setUpdate(info.update());
|
|
|
base.setShow(info.show());
|
|
|
base.setOrder(info.order());
|
|
|
base.setName(info.value());
|
|
|
if (!info.addDefault().equals("")) {
|
|
|
base.setAddDefault(info.addDefault());
|
|
|
}
|
|
|
if (!info.updateDefault().equals("")) {
|
|
|
base.setUpdateDefault(info.updateDefault());
|
|
|
}
|
|
|
if (!info.comment().equals("")) {
|
|
|
base.setComment(info.comment());
|
|
|
}
|
|
|
|
|
|
return base;
|
|
|
}
|
|
|
|
|
|
|
|
|
@Data
|
|
|
public static class BaseInfo {
|
|
|
|
|
|
public Class<?> clazz;
|
|
|
|
|
|
public Field field;
|
|
|
|
|
|
/**
|
|
|
* 所有字段
|
|
|
*/
|
|
|
public List<BaseInfo> all;
|
|
|
|
|
|
/**
|
|
|
* 不含主键
|
|
|
*/
|
|
|
public List<BaseInfo> cols;
|
|
|
|
|
|
/**
|
|
|
* 主键字段
|
|
|
*/
|
|
|
public BaseInfo id;
|
|
|
|
|
|
public Boolean isId = false;
|
|
|
|
|
|
public String name;
|
|
|
|
|
|
public String getName() {
|
|
|
if (StrUtil.isBlank(name)) {
|
|
|
return javaName;
|
|
|
} else {
|
|
|
return name;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public String javaName;
|
|
|
|
|
|
public String moduleName;
|
|
|
|
|
|
public String toUpperName() {
|
|
|
return javaName.substring(0, 1).toUpperCase() + javaName.substring(1);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 去掉模块名后的
|
|
|
*
|
|
|
* @return
|
|
|
*/
|
|
|
public String toSimpleUpperName() {
|
|
|
String n = toLowerName();
|
|
|
if (n.startsWith(moduleName)) {
|
|
|
return n.substring(moduleName.length());
|
|
|
} else {
|
|
|
return toUpperName();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
public String toSimpleLowerName() {
|
|
|
String n = toLowerName();
|
|
|
if (n.startsWith(moduleName)) {
|
|
|
n = n.substring(moduleName.length());
|
|
|
return n.substring(0, 1).toLowerCase() + n.substring(1);
|
|
|
} else {
|
|
|
return toLowerName();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public String toLowerName() {
|
|
|
return javaName.substring(0, 1).toLowerCase() + javaName.substring(1);
|
|
|
}
|
|
|
|
|
|
public String comment;
|
|
|
|
|
|
/**
|
|
|
* @param tabNum
|
|
|
* @return
|
|
|
*/
|
|
|
public String toComment(int tabNum) {
|
|
|
if (tabNum < 0) {
|
|
|
tabNum = 0;
|
|
|
}
|
|
|
String tabs = tabNum > 0 ? String.format("%" + (tabNum * 2) + "s", "") + " * " : " * ";
|
|
|
if (StrUtil.isNotBlank(comment)) {
|
|
|
return tabs + comment.replace("\n", "\n" + tabs);
|
|
|
} else {
|
|
|
return tabs;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
public boolean show;
|
|
|
|
|
|
public boolean add;
|
|
|
public String addDefault;
|
|
|
|
|
|
public boolean update;
|
|
|
public String updateDefault;
|
|
|
|
|
|
public int order;
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|