diff --git a/qiaoba-modules/qiaoba-module-generator/pom.xml b/qiaoba-modules/qiaoba-module-generator/pom.xml
index ba023c8..a4c1a75 100644
--- a/qiaoba-modules/qiaoba-module-generator/pom.xml
+++ b/qiaoba-modules/qiaoba-module-generator/pom.xml
@@ -30,5 +30,13 @@
org.apache.velocity
velocity-engine-core
+
+ com.qiaoba
+ qiaoba-common-doc
+
+
+ com.qiaoba
+ qiaoba-auth
+
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/constant/GenConstants.java b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/constant/GenConstants.java
index d831538..d7d206f 100644
--- a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/constant/GenConstants.java
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/constant/GenConstants.java
@@ -6,45 +6,6 @@ package com.qiaoba.module.generator.constant;
* @author ruoyi
*/
public class GenConstants {
- /**
- * 单表(增删改查)
- */
- public static final String TPL_CRUD = "crud";
-
- /**
- * 树表(增删改查)
- */
- public static final String TPL_TREE = "tree";
-
- /**
- * 主子表(增删改查)
- */
- public static final String TPL_SUB = "sub";
-
- /**
- * 树编码字段
- */
- public static final String TREE_CODE = "treeCode";
-
- /**
- * 树父编码字段
- */
- public static final String TREE_PARENT_CODE = "treeParentCode";
-
- /**
- * 树名称字段
- */
- public static final String TREE_NAME = "treeName";
-
- /**
- * 上级菜单ID字段
- */
- public static final String PARENT_MENU_ID = "parentMenuId";
-
- /**
- * 上级菜单名称字段
- */
- public static final String PARENT_MENU_NAME = "parentMenuName";
/**
* 数据库字符串类型
@@ -87,12 +48,8 @@ public class GenConstants {
/**
* Entity基类字段
*/
- public static final String[] BASE_ENTITY = {"createBy", "createTime", "updateBy", "updateTime", "remark"};
+ public static final String[] BASE_ENTITY = {"createUser", "createTime", "updateUser", "updateTime", "remark", "tenantId"};
- /**
- * Tree基类字段
- */
- public static final String[] TREE_ENTITY = {"parentName", "parentId", "orderNum", "ancestors", "children"};
/**
* 文本框
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/controller/GeneratorController.java b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/controller/GeneratorController.java
index 0553b07..5ba4de5 100644
--- a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/controller/GeneratorController.java
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/controller/GeneratorController.java
@@ -1,14 +1,16 @@
package com.qiaoba.module.generator.controller;
+import cn.hutool.core.io.IoUtil;
import com.qiaoba.common.base.result.AjaxResult;
import com.qiaoba.module.generator.entity.dto.TableDto;
import com.qiaoba.module.generator.service.GeneratorTableService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+import sun.nio.ch.IOUtil;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
/**
* 代码生成 Web层
@@ -32,4 +34,24 @@ public class GeneratorController {
public AjaxResult importTable(@RequestBody TableDto dto) {
return AjaxResult.toAjax(generatorTableService.importTable(dto));
}
+
+ @GetMapping("/download/{tableName}")
+ public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException
+ {
+ byte[] data = generatorTableService.downloadCode(tableName);
+ genCode(response, data);
+ }
+
+ /**
+ * 生成zip文件
+ */
+ private void genCode(HttpServletResponse response, byte[] data) throws IOException {
+ response.reset();
+ response.addHeader("Access-Control-Allow-Origin", "*");
+ response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
+ response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\"");
+ response.addHeader("Content-Length", "" + data.length);
+ response.setContentType("application/octet-stream; charset=UTF-8");
+ IoUtil.write(response.getOutputStream(), true, data);
+ }
}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/entity/Generator.java b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/entity/Generator.java
new file mode 100644
index 0000000..301ab76
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/entity/Generator.java
@@ -0,0 +1,39 @@
+package com.qiaoba.module.generator.entity;
+
+import com.qiaoba.common.base.enums.BaseEnum;
+import com.qiaoba.common.base.utils.ArrayUtil;
+import com.qiaoba.module.generator.constant.GenConstants;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author ailanyin
+ * @version 1.0
+ * @since 2023/7/3 9:40
+ */
+@Data
+@NoArgsConstructor
+public class Generator implements Serializable {
+
+ private GeneratorTable table;
+
+ private List columns;
+
+ private GeneratorTableColumn pkColumn;
+
+ public boolean isBaseColumn(String column) {
+ return ArrayUtil.contains(GenConstants.BASE_ENTITY, column);
+ }
+
+ public boolean isPk(String isPk) {
+ return BaseEnum.YES.getCode().equals(isPk);
+ }
+
+ public Generator(GeneratorTable table, List columns) {
+ this.table = table;
+ this.columns = columns;
+ }
+}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/entity/GeneratorTableColumn.java b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/entity/GeneratorTableColumn.java
index 2de4fe9..57f18cf 100644
--- a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/entity/GeneratorTableColumn.java
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/entity/GeneratorTableColumn.java
@@ -104,4 +104,5 @@ public class GeneratorTableColumn implements Serializable {
* 排序
*/
private Integer sort;
+
}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/factory/VelocityFactory.java b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/factory/VelocityFactory.java
new file mode 100644
index 0000000..08ab7e7
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/factory/VelocityFactory.java
@@ -0,0 +1,30 @@
+package com.qiaoba.module.generator.factory;
+
+import com.qiaoba.common.base.constants.BaseConstant;
+import org.apache.velocity.app.Velocity;
+
+import java.util.Properties;
+
+/**
+ * VelocityEngine工厂
+ *
+ * @author ruoyi
+ */
+public class VelocityFactory {
+ /**
+ * 初始化vm方法
+ */
+ public static void init() {
+ Properties p = new Properties();
+ try {
+ // 加载classpath目录下的vm文件
+ p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+ // 定义字符集
+ p.setProperty(Velocity.INPUT_ENCODING, BaseConstant.UTF8);
+ // 初始化Velocity引擎,指定配置Properties
+ Velocity.init(p);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/GeneratorTableColumnService.java b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/GeneratorTableColumnService.java
index dd6aaae..92aed3c 100644
--- a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/GeneratorTableColumnService.java
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/GeneratorTableColumnService.java
@@ -18,9 +18,19 @@ public interface GeneratorTableColumnService {
* 查询表的字段信息
*
* @param tableName 表名
+ * @param allowNull 允许空
* @return list
*/
- List selectListByTableName(String tableName);
+ List selectVoListByTableName(String tableName, boolean allowNull);
+
+ /**
+ * 查询表的字段信息
+ *
+ * @param tableId 表ID
+ * @param allowNull 允许空
+ * @return list
+ */
+ List selectListByTableId(String tableId, boolean allowNull);
/**
* 新增
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/GeneratorTableService.java b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/GeneratorTableService.java
index 06bfca8..e57f4ce 100644
--- a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/GeneratorTableService.java
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/GeneratorTableService.java
@@ -2,6 +2,7 @@ package com.qiaoba.module.generator.service;
import com.qiaoba.common.database.entity.PageQuery;
import com.qiaoba.common.database.entity.TableDataInfo;
+import com.qiaoba.module.generator.entity.GeneratorTable;
import com.qiaoba.module.generator.entity.dto.TableDto;
import com.qiaoba.module.generator.entity.vo.DbTableVo;
@@ -23,6 +24,14 @@ public interface GeneratorTableService {
*/
TableDataInfo selectPageDbTableList(TableDto dto, PageQuery pageQuery);
+ /**
+ * 通过表名查询
+ *
+ * @param tableName 表名
+ * @param allowNull 允许空
+ * @return GeneratorTable
+ */
+ GeneratorTable selectByTableName(String tableName, boolean allowNull);
/**
* 导入表结构
@@ -31,4 +40,12 @@ public interface GeneratorTableService {
* @return 结果
*/
int importTable(TableDto dto);
+
+ /**
+ * 下载
+ *
+ * @param tableName 表名
+ * @return 文件字节
+ */
+ byte[] downloadCode(String tableName);
}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/impl/GeneratorTableColumnServiceImpl.java b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/impl/GeneratorTableColumnServiceImpl.java
index 0f342de..91b3611 100644
--- a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/impl/GeneratorTableColumnServiceImpl.java
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/impl/GeneratorTableColumnServiceImpl.java
@@ -1,5 +1,9 @@
package com.qiaoba.module.generator.service.impl;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qiaoba.common.base.exceptions.ServiceException;
import com.qiaoba.module.generator.entity.GeneratorTableColumn;
import com.qiaoba.module.generator.entity.vo.TableColumnVo;
import com.qiaoba.module.generator.mapper.GeneratorTableColumnMapper;
@@ -23,10 +27,26 @@ public class GeneratorTableColumnServiceImpl implements GeneratorTableColumnServ
private final GeneratorTableColumnMapper generatorTableColumnMapper;
@Override
- public List selectListByTableName(String tableName) {
- return generatorTableColumnMapper.selectListByTableName(tableName);
+ public List selectVoListByTableName(String tableName, boolean allowNull) {
+ List list = generatorTableColumnMapper.selectListByTableName(tableName);
+ if (CollUtil.isEmpty(list) && !allowNull) {
+ throw new ServiceException(StrUtil.format("未查询到表字段信息, 表名: {}", tableName));
+ }
+ return list;
}
+ @Override
+ public List selectListByTableId(String tableId, boolean allowNull) {
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.lambda().eq(GeneratorTableColumn::getTableId, tableId);
+ List list = generatorTableColumnMapper.selectList(wrapper);
+ if (CollUtil.isEmpty(list) && !allowNull) {
+ throw new ServiceException(StrUtil.format("未查询到表字段信息, tableId: {}", tableId));
+ }
+ return list;
+ }
+
+
@Override
public Integer insert(GeneratorTableColumn generatorTableColumn) {
return generatorTableColumnMapper.insert(generatorTableColumn);
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/impl/GeneratorTableServiceImpl.java b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/impl/GeneratorTableServiceImpl.java
index 93ce4f8..63b83e5 100644
--- a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/impl/GeneratorTableServiceImpl.java
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/service/impl/GeneratorTableServiceImpl.java
@@ -1,22 +1,41 @@
package com.qiaoba.module.generator.service.impl;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qiaoba.common.base.constants.BaseConstant;
+import com.qiaoba.common.base.enums.BaseEnum;
+import com.qiaoba.common.base.exceptions.ServiceException;
import com.qiaoba.common.database.context.TenantDbTypeContext;
import com.qiaoba.common.database.entity.PageQuery;
import com.qiaoba.common.database.entity.TableDataInfo;
+import com.qiaoba.module.generator.entity.Generator;
import com.qiaoba.module.generator.entity.GeneratorTable;
import com.qiaoba.module.generator.entity.GeneratorTableColumn;
import com.qiaoba.module.generator.entity.dto.TableDto;
import com.qiaoba.module.generator.entity.vo.DbTableVo;
import com.qiaoba.module.generator.entity.vo.TableColumnVo;
+import com.qiaoba.module.generator.factory.VelocityFactory;
import com.qiaoba.module.generator.mapper.GeneratorTableMapper;
import com.qiaoba.module.generator.service.GeneratorTableColumnService;
import com.qiaoba.module.generator.service.GeneratorTableService;
import com.qiaoba.module.generator.util.GeneratorUtil;
+import com.qiaoba.module.generator.util.VelocityUtil;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
import org.springframework.stereotype.Service;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
import java.util.List;
+import java.util.Objects;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
/**
* 数据库表 服务层实现
@@ -27,6 +46,7 @@ import java.util.List;
*/
@Service
@RequiredArgsConstructor
+@Slf4j
public class GeneratorTableServiceImpl implements GeneratorTableService {
private final GeneratorTableMapper generatorTableMapper;
@@ -40,12 +60,23 @@ public class GeneratorTableServiceImpl implements GeneratorTableService {
return TableDataInfo.build(generatorTableMapper.selectPageDbTableList(pageQuery.build(), dto));
}
+ @Override
+ public GeneratorTable selectByTableName(String tableName, boolean allowNull) {
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.lambda().eq(GeneratorTable::getTableName, tableName);
+ GeneratorTable generatorTable = generatorTableMapper.selectOne(wrapper);
+ if (Objects.isNull(generatorTable) && !allowNull) {
+ throw new ServiceException(StrUtil.format("未查到表信息, 表名: {}", tableName));
+ }
+ return generatorTable;
+ }
+
@Override
public int importTable(TableDto dto) {
GeneratorTable generatorTable = GeneratorUtil.dtoToGeneratorTable(dto);
int result = generatorTableMapper.insert(generatorTable);
if (result > BaseConstant.HANDLE_ERROR) {
- List columnVos = generatorTableColumnService.selectListByTableName(dto.getTableName());
+ List columnVos = generatorTableColumnService.selectVoListByTableName(dto.getTableName(), false);
for (TableColumnVo columnVo : columnVos) {
GeneratorTableColumn generatorTableColumn = GeneratorUtil.initColumn(columnVo, generatorTable.getTableId());
generatorTableColumnService.insert(generatorTableColumn);
@@ -54,9 +85,67 @@ public class GeneratorTableServiceImpl implements GeneratorTableService {
return result;
}
+ @Override
+ public byte[] downloadCode(String tableName) {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ZipOutputStream zip = new ZipOutputStream(outputStream);
+ generatorCode(tableName, zip);
+ IoUtil.close(zip);
+ return outputStream.toByteArray();
+ }
+
+ private void generatorCode(String tableName, ZipOutputStream zip) {
+ // 查询表信息
+ GeneratorTable table = selectByTableName(tableName, false);
+ // 查询字段信息
+ List columns = generatorTableColumnService.selectListByTableId(table.getTableId(), false);
+ Generator generator = new Generator(table, columns);
+ // 设置主键列信息
+ setPkColumn(generator);
+ // 初始化 Velocity
+ VelocityFactory.init();
+ // 设置参数
+ VelocityContext context = VelocityUtil.setVariables(generator);
+ // 获取模板列表
+ List templates = VelocityUtil.getTemplateList();
+ for (String template : templates) {
+ // 渲染模板
+ StringWriter sw = new StringWriter();
+ Template tpl = Velocity.getTemplate(template, BaseConstant.UTF8);
+ tpl.merge(context, sw);
+ try {
+ // 添加到zip
+ zip.putNextEntry(new ZipEntry(VelocityUtil.getFileName(template, table)));
+ IoUtil.write(zip, false, sw.toString().getBytes());
+ IoUtil.close(sw);
+ zip.flush();
+ zip.closeEntry();
+ } catch (IOException e) {
+ log.error("渲染模板失败,表名:" + table.getTableName(), e);
+ }
+ }
+ }
+
private String selectSchema() {
// PgSQL 需要设置 schema
//DataBaseEnum.POSTGRE_SQL.getType().equals(dbType)
return null;
}
+
+ /**
+ * 设置主键列信息
+ *
+ * @param generator generator
+ */
+ private void setPkColumn(Generator generator) {
+ for (GeneratorTableColumn column : generator.getColumns()) {
+ if (BaseEnum.YES.getCode().equals(column.getIsPk())) {
+ generator.setPkColumn(column);
+ break;
+ }
+ }
+ if (ObjectUtil.isNull(generator.getPkColumn())) {
+ generator.setPkColumn(generator.getColumns().get(0));
+ }
+ }
}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/util/VelocityUtil.java b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/util/VelocityUtil.java
new file mode 100644
index 0000000..9f9fcb2
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/java/com/qiaoba/module/generator/util/VelocityUtil.java
@@ -0,0 +1,175 @@
+package com.qiaoba.module.generator.util;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.qiaoba.module.generator.constant.GenConstants;
+import com.qiaoba.module.generator.entity.Generator;
+import com.qiaoba.module.generator.entity.GeneratorTable;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.velocity.VelocityContext;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * 模板生成 工具类
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2023/7/3 9:22
+ */
+public class VelocityUtil {
+
+ private static final String VM_CONTROLLER = "controller.java.vm";
+ private static final String VM_DOMAIN = "entity.java.vm";
+ private static final String VM_DTO = "dto.java.vm";
+ private static final String VM_PARAM = "param.java.vm";
+ private static final String VM_SUB_DOMAIN = "sub-entity.java.vm";
+ private static final String VM_MAPPER = "mapper.java.vm";
+ private static final String VM_MAPPER_XML = "mapper.xml.vm";
+ private static final String VM_SERVICE = "service.java.vm";
+ private static final String VM_SERVICE_IMPL = "serviceImpl.java.vm";
+ private static final String VM_SQL = "sql.vm";
+ private static final String VM_API_JS = "api.js.vm";
+ private static final String VM_INDEX_VUE = "index.vue.vm";
+ private static final String VM_INDEX_TREE_VUE = "index-tree.vue.vm";
+
+ /**
+ * 项目空间路径
+ */
+ private static final String PROJECT_PATH = "main/java";
+
+ /**
+ * mybatis空间路径
+ */
+ private static final String MYBATIS_PATH = "main/resources/mapper";
+
+ /**
+ * 默认上级菜单,系统工具
+ */
+ private static final String DEFAULT_PARENT_MENU_ID = "3";
+
+ /**
+ * 加载模板
+ *
+ * @return 模板集合
+ */
+ public static List getTemplateList() {
+ List templates = new ArrayList<>();
+ templates.add("vm/java/entity.java.vm");
+ templates.add("vm/java/dto.java.vm");
+ templates.add("vm/java/param.java.vm");
+ templates.add("vm/java/mapper.java.vm");
+ templates.add("vm/java/service.java.vm");
+ templates.add("vm/java/serviceImpl.java.vm");
+ templates.add("vm/java/controller.java.vm");
+
+ templates.add("vm/js/api.js.vm");
+ /*
+
+ templates.add("vm/sql/sql.vm");
+ templates.add("vm/js/api.js.vm");
+ templates.add("vm/vue/index.vue.vm");*/
+ return templates;
+ }
+
+ public static VelocityContext setVariables(Generator generator) {
+
+ String moduleName = generator.getTable().getModuleName();
+ String businessName = generator.getTable().getBusinessName();
+ String packageName = generator.getTable().getPackageName();
+ String functionName = generator.getTable().getFunctionName();
+
+ VelocityContext velocityContext = new VelocityContext();
+ velocityContext.put("tableName", generator.getTable().getTableName());
+ velocityContext.put("functionName", StrUtil.isNotBlank(functionName) ? functionName : "【请填写功能名称】");
+ velocityContext.put("ClassName", generator.getTable().getClassName());
+ velocityContext.put("className", StringUtils.uncapitalize(generator.getTable().getClassName()));
+ velocityContext.put("moduleName", generator.getTable().getModuleName());
+ velocityContext.put("BusinessName", StringUtils.capitalize(generator.getTable().getBusinessName()));
+ velocityContext.put("businessName", generator.getTable().getBusinessName());
+ velocityContext.put("basePackage", getPackagePrefix(packageName));
+ velocityContext.put("packageName", packageName);
+ velocityContext.put("author", generator.getTable().getAuthor());
+ velocityContext.put("datetime", DateUtil.now());
+ velocityContext.put("pkColumn", generator.getPkColumn());
+ // todo
+ //velocityContext.put("importList", getImportList(generator.getTable()))
+ velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
+ velocityContext.put("columns", generator.getColumns());
+ velocityContext.put("table", generator.getTable());
+ velocityContext.put("generator", generator);
+
+ return velocityContext;
+ }
+
+ /**
+ * 获取包前缀
+ *
+ * @param packageName 包名称
+ * @return 包前缀名称
+ */
+ private static String getPackagePrefix(String packageName) {
+ int lastIndex = packageName.lastIndexOf(".");
+ return StringUtils.substring(packageName, 0, lastIndex);
+ }
+
+ /**
+ * 获取权限前缀
+ *
+ * @param moduleName 模块名称
+ * @param businessName 业务名称
+ * @return 返回权限前缀
+ */
+ private static String getPermissionPrefix(String moduleName, String businessName) {
+ return StrUtil.format("{}:{}", moduleName, businessName);
+ }
+
+ /**
+ * 获取文件名
+ */
+ public static String getFileName(String template, GeneratorTable genTable) {
+ // 文件名称
+ String fileName = "";
+ // 包路径
+ String packageName = genTable.getPackageName();
+ // 模块名
+ String moduleName = genTable.getModuleName();
+ // 大写类名
+ String className = genTable.getClassName();
+ // 业务名称
+ String businessName = genTable.getBusinessName();
+
+ String javaPath = PROJECT_PATH + "/" + StrUtil.replace(packageName, ".", "/");
+ String mybatisPath = MYBATIS_PATH + "/" + moduleName;
+ String vuePath = "vue";
+
+ if (template.contains(VM_DOMAIN)) {
+ fileName = StrUtil.format("{}/entity/{}.java", javaPath, className);
+ } else if (template.contains(VM_DTO)) {
+ fileName = StrUtil.format("{}/entity/dto/{}Dto.java", javaPath, className);
+ } else if (template.contains(VM_PARAM)) {
+ fileName = StrUtil.format("{}/entity/param/{}Param.java", javaPath, className);
+ } else if (template.contains(VM_MAPPER)) {
+ fileName = StrUtil.format("{}/mapper/{}Mapper.java", javaPath, className);
+ } else if (template.contains(VM_SERVICE)) {
+ fileName = StrUtil.format("{}/service/{}Service.java", javaPath, className);
+ } else if (template.contains(VM_SERVICE_IMPL)) {
+ fileName = StrUtil.format("{}/service/impl/{}ServiceImpl.java", javaPath, className);
+ } else if (template.contains(VM_CONTROLLER)) {
+ fileName = StrUtil.format("{}/controller/{}Controller.java", javaPath, className);
+ } else if (template.contains(VM_MAPPER_XML)) {
+ fileName = StrUtil.format("{}/{}Mapper.xml", mybatisPath, className);
+ } else if (template.contains(VM_SQL)) {
+ fileName = businessName + "Menu.sql";
+ } else if (template.contains(VM_API_JS)) {
+ fileName = StrUtil.format("{}/api/{}/{}.js", vuePath, moduleName, businessName);
+ } else if (template.contains(VM_INDEX_VUE)) {
+ fileName = StrUtil.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
+ } else if (template.contains(VM_INDEX_TREE_VUE)) {
+ fileName = StrUtil.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
+ }
+ return fileName;
+ }
+}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/controller.java.vm b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/controller.java.vm
new file mode 100644
index 0000000..cd97329
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/controller.java.vm
@@ -0,0 +1,71 @@
+package ${packageName}.controller;
+
+import com.qiaoba.common.base.result.AjaxResult;
+import com.qiaoba.common.database.entity.PageQuery;
+import com.qiaoba.common.database.entity.TableDataInfo;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+import ${packageName}.entity.${ClassName};
+import ${packageName}.entity.dto.${ClassName}Dto;
+import ${packageName}.entity.param.${ClassName}Param;
+import ${packageName}.service.${ClassName}Service;
+
+
+/**
+ * ${functionName} Web层
+ *
+ * @author ${author}
+ * @version 1.0
+ * @since ${datetime}
+ */
+@RestController
+@RequestMapping("/${moduleName}/${businessName}")
+@RequiredArgsConstructor
+@Tag(name = "${functionName}管理")
+public class ${ClassName}Controller {
+
+ private final ${ClassName}Service ${className}Service;
+
+ @PreAuthorize("hasAuthority('${permissionPrefix}:list')")
+ @GetMapping("/list")
+ @Operation(summary = "获取列表")
+ public TableDataInfo<${ClassName}> list(${ClassName}Param param, PageQuery pageQuery) {
+ return ${className}Service.selectPageList(param, pageQuery);
+ }
+
+ @PreAuthorize("hasAuthority('${permissionPrefix}:query')")
+ @GetMapping(value = "/{${pkColumn.javaField}}")
+ @Operation(summary = "获取详情")
+ public AjaxResult getInfo(@PathVariable String ${pkColumn.javaField}) {
+ return AjaxResult.success(${className}Service.selectById(${pkColumn.javaField}, false));
+ }
+
+ @PreAuthorize("hasAuthority('${permissionPrefix}:add')")
+ @PostMapping
+ @Operation(summary = "新增${functionName}")
+ public AjaxResult add(@RequestBody ${ClassName}Dto dto) {
+ return AjaxResult.toAjax(${className}Service.insert(dto));
+
+ }
+
+ @PreAuthorize("hasAuthority('${permissionPrefix}:edit')")
+ @PutMapping
+ @Operation(summary = "修改${functionName}")
+ public AjaxResult edit(@RequestBody ${ClassName}Dto dto) {
+ return AjaxResult.toAjax(${className}Service.updateById(dto));
+
+ }
+
+ @PreAuthorize("hasAuthority('${permissionPrefix}:remove')")
+ @DeleteMapping("/{${pkColumn.javaField}s}")
+ @Operation(summary = "删除${functionName}")
+ public AjaxResult remove(@PathVariable List ${pkColumn.javaField}s) {
+ return AjaxResult.toAjax(${className}Service.deleteByIds(${pkColumn.javaField}s));
+ }
+}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/dto.java.vm b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/dto.java.vm
new file mode 100644
index 0000000..4844fd7
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/dto.java.vm
@@ -0,0 +1,39 @@
+package ${packageName}.entity;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+/**
+ * ${functionName} Dto
+ *
+ * @author ${author}
+ * @version 1.0
+ * @since ${datetime}
+ */
+@Getter
+@Setter
+public class ${ClassName}Dto implements Serializable {
+
+ private static final long serialVersionUID=1L;
+
+## 遍历字段
+#foreach ($column in $columns)
+## 忽略基础(父类)字段
+#if(!$generator.isBaseColumn($column.javaField))
+## 是主键
+#if($generator.isPk($column.isPk))
+ @Schema(description = "$column.columnComment")
+ private String $column.javaField;
+
+## 不是主键
+#else
+ @Schema(description = "$column.columnComment")
+ private $column.javaType $column.javaField;
+
+#end
+#end
+#end
+}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/entity.java.vm b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/entity.java.vm
new file mode 100644
index 0000000..eeb7a71
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/entity.java.vm
@@ -0,0 +1,45 @@
+package ${packageName}.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.qiaoba.common.base.entity.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * ${functionName} ${tableName}
+ *
+ * @author ${author}
+ * @version 1.0
+ * @since ${datetime}
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("${tableName}")
+public class ${ClassName} extends BaseEntity{
+
+ private static final long serialVersionUID=1L;
+
+## 遍历字段
+#foreach ($column in $columns)
+## 忽略基础(父类)字段
+#if(!$generator.isBaseColumn($column.javaField))
+## 是主键
+#if($generator.isPk($column.isPk))
+ /**
+ * $column.columnComment
+ */
+ @TableId
+ private String $column.javaField;
+
+## 不是主键
+#else
+ /**
+ * $column.columnComment
+ */
+ private $column.javaType $column.javaField;
+
+#end
+#end
+#end
+}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/mapper.java.vm b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/mapper.java.vm
new file mode 100644
index 0000000..6a6e963
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/mapper.java.vm
@@ -0,0 +1,14 @@
+package ${packageName}.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ${packageName}.entity.${ClassName};
+
+/**
+ * ${functionName}管理 数据层
+ *
+ * @author ${author}
+ * @version 1.0
+ * @since ${datetime}
+ */
+public interface ${ClassName}Mapper extends BaseMapper<${ClassName}> {
+}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/param.java.vm b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/param.java.vm
new file mode 100644
index 0000000..50c7151
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/param.java.vm
@@ -0,0 +1,22 @@
+package ${packageName}.entity;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+/**
+ * ${functionName} Param
+ *
+ * @author ${author}
+ * @version 1.0
+ * @since ${datetime}
+ */
+@Getter
+@Setter
+public class ${ClassName}Param implements Serializable {
+
+ private static final long serialVersionUID=1L;
+
+}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/service.java.vm b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/service.java.vm
new file mode 100644
index 0000000..1f43dfc
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/service.java.vm
@@ -0,0 +1,77 @@
+package ${packageName}.service;
+
+import java.util.List;
+import com.qiaoba.common.database.entity.PageQuery;
+import com.qiaoba.common.database.entity.TableDataInfo;
+import ${packageName}.entity.${ClassName};
+import ${packageName}.entity.dto.${ClassName}Dto;
+import ${packageName}.entity.param.${ClassName}Param;
+
+/**
+ * ${functionName} 服务层
+ *
+ * @author ${author}
+ * @version 1.0
+ * @since ${datetime}
+ */
+public interface ${ClassName}Service {
+
+ /**
+ * 查询${functionName}列表
+ *
+ * @param param 查询条件
+ * @return ${functionName}集合
+ */
+ List<${ClassName}> selectList(${ClassName}Param param);
+
+ /**
+ * 分页查询${functionName}列表
+ *
+ * @param param 查询条件
+ * @param pageQuery 分页信息
+ * @return ${functionName}集合
+ */
+ TableDataInfo<${ClassName}> selectPageList(${ClassName}Param param, PageQuery pageQuery);
+
+ /**
+ * 查询${functionName}
+ *
+ * @param ${pkColumn.javaField} ${pkColumn.javaField}
+ * @param allowNull 允许空
+ * @return ${functionName}
+ */
+ ${ClassName} selectById(String ${pkColumn.javaField}, boolean allowNull);
+
+ /**
+ * 新增${functionName}
+ *
+ * @param dto dto
+ * @return 结果
+ */
+ int insert(${ClassName}Dto dto);
+
+ /**
+ * 修改${functionName}
+ *
+ * @param dto dto
+ * @return 结果
+ */
+ int updateById(${ClassName}Dto dto);
+
+ /**
+ * 删除${functionName}信息
+ *
+ * @param ${pkColumn.javaField} ${pkColumn.javaField}
+ * @return 结果
+ */
+ int deleteById(String ${pkColumn.javaField});
+
+ /**
+ * 批量删除${functionName}
+ *
+ * @param ${pkColumn.javaField}s ${pkColumn.javaField}s
+ * @return 结果
+ */
+ int deleteByIds(List ${pkColumn.javaField}s);
+
+}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/serviceImpl.java.vm b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/serviceImpl.java.vm
new file mode 100644
index 0000000..a89794c
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/java/serviceImpl.java.vm
@@ -0,0 +1,99 @@
+package ${packageName}.service.impl;
+
+import java.util.*;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qiaoba.auth.utils.SecurityUtil;
+import com.qiaoba.common.base.exceptions.ServiceException;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import com.qiaoba.common.database.entity.PageQuery;
+import com.qiaoba.common.database.entity.TableDataInfo;
+
+import ${packageName}.entity.${ClassName};
+import ${packageName}.entity.dto.${ClassName}Dto;
+import ${packageName}.entity.param.${ClassName}Param;
+import ${packageName}.service.${ClassName}Service;
+import ${packageName}.mapper.${ClassName}Mapper;
+
+/**
+ * ${functionName} 服务层实现
+ *
+ * @author ${author}
+ * @version 1.0
+ * @since ${datetime}
+ */
+@Service
+@RequiredArgsConstructor
+public class ${ClassName}ServiceImpl implements ${ClassName}Service {
+
+ private final ${ClassName}Mapper ${className}Mapper;
+
+ @Override
+ public List<${ClassName}> selectList(${ClassName}Param param) {
+ return ${className}Mapper.selectList(param2Wrapper(param));
+ }
+
+ @Override
+ public TableDataInfo<${ClassName}> selectPageList(${ClassName}Param param, PageQuery pageQuery) {
+ return TableDataInfo.build(${className}Mapper.selectPage(pageQuery.build(), param2Wrapper(param)));
+ }
+
+ @Override
+ public ${ClassName} selectById(String ${pkColumn.javaField}, boolean allowNull) {
+ ${ClassName} ${className} =${className}Mapper.selectById(${pkColumn.javaField});
+
+ if (!allowNull && Objects.isNull(${className})) {
+ throw new ServiceException("未查询到有关信息");
+ }
+
+ return ${className};
+ }
+
+ @Override
+ public int insert(${ClassName}Dto dto) {
+
+ ${ClassName} ${className} =dto2Entity(dto);
+ ${className}.setCreateTime(new Date());
+ ${className}.setCreateUser(SecurityUtil.getLoginUsername());
+
+ return ${className}Mapper.insert(${className});
+ }
+
+ @Override
+ public int updateById(${ClassName}Dto dto) {
+
+ ${ClassName} ${className} =dto2Entity(dto);
+ ${className}.setUpdateTime(new Date());
+ ${className}.setUpdateUser(SecurityUtil.getLoginUsername());
+
+ return ${className}Mapper.updateById(${className});
+ }
+
+ @Override
+ public int deleteById(String ${pkColumn.javaField}) {
+ return ${className}Mapper.deleteById(${pkColumn.javaField});
+ }
+
+ @Override
+ public int deleteByIds(List ${pkColumn.javaField}s) {
+ return ${className}Mapper.deleteBatchIds(${pkColumn.javaField}s);
+ }
+
+ private ${ClassName} dto2Entity(${ClassName}Dto dto) {
+ ${ClassName} ${className} = new ${ClassName}();
+ #foreach ($column in $columns)
+ #if(!$generator.isBaseColumn($column.javaField))
+ ## 首字母大写
+ #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ ${className}.set$AttrName(dto.get$AttrName());
+ #end
+ #end
+ return ${className};
+ }
+
+ private QueryWrapper<${ClassName}> param2Wrapper(${ClassName}Param param) {
+ QueryWrapper<${ClassName}> wrapper = new QueryWrapper<>();
+ return wrapper;
+ }
+}
diff --git a/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/js/api.js.vm b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/js/api.js.vm
new file mode 100644
index 0000000..9295524
--- /dev/null
+++ b/qiaoba-modules/qiaoba-module-generator/src/main/resources/vm/js/api.js.vm
@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询${functionName}列表
+export function list${BusinessName}(query) {
+ return request({
+ url: '/${moduleName}/${businessName}/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询${functionName}详细
+export function get${BusinessName}(${pkColumn.javaField}) {
+ return request({
+ url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField},
+ method: 'get'
+ })
+}
+
+// 新增${functionName}
+export function add${BusinessName}(data) {
+ return request({
+ url: '/${moduleName}/${businessName}',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改${functionName}
+export function update${BusinessName}(data) {
+ return request({
+ url: '/${moduleName}/${businessName}',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除${functionName}
+export function del${BusinessName}(${pkColumn.javaField}) {
+ return request({
+ url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField},
+ method: 'delete'
+ })
+}