This commit is contained in:
2023-07-04 17:53:04 +08:00
parent 065b60f851
commit 8be13f00a4
24 changed files with 417 additions and 135 deletions

View File

@ -43,7 +43,7 @@ mybatis-plus:
# NONE不做处理 WARNING打印相关警告 FAILING抛出异常和详细信息
autoMappingUnknownColumnBehavior: NONE
# 控制台打印 SQL
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
level:

View File

@ -115,9 +115,6 @@ springdoc:
- group: '监控管理'
paths-to-match: '/**'
packages-to-scan: com.qiaoba.module.monitor.controller
- group: '代码生成'
paths-to-match: '/**'
packages-to-scan: com.qiaoba.module.generator.controller
# knife4j的增强配置不需要增强可以不配
knife4j:
enable: true

View File

@ -30,10 +30,6 @@
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
</dependency>
<dependency>
<groupId>com.qiaoba</groupId>
<artifactId>qiaoba-common-doc</artifactId>
</dependency>
<dependency>
<groupId>com.qiaoba</groupId>
<artifactId>qiaoba-auth</artifactId>

View File

@ -7,50 +7,42 @@ package com.qiaoba.module.generator.constant;
*/
public class GenConstants {
/*====================================[数据库]=========================================*/
/**
* 数据库字符串类型
*/
public static final String[] COLUMNTYPE_STR = {"char", "varchar", "nvarchar", "varchar2"};
public static final String[] COLUMN_TYPE_STR = {"char", "varchar", "nvarchar", "varchar2"};
/**
* 数据库文本类型
*/
public static final String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext"};
public static final String[] COLUMN_TYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext"};
/**
* 数据库时间类型
*/
public static final String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp"};
public static final String[] COLUMN_TYPE_TIME = {"datetime", "time", "date", "timestamp"};
/**
* 数据库数字类型
*/
public static final String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer",
public static final String[] COLUMN_TYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer",
"bit", "bigint", "float", "double", "decimal"};
/**
* 页面不需要编辑字段
* 页面不需要处理的字段
*/
public static final String[] COLUMNNAME_NOT_EDIT = {"id", "create_by", "create_time", "del_flag"};
public static final String[] COLUMN_NAME_NOT_HANDLE = {"id", "create_user", "create_time", "del_flag", "update_user",
"update_time", "tenant_id"};
/**
* 页面不需要显示的列表字段
*/
public static final String[] COLUMNNAME_NOT_LIST = {"id", "create_by", "create_time", "del_flag", "update_by",
"update_time"};
/**
* 页面不需要查询字段
*/
public static final String[] COLUMNNAME_NOT_QUERY = {"id", "create_by", "create_time", "del_flag", "update_by",
"update_time", "remark"};
/**
* Entity基类字段
*/
public static final String[] BASE_ENTITY = {"createUser", "createTime", "updateUser", "updateTime", "remark", "tenantId"};
/*====================================[前端控件]=========================================*/
/**
* 文本框
*/
@ -96,6 +88,7 @@ public class GenConstants {
*/
public static final String HTML_EDITOR = "editor";
/*====================================[后端类型]=========================================*/
/**
* 字符串类型
*/
@ -141,33 +134,57 @@ public class GenConstants {
*/
public static final String REQUIRE = "1";
/*====================================[特殊处理]=========================================*/
/**
* 需处理成 模糊搜索 的字段
* 需处理成 模糊搜索 的字段
*/
public static final String[] HTML_LIKE_COLUMN = {"name", "code", "phone"};
/**
* 需处理成 单选框 的字段
* 需处理成 单选框 的字段
*/
public static final String[] HTML_RADIO_COLUMN = {"status"};
/**
* 需处理成 下拉框 的字段
* 需处理成 下拉框 的字段
*/
public static final String[] HTML_SELECT_COLUMN = {"type", "sex", "gender"};
/**
* 需处理成 图片上传控件 的字段
* 需处理成 图片上传控件 的字段
*/
public static final String[] HTML_IMAGE_COLUMN = {"image", "pic"};
/**
* 需处理成 文件上传控件 的字段
* 需处理成 文件上传控件 的字段
*/
public static final String[] HTML_FILE_COLUMN = {"file"};
/**
* 需处理成 富文本 的字段
* 需处理成 富文本 的字段
*/
public static final String[] HTML_EDITOR_COLUMN = {"content", "description"};
/*====================================[下载类型]=========================================*/
/**
* 下载-全部
*/
public static final String TEMPLATE_TYPE_ALL = "all";
/**
* 下载-后端
*/
public static final String TEMPLATE_TYPE_JAVA = "java";
/**
* 下载-前端
*/
public static final String TEMPLATE_TYPE_VUE = "vue";
/**
* 下载-SQL
*/
public static final String TEMPLATE_TYPE_SQL = "sql";
}

View File

@ -1,19 +1,18 @@
package com.qiaoba.module.generator.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.IoUtil;
import com.qiaoba.common.base.result.AjaxResult;
import com.qiaoba.common.database.entity.PageQuery;
import com.qiaoba.common.database.entity.TableDataInfo;
import com.qiaoba.module.generator.constant.GenConstants;
import com.qiaoba.module.generator.entity.GeneratorTable;
import com.qiaoba.module.generator.entity.GeneratorTableColumn;
import com.qiaoba.module.generator.entity.dto.GeneratorTableDto;
import com.qiaoba.module.generator.entity.dto.TableDto;
import com.qiaoba.module.generator.service.GeneratorTableColumnService;
import com.qiaoba.module.generator.service.GeneratorTableService;
import io.swagger.v3.oas.annotations.Operation;
import com.qiaoba.module.generator.util.GeneratorUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -40,14 +39,16 @@ public class GeneratorController {
private final GeneratorTableColumnService generatorTableColumnService;
/**
* 查询代码生成列表
* 代码生成列表
*/
@GetMapping("/list")
@Operation(summary = "获取列表")
public TableDataInfo list(TableDto dto, PageQuery pageQuery) {
return generatorTableService.selectPageList(dto, pageQuery);
}
/**
* 代码生成详细
*/
@GetMapping(value = "/{tableId}")
public AjaxResult getInfo(@PathVariable String tableId) {
GeneratorTable table = generatorTableService.selectById(tableId);
@ -58,6 +59,9 @@ public class GeneratorController {
return AjaxResult.success(map);
}
/**
* 修改代码生成
*/
@PutMapping
public AjaxResult edit(@RequestBody GeneratorTableDto dto) {
GeneratorTable generatorTable = BeanUtil.copyProperties(dto, GeneratorTable.class);
@ -66,31 +70,55 @@ public class GeneratorController {
return AjaxResult.toAjax(result);
}
/**
* 批量删除代码生成
*/
@DeleteMapping("/{tableIds}")
public AjaxResult remove(@PathVariable List<String> tableIds) {
return AjaxResult.toAjax(generatorTableService.deleteByIds(tableIds));
}
/**
* 导入表结构(保存)
* 数据库表列表(排除已导入表)
*/
@GetMapping("/db/list")
public TableDataInfo dbTableList(TableDto dto, PageQuery pageQuery) {
return generatorTableService.selectPageDbTableList(dto, pageQuery);
}
/**
* 导入表结构
*/
@PostMapping("/importTable")
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);
/**
* 预览代码
*/
@GetMapping("/preview/{tableId}")
public AjaxResult preview(@PathVariable("tableId") String tableId) {
Map<String, String> dataMap = generatorTableService.previewCode(tableId, GenConstants.TEMPLATE_TYPE_ALL);
return AjaxResult.success(dataMap);
}
/**
* 生成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);
@GetMapping("/download/{tableId}/{templateType}")
public void download(HttpServletResponse response, @PathVariable String tableId, @PathVariable String templateType) throws IOException {
byte[] data = generatorTableService.downloadCode(tableId, templateType);
GeneratorUtil.download(response, data);
}
/**
* 同步表结构
*/
@GetMapping("/syncTable/{tableId}")
public AjaxResult syncTable(@PathVariable String tableId) {
generatorTableService.syncTable(tableId);
return AjaxResult.success();
}
}

View File

@ -22,12 +22,18 @@ public class Generator implements Serializable {
private List<GeneratorTableColumn> columns;
private List<GeneratorTableColumn> queryColumns;
private GeneratorTableColumn pkColumn;
public boolean isBaseColumn(String column) {
return ArrayUtil.contains(GenConstants.BASE_ENTITY, column);
}
public boolean isQueryColumn(String isQuery) {
return BaseEnum.YES.getCode().equals(isQuery);
}
public boolean isPk(String isPk) {
return BaseEnum.YES.getCode().equals(isPk);
}

View File

@ -66,8 +66,8 @@ public class GeneratorTable implements Serializable {
private String author;
/**
* 生成路径(不填默认项目路径)
* 父级菜单ID
*/
private String genPath;
private String parentMenuId;
}

View File

@ -72,6 +72,11 @@ public class GeneratorTableDto implements Serializable {
*/
private String genPath;
/**
* 父级菜单ID
*/
private String parentMenuId;
/**
* 字段信息
*/

View File

@ -23,5 +23,12 @@ public interface GeneratorTableColumnMapper extends BaseMapper<GeneratorTableCol
* @param tableName 表名
* @return list
*/
List<TableColumnVo> selectListByTableName(String tableName);
List<TableColumnVo> selectDbColumnList(String tableName);
/**
* 通过 tableIds 批量删除
*
* @param tableIds tableIds
*/
void deleteByTableIds(List<String> tableIds);
}

View File

@ -1,5 +1,6 @@
package com.qiaoba.module.generator.mapper;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiaoba.module.generator.entity.GeneratorTable;
@ -14,6 +15,7 @@ import org.apache.ibatis.annotations.Param;
* @version 1.0
* @since 2023/6/26 9:24
*/
@InterceptorIgnore(tenantLine = "true")
public interface GeneratorTableMapper extends BaseMapper<GeneratorTable> {
/**

View File

@ -21,7 +21,7 @@ public interface GeneratorTableColumnService {
* @param allowNull 允许空
* @return list
*/
List<TableColumnVo> selectVoListByTableName(String tableName, boolean allowNull);
List<TableColumnVo> selectDbColumnList(String tableName, boolean allowNull);
/**
* 查询表的字段信息
@ -40,10 +40,31 @@ public interface GeneratorTableColumnService {
*/
Integer insert(GeneratorTableColumn generatorTableColumn);
/**
* 根据ID更新
*
* @param generatorTableColumn generatorTableColumn
*/
void updateById(GeneratorTableColumn generatorTableColumn);
/**
* 批量根据ID更新
*
* @param columns columns
*/
void updateBatchById(List<GeneratorTableColumn> columns);
/**
* 通过 tableIds 批量删除
*
* @param tableIds tableIds
*/
void deleteByTableIds(List<String> tableIds);
/**
* 通过主键批量删除
*
* @param ids 主键Ids
*/
void deleteByIds(List<String> ids);
}

View File

@ -6,6 +6,9 @@ import com.qiaoba.module.generator.entity.GeneratorTable;
import com.qiaoba.module.generator.entity.dto.TableDto;
import com.qiaoba.module.generator.entity.vo.DbTableVo;
import java.util.List;
import java.util.Map;
/**
* 数据库表 服务层
*
@ -16,7 +19,7 @@ import com.qiaoba.module.generator.entity.vo.DbTableVo;
public interface GeneratorTableService {
/**
* 查询业务列表
* 查询代码生成列表
*
* @param dto 查询条件
* @param pageQuery 分页
@ -25,7 +28,7 @@ public interface GeneratorTableService {
TableDataInfo<GeneratorTable> selectPageList(TableDto dto, PageQuery pageQuery);
/**
* 根据ID查询业务
* 查询代码生成详细
*
* @param tableId tableId
* @return info
@ -33,7 +36,7 @@ public interface GeneratorTableService {
GeneratorTable selectById(String tableId);
/**
* 根据ID更新
* 更新代码生成
*
* @param generatorTable generatorTable
* @return 结果
@ -50,13 +53,13 @@ public interface GeneratorTableService {
TableDataInfo<DbTableVo> selectPageDbTableList(TableDto dto, PageQuery pageQuery);
/**
* 通过表名查询
* 通过表名查询代码生成
*
* @param tableName 表名
* @param tableId 表ID
* @param allowNull 允许空
* @return GeneratorTable
*/
GeneratorTable selectByTableName(String tableName, boolean allowNull);
GeneratorTable selectByTableId(String tableId, boolean allowNull);
/**
* 导入表结构
@ -69,9 +72,34 @@ public interface GeneratorTableService {
/**
* 下载
*
* @param tableName 表名
* @param tableId 表ID
* @param templateType 模板类型(前端/后端/sql/全部)
* @return 文件字节
*/
byte[] downloadCode(String tableName);
byte[] downloadCode(String tableId, String templateType);
/**
* 预览代码
*
* @param tableId tableId
* @param templateType 模板类型(前端/后端/sql/全部)
* @return 结果
*/
Map<String, String> previewCode(String tableId, String templateType);
/**
* 批量删除代码生成
*
* @param tableIds tableIds
* @return 结果
*/
int deleteByIds(List<String> tableIds);
/**
* 同步表结构
*
* @param tableId 表ID
*/
void syncTable(String tableId);
}

View File

@ -28,8 +28,8 @@ public class GeneratorTableColumnServiceImpl implements GeneratorTableColumnServ
private final GeneratorTableColumnMapper generatorTableColumnMapper;
@Override
public List<TableColumnVo> selectVoListByTableName(String tableName, boolean allowNull) {
List<TableColumnVo> list = generatorTableColumnMapper.selectListByTableName(tableName);
public List<TableColumnVo> selectDbColumnList(String tableName, boolean allowNull) {
List<TableColumnVo> list = generatorTableColumnMapper.selectDbColumnList(tableName);
if (CollUtil.isEmpty(list) && !allowNull) {
throw new ServiceException(StrUtil.format("未查询到表字段信息, 表名: {}", tableName));
}
@ -53,8 +53,23 @@ public class GeneratorTableColumnServiceImpl implements GeneratorTableColumnServ
return generatorTableColumnMapper.insert(generatorTableColumn);
}
@Override
public void updateById(GeneratorTableColumn generatorTableColumn) {
generatorTableColumnMapper.updateById(generatorTableColumn);
}
@Override
public void updateBatchById(List<GeneratorTableColumn> columns) {
Db.updateBatchById(columns);
}
@Override
public void deleteByTableIds(List<String> tableIds) {
generatorTableColumnMapper.deleteByTableIds(tableIds);
}
@Override
public void deleteByIds(List<String> ids) {
generatorTableColumnMapper.deleteBatchIds(ids);
}
}

View File

@ -1,11 +1,10 @@
package com.qiaoba.module.generator.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.qiaoba.common.base.constants.BaseConstant;
import com.qiaoba.common.base.enums.BaseEnum;
import com.qiaoba.common.base.exceptions.ServiceException;
@ -30,12 +29,14 @@ import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@ -81,12 +82,10 @@ public class GeneratorTableServiceImpl implements GeneratorTableService {
}
@Override
public GeneratorTable selectByTableName(String tableName, boolean allowNull) {
QueryWrapper<GeneratorTable> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(GeneratorTable::getTableName, tableName);
GeneratorTable generatorTable = generatorTableMapper.selectOne(wrapper);
public GeneratorTable selectByTableId(String tableId, boolean allowNull) {
GeneratorTable generatorTable = generatorTableMapper.selectById(tableId);
if (Objects.isNull(generatorTable) && !allowNull) {
throw new ServiceException(StrUtil.format("未查到表信息, 表: {}", tableName));
throw new ServiceException(StrUtil.format("未查到表信息, 表ID: {}", tableId));
}
return generatorTable;
}
@ -96,7 +95,7 @@ public class GeneratorTableServiceImpl implements GeneratorTableService {
GeneratorTable generatorTable = GeneratorUtil.dtoToGeneratorTable(dto);
int result = generatorTableMapper.insert(generatorTable);
if (result > BaseConstant.HANDLE_ERROR) {
List<TableColumnVo> columnVos = generatorTableColumnService.selectVoListByTableName(dto.getTableName(), false);
List<TableColumnVo> columnVos = generatorTableColumnService.selectDbColumnList(dto.getTableName(), false);
for (TableColumnVo columnVo : columnVos) {
GeneratorTableColumn generatorTableColumn = GeneratorUtil.initColumn(columnVo, generatorTable.getTableId());
generatorTableColumnService.insert(generatorTableColumn);
@ -106,38 +105,103 @@ public class GeneratorTableServiceImpl implements GeneratorTableService {
}
@Override
public byte[] downloadCode(String tableName) {
public byte[] downloadCode(String tableId, String templateType) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream);
generatorCode(tableName, zip);
generatorCode(tableId, templateType, zip);
IoUtil.close(zip);
return outputStream.toByteArray();
}
private void generatorCode(String tableName, ZipOutputStream zip) {
@Override
public Map<String, String> previewCode(String tableId, String templateType) {
Map<String, String> dataMap = new LinkedHashMap<>();
// 查询表信息
GeneratorTable table = selectByTableName(tableName, false);
GeneratorTable table = selectByTableId(tableId, false);
// 查询字段信息
List<GeneratorTableColumn> columns = generatorTableColumnService.selectListByTableId(table.getTableId(), false);
Generator generator = new Generator(table, columns);
// 设置主键列信息
setPkColumn(generator);
// 设置查询字段信息
setQueryColumns(generator);
// 初始化 Velocity
VelocityFactory.init();
// 设置参数
VelocityContext context = VelocityUtil.setVariables(generator);
// 获取模板列表
List<String> templates = VelocityUtil.getTemplateList();
List<String> templates = VelocityUtil.getTemplateList(templateType);
for (String template : templates) {
// 渲染模板
StringWriter sw = new StringWriter();
Template tpl = Velocity.getTemplate(template, BaseConstant.UTF8);
tpl.merge(context, sw);
dataMap.put(template, sw.toString());
}
return dataMap;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteByIds(List<String> tableIds) {
int result = generatorTableMapper.deleteBatchIds(tableIds);
if (result > BaseConstant.HANDLE_ERROR) {
generatorTableColumnService.deleteByTableIds(tableIds);
}
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void syncTable(String tableId) {
// 查询表信息
GeneratorTable table = selectByTableId(tableId, false);
// 查询最新表结构
List<TableColumnVo> dbColumns = generatorTableColumnService.selectDbColumnList(table.getTableName(), false);
// 查询保存的表结构
List<GeneratorTableColumn> generatorTableColumns = generatorTableColumnService.selectListByTableId(tableId, false);
// 构造比较map
Map<String, GeneratorTableColumn> generatorTableColumnMap = generatorTableColumns.stream().collect(Collectors.toMap(GeneratorTableColumn::getColumnName, Function.identity()));
List<String> dbTableColumnNames = dbColumns.stream().map(TableColumnVo::getColumnName).collect(Collectors.toList());
// 开始比较
dbColumns.forEach(column -> {
GeneratorTableColumn generatorTableColumn = GeneratorUtil.initColumn(column, tableId);
// 字段名不变
if (generatorTableColumnMap.containsKey(column.getColumnName())) {
GeneratorTableColumn prevColumn = generatorTableColumnMap.get(column.getColumnName());
generatorTableColumn.setColumnId(prevColumn.getColumnId());
if (BaseEnum.YES.getCode().equals(generatorTableColumn.getIsList())) {
// 如果是列表,继续保留查询方式/字典类型选项
generatorTableColumn.setDictType(prevColumn.getDictType());
generatorTableColumn.setQueryType(prevColumn.getQueryType());
}
generatorTableColumnService.updateById(generatorTableColumn);
} else {
generatorTableColumnService.insert(generatorTableColumn);
}
});
List<String> deleteIds = new ArrayList<>();
for (GeneratorTableColumn generatorTableColumn : generatorTableColumns) {
if (!dbTableColumnNames.contains(generatorTableColumn.getColumnName())) {
deleteIds.add(generatorTableColumn.getColumnId());
}
}
if (CollUtil.isNotEmpty(deleteIds)) {
generatorTableColumnService.deleteByIds(deleteIds);
}
}
private void generatorCode(String tableId, String templateType, ZipOutputStream zip) {
// 查询表信息
GeneratorTable table = selectByTableId(tableId, false);
Map<String, String> dataMap = previewCode(tableId, templateType);
for (String key : dataMap.keySet()) {
String code = dataMap.get(key);
try {
// 添加到zip
zip.putNextEntry(new ZipEntry(VelocityUtil.getFileName(template, table)));
IoUtil.write(zip, false, sw.toString().getBytes());
IoUtil.close(sw);
zip.putNextEntry(new ZipEntry(VelocityUtil.getFileName(key, table)));
IoUtil.write(zip, false, code.getBytes());
zip.flush();
zip.closeEntry();
} catch (IOException e) {
@ -168,4 +232,14 @@ public class GeneratorTableServiceImpl implements GeneratorTableService {
generator.setPkColumn(generator.getColumns().get(0));
}
}
private void setQueryColumns(Generator generator) {
List<GeneratorTableColumn> queryColumns = new ArrayList<>();
for (GeneratorTableColumn column : generator.getColumns()) {
if (generator.isQueryColumn(column.getIsQuery())) {
queryColumns.add(column);
}
}
generator.setQueryColumns(queryColumns);
}
}

View File

@ -1,6 +1,7 @@
package com.qiaoba.module.generator.util;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.base.constants.BaseConstant;
import com.qiaoba.common.base.utils.ArrayUtil;
@ -11,6 +12,8 @@ import com.qiaoba.module.generator.entity.GeneratorTableColumn;
import com.qiaoba.module.generator.entity.dto.TableDto;
import com.qiaoba.module.generator.entity.vo.TableColumnVo;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
@ -35,23 +38,22 @@ public class GeneratorUtil {
column.setQueryType(GenConstants.QUERY_EQ);
column.setColumnType(vo.getColumnType());
setType(column, vo.getColumnType());
// 插入字段(默认所有字段都需要插入)
column.setIsInsert(GenConstants.REQUIRE);
column.setIsPk(vo.getIsPk());
column.setIsRequired(vo.getIsRequired());
// 编辑字段
if (!ArrayUtil.contains(GenConstants.COLUMNNAME_NOT_EDIT, column.getColumnName()) && !BaseConstant.YES.equals(column.getIsPk())) {
// (排除基类字段)
if (!ArrayUtil.contains(GenConstants.COLUMN_NAME_NOT_HANDLE, column.getColumnName()) && !BaseConstant.YES.equals(column.getIsPk())) {
column.setIsInsert(GenConstants.REQUIRE);
column.setIsEdit(GenConstants.REQUIRE);
}
// 列表字段
if (!ArrayUtil.contains(GenConstants.COLUMNNAME_NOT_LIST, column.getColumnName()) && !BaseConstant.YES.equals(column.getIsPk())) {
column.setIsList(GenConstants.REQUIRE);
}
// 查询字段
if (!ArrayUtil.contains(GenConstants.COLUMNNAME_NOT_QUERY, column.getColumnName()) && !BaseConstant.YES.equals(column.getIsPk())) {
column.setIsQuery(GenConstants.REQUIRE);
}
// 查询字段
if (ArrayUtil.containsValueIgnoreCase(GenConstants.HTML_LIKE_COLUMN, column.getColumnName())) {
column.setIsQuery(GenConstants.REQUIRE);
column.setQueryType(GenConstants.QUERY_LIKE);
}
return column;
}
@ -107,21 +109,21 @@ public class GeneratorUtil {
// varchar(50) -> varchar
columnType = StrUtil.subBefore(columnType, "(", false);
// 字符串 or 长文本
if (ArrayUtil.contains(GenConstants.COLUMNTYPE_STR, columnType) || ArrayUtil.contains(GenConstants.COLUMNTYPE_TEXT, columnType)) {
if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_STR, columnType) || ArrayUtil.contains(GenConstants.COLUMN_TYPE_TEXT, columnType)) {
// 字符串长度超过500设置为文本域
Integer columnLength = getColumnLength(column.getColumnType());
String htmlType = columnLength >= 500 || ArrayUtil.contains(GenConstants.COLUMNTYPE_TEXT, columnType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
String htmlType = columnLength >= 500 || ArrayUtil.contains(GenConstants.COLUMN_TYPE_TEXT, columnType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
column.setHtmlType(htmlType);
}
// 时间类型
if (ArrayUtil.contains(GenConstants.COLUMNTYPE_TIME, columnType)) {
if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_TIME, columnType)) {
column.setJavaType(GenConstants.TYPE_DATE);
column.setHtmlType(GenConstants.HTML_DATETIME);
}
// 数字类型
if (ArrayUtil.contains(GenConstants.COLUMNTYPE_NUMBER, columnType)) {
if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_NUMBER, columnType)) {
column.setHtmlType(GenConstants.HTML_INPUT);
// 如果是浮点型 统一用BigDecimal
List<String> strList = StrUtil.split(StrUtil.subBetween(column.getColumnType(), "(", ")"), ",");
@ -139,10 +141,6 @@ public class GeneratorUtil {
}
}
// 字段包含中 LIKE_COLUMN 设置 type = like
if (ArrayUtil.containsValueIgnoreCase(GenConstants.HTML_LIKE_COLUMN, column.getColumnName())) {
column.setQueryType(GenConstants.QUERY_LIKE);
}
// 单选框
if (ArrayUtil.containsValueIgnoreCase(GenConstants.HTML_RADIO_COLUMN, column.getColumnName())) {
column.setHtmlType(GenConstants.HTML_RADIO);
@ -181,4 +179,15 @@ public class GeneratorUtil {
}
}
/**
* 生成zip文件
*/
public static void download(HttpServletResponse response, byte[] data) throws IOException {
response.reset();
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.addHeader("Content-Length", String.valueOf(data.length));
response.setContentType("application/octet-stream; charset=UTF-8");
IoUtil.write(response.getOutputStream(), true, data);
}
}

View File

@ -3,7 +3,9 @@ package com.qiaoba.module.generator.util;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.base.constants.BaseConstant;
import com.qiaoba.common.base.context.BaseContext;
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;
@ -25,7 +27,6 @@ public class VelocityUtil {
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";
@ -45,30 +46,49 @@ public class VelocityUtil {
*/
private static final String MYBATIS_PATH = "main/resources/mapper";
/**
* 默认上级菜单,系统工具
*/
private static final String DEFAULT_PARENT_MENU_ID = "3";
/**
* 加载模板
*
* @return 模板集合
*/
public static List<String> getTemplateList() {
public static List<String> getTemplateList(String templateType) {
List<String> 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/vue/index.vue.vm");
// 全部
if (GenConstants.TEMPLATE_TYPE_ALL.equals(templateType)) {
// 后端
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/vue/index.vue.vm");
// SQL
templates.add("vm/sql/sql.vm");
}
// 后端
else if (GenConstants.TEMPLATE_TYPE_JAVA.equals(templateType)) {
// 后端
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");
}
// 前端
else if (GenConstants.TEMPLATE_TYPE_VUE.equals(templateType)) {
// 前端
templates.add("vm/js/api.js.vm");
templates.add("vm/vue/index.vue.vm");
} else {
// SQL
templates.add("vm/sql/sql.vm");
}
return templates;
}
@ -92,10 +112,10 @@ public class VelocityUtil {
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("queryColumns", generator.getQueryColumns());
velocityContext.put("table", generator.getTable());
velocityContext.put("generator", generator);
@ -107,7 +127,9 @@ public class VelocityUtil {
velocityContext.put("selectMenuId", new Snowflake().nextIdStr());
velocityContext.put("tenantId", BaseContext.getTenantId());
velocityContext.put("parentMenuId", "0");
String parentMenuId = generator.getTable().getParentMenuId();
velocityContext.put("parentMenuId", StrUtil.isNotBlank(parentMenuId) ? parentMenuId : BaseConstant.DEFAULT_PARENT_ID_VALUE);
return velocityContext;
}

View File

@ -13,10 +13,16 @@
<result property="sort" column="sort"/>
</resultMap>
<select id="selectListByTableName" resultMap="DbTableColumnVoResult">
<select id="selectDbColumnList" resultMap="DbTableColumnVoResult">
select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, column_type
from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
order by ordinal_position
</select>
<delete id="deleteByTableIds">
delete from generator_table_column where table_id in
<foreach collection="list" item="tableId" open="(" separator="," close=")">
#{tableId}
</foreach>
</delete>
</mapper>

View File

@ -15,8 +15,8 @@
<if test="dto.dbType=='MySQL'.toString()">
select table_name, table_comment, create_time, update_time from information_schema.tables
where table_schema = (select database())
AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%'
AND table_name NOT IN (select table_name from gen_table)
AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'generator_%'
AND table_name NOT IN (select table_name from generator_table)
<if test="dto.tableName != null and dto.tableName != ''">
AND lower(table_name) like lower(concat('%', #{dto.tableName}, '%'))
</if>
@ -34,7 +34,7 @@
and dt.table_name = uo.object_name
and uo.object_type = 'TABLE'
AND dt.table_name NOT LIKE 'XXL_JOB_%' AND dt.table_name NOT LIKE 'GEN_%'
AND dt.table_name NOT IN (select table_name from gen_table)
AND dt.table_name NOT IN (select table_name from generator_table)
<if test="dto.tableName != null and dto.tableName != ''">
AND lower(dt.table_name) like lower(concat(concat('%', #{dto.tableName}), '%'))
</if>
@ -59,7 +59,7 @@
AND n.nspname <![CDATA[ <> ]]> ''::name
) list_table
where table_name NOT LIKE 'xxl_job_%' AND table_name NOT LIKE 'gen_%'
AND table_name NOT IN (select table_name from gen_table)
AND table_name NOT IN (select table_name from generator_table)
<if test="dto.tableName != null and dto.tableName != ''">
AND lower(table_name) like lower(concat('%', #{dto.tableName}, '%'))
</if>

View File

@ -0,0 +1 @@
如果不慎使用了IDEA代码格式化, 导致代码生成出来的数据异常, 删除vm目录下的所有文件, 解压vm.zip下的文件即可

View File

@ -25,7 +25,6 @@ public class ${ClassName}Dto implements Serializable {
#if(!$generator.isBaseColumn($column.javaField))
## 是主键
#if($generator.isPk($column.isPk))
@Schema(description = "$column.columnComment")
private String $column.javaField;
## 不是主键

View File

@ -26,9 +26,6 @@ public class ${ClassName} extends BaseEntity{
#if(!$generator.isBaseColumn($column.javaField))
## 是主键
#if($generator.isPk($column.isPk))
/**
* $column.columnComment
*/
@TableId
private String $column.javaField;

View File

@ -4,10 +4,12 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.io.Serializable;
/**
* ${functionName} Param
* ${functionName} 查询参数
*
* @author ${author}
* @version 1.0
@ -18,5 +20,30 @@ import java.io.Serializable;
public class ${ClassName}Param implements Serializable {
private static final long serialVersionUID=1L;
## 遍历字段
#foreach ($column in $queryColumns)
#if($column.queryType == "BETWEEN")
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#if($column.javaType == "Date")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
#end
@Schema(description = "开始$column.columnComment")
private $column.javaType start$AttrName;
#if($column.javaType == "Date")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
#end
@Schema(description = "结束$column.columnComment")
private $column.javaType end$AttrName;
#else
#if($column.javaType == "Date")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
#end
@Schema(description = "$column.columnComment")
private $column.javaType $column.javaField;
#end
#end
}

View File

@ -2,6 +2,7 @@ package ${packageName}.service.impl;
import java.util.*;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qiaoba.auth.utils.SecurityUtil;
import com.qiaoba.common.base.exceptions.ServiceException;
@ -94,6 +95,30 @@ public class ${ClassName}ServiceImpl implements ${ClassName}Service {
private QueryWrapper<${ClassName}> param2Wrapper(${ClassName}Param param) {
QueryWrapper<${ClassName}> wrapper = new QueryWrapper<>();
#if($queryColumns.size() > 0)
wrapper.lambda()
#foreach ($column in $queryColumns)
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#if($column.queryType == "EQ")
.eq(ObjectUtil.isNotEmpty(param.get${AttrName}()), ${ClassName}::get${AttrName}, param.get${AttrName}())#if($foreach.count == $queryColumns.size());#end
#elseif($column.queryType == "NE")
.ne(ObjectUtil.isNotEmpty(param.get${AttrName}()), ${ClassName}::get${AttrName}, param.get${AttrName}())#if($foreach.count == $queryColumns.size());#end
#elseif($column.queryType == "GT")
.gt(ObjectUtil.isNotEmpty(param.get${AttrName}()), ${ClassName}::get${AttrName}, param.get${AttrName}())#if($foreach.count == $queryColumns.size());#end
#elseif($column.queryType == "GTE")
.ge(ObjectUtil.isNotEmpty(param.get${AttrName}()), ${ClassName}::get${AttrName}, param.get${AttrName}())#if($foreach.count == $queryColumns.size());#end
#elseif($column.queryType == "LT")
.lt(ObjectUtil.isNotEmpty(param.get${AttrName}()), ${ClassName}::get${AttrName}, param.get${AttrName}())#if($foreach.count == $queryColumns.size());#end
#elseif($column.queryType == "LTE")
.le(ObjectUtil.isNotEmpty(param.get${AttrName}()), ${ClassName}::get${AttrName}, param.get${AttrName}())#if($foreach.count == $queryColumns.size());#end
#elseif($column.queryType == "LIKE")
.like(ObjectUtil.isNotEmpty(param.get${AttrName}()), ${ClassName}::get${AttrName}, param.get${AttrName}())#if($foreach.count == $queryColumns.size());#end
#elseif($column.queryType == "BETWEEN")
.between((ObjectUtil.isNotEmpty(param.getStart${AttrName}()) && ObjectUtil.isNotEmpty(param.getEnd${AttrName}())),
${ClassName}::get${AttrName}, param.getStart${AttrName}(), param.getEnd${AttrName}())#if($foreach.count == $queryColumns.size());#end
#end
#end
#end
return wrapper;
}
}