| | |
| | | import cn.hutool.core.lang.Dict; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.dynamic.datasource.annotation.DS; |
| | | import com.baomidou.dynamic.datasource.annotation.DSTransactional; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.anyline.metadata.Column; |
| | | import org.anyline.metadata.Table; |
| | | import org.anyline.proxy.ServiceProxy; |
| | | import org.apache.velocity.Template; |
| | | import org.apache.velocity.VelocityContext; |
| | | import org.apache.velocity.app.Velocity; |
| | | import org.dromara.common.core.constant.Constants; |
| | | import org.dromara.generator.constant.GenConstants; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.core.utils.file.FileUtils; |
| | |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.generator.constant.GenConstants; |
| | | import org.dromara.generator.domain.GenTable; |
| | | import org.dromara.generator.domain.GenTableColumn; |
| | | import org.dromara.generator.mapper.GenTableColumnMapper; |
| | |
| | | import org.dromara.generator.util.GenUtils; |
| | | import org.dromara.generator.util.VelocityInitializer; |
| | | import org.dromara.generator.util.VelocityUtils; |
| | | 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 org.springframework.transaction.annotation.Transactional; |
| | | |
| | |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @DS("#header.datasource") |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @Service |
| | |
| | | private final GenTableMapper baseMapper; |
| | | private final GenTableColumnMapper genTableColumnMapper; |
| | | private final IdentifierGenerator identifierGenerator; |
| | | |
| | | private static final String[] TABLE_IGNORE = new String[]{"sj_", "act_", "flw_", "gen_"}; |
| | | |
| | | /** |
| | | * 查询业务字段列表 |
| | |
| | | private QueryWrapper<GenTable> buildGenTableQueryWrapper(GenTable genTable) { |
| | | Map<String, Object> params = genTable.getParams(); |
| | | QueryWrapper<GenTable> wrapper = Wrappers.query(); |
| | | wrapper.like(StringUtils.isNotBlank(genTable.getTableName()), "lower(table_name)", StringUtils.lowerCase(genTable.getTableName())) |
| | | wrapper |
| | | .eq(StringUtils.isNotEmpty(genTable.getDataName()), "data_name", genTable.getDataName()) |
| | | .like(StringUtils.isNotBlank(genTable.getTableName()), "lower(table_name)", StringUtils.lowerCase(genTable.getTableName())) |
| | | .like(StringUtils.isNotBlank(genTable.getTableComment()), "lower(table_comment)", StringUtils.lowerCase(genTable.getTableComment())) |
| | | .between(params.get("beginTime") != null && params.get("endTime") != null, |
| | | "create_time", params.get("beginTime"), params.get("endTime")); |
| | | return wrapper; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 查询数据库列表 |
| | | * |
| | | * @param genTable 包含查询条件的GenTable对象 |
| | | * @param pageQuery 包含分页信息的PageQuery对象 |
| | | * @return 包含分页结果的TableDataInfo对象 |
| | | */ |
| | | @DS("#genTable.dataName") |
| | | @Override |
| | | public TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery) { |
| | | Page<GenTable> page = baseMapper.selectPageDbTableList(pageQuery.build(), genTable); |
| | | // 获取查询条件 |
| | | String tableName = genTable.getTableName(); |
| | | String tableComment = genTable.getTableComment(); |
| | | |
| | | LinkedHashMap<String, Table<?>> tablesMap = ServiceProxy.metadata().tables(); |
| | | if (CollUtil.isEmpty(tablesMap)) { |
| | | return TableDataInfo.build(); |
| | | } |
| | | List<String> tableNames = baseMapper.selectTableNameList(genTable.getDataName()); |
| | | String[] tableArrays; |
| | | if (CollUtil.isNotEmpty(tableNames)) { |
| | | tableArrays = tableNames.toArray(new String[0]); |
| | | } else { |
| | | tableArrays = new String[0]; |
| | | } |
| | | // 过滤并转换表格数据 |
| | | List<GenTable> tables = tablesMap.values().stream() |
| | | .filter(x -> !StringUtils.containsAnyIgnoreCase(x.getName(), TABLE_IGNORE)) |
| | | .filter(x -> { |
| | | if (CollUtil.isEmpty(tableNames)) { |
| | | return true; |
| | | } |
| | | return !StringUtils.equalsAnyIgnoreCase(x.getName(), tableArrays); |
| | | }) |
| | | .filter(x -> { |
| | | boolean nameMatches = true; |
| | | boolean commentMatches = true; |
| | | // 进行表名称的模糊查询 |
| | | if (StringUtils.isNotBlank(tableName)) { |
| | | nameMatches = StringUtils.containsIgnoreCase(x.getName(), tableName); |
| | | } |
| | | // 进行表描述的模糊查询 |
| | | if (StringUtils.isNotBlank(tableComment)) { |
| | | commentMatches = StringUtils.containsIgnoreCase(x.getComment(), tableComment); |
| | | } |
| | | // 同时匹配名称和描述 |
| | | return nameMatches && commentMatches; |
| | | }) |
| | | .map(x -> { |
| | | GenTable gen = new GenTable(); |
| | | gen.setTableName(x.getName()); |
| | | gen.setTableComment(x.getComment()); |
| | | gen.setCreateTime(x.getCreateTime()); |
| | | gen.setUpdateTime(x.getUpdateTime()); |
| | | return gen; |
| | | }).toList(); |
| | | |
| | | IPage<GenTable> page = pageQuery.build(); |
| | | page.setTotal(tables.size()); |
| | | // 手动分页 set数据 |
| | | page.setRecords(CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), tables)); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | |
| | | * 查询据库列表 |
| | | * |
| | | * @param tableNames 表名称组 |
| | | * @param dataName 数据源名称 |
| | | * @return 数据库表集合 |
| | | */ |
| | | @DS("#dataName") |
| | | @Override |
| | | public List<GenTable> selectDbTableListByNames(String[] tableNames) { |
| | | return baseMapper.selectDbTableListByNames(tableNames); |
| | | public List<GenTable> selectDbTableListByNames(String[] tableNames, String dataName) { |
| | | Set<String> tableNameSet = new HashSet<>(List.of(tableNames)); |
| | | LinkedHashMap<String, Table<?>> tablesMap = ServiceProxy.metadata().tables(); |
| | | |
| | | if (CollUtil.isEmpty(tablesMap)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | List<Table<?>> tableList = tablesMap.values().stream() |
| | | .filter(x -> !StringUtils.containsAnyIgnoreCase(x.getName(), TABLE_IGNORE)) |
| | | .filter(x -> tableNameSet.contains(x.getName())).toList(); |
| | | |
| | | if (CollUtil.isEmpty(tableList)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | return tableList.stream().map(x -> { |
| | | GenTable gen = new GenTable(); |
| | | gen.setDataName(dataName); |
| | | gen.setTableName(x.getName()); |
| | | gen.setTableComment(x.getComment()); |
| | | gen.setCreateTime(x.getCreateTime()); |
| | | gen.setUpdateTime(x.getUpdateTime()); |
| | | return gen; |
| | | }).toList(); |
| | | } |
| | | |
| | | /** |
| | |
| | | * 修改业务 |
| | | * |
| | | * @param genTable 业务信息 |
| | | * @return 结果 |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | |
| | | * 删除业务对象 |
| | | * |
| | | * @param tableIds 需要删除的数据ID |
| | | * @return 结果 |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public void deleteGenTableByIds(Long[] tableIds) { |
| | | List<Long> ids = Arrays.asList(tableIds); |
| | | baseMapper.deleteBatchIds(ids); |
| | | baseMapper.deleteByIds(ids); |
| | | genTableColumnMapper.delete(new LambdaQueryWrapper<GenTableColumn>().in(GenTableColumn::getTableId, ids)); |
| | | } |
| | | |
| | |
| | | * 导入表结构 |
| | | * |
| | | * @param tableList 导入表列表 |
| | | * @param dataName 数据源名称 |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @DSTransactional |
| | | @Override |
| | | public void importGenTable(List<GenTable> tableList) { |
| | | String operName = LoginHelper.getUsername(); |
| | | public void importGenTable(List<GenTable> tableList, String dataName) { |
| | | Long operId = LoginHelper.getUserId(); |
| | | try { |
| | | for (GenTable table : tableList) { |
| | | String tableName = table.getTableName(); |
| | | GenUtils.initTable(table, operName); |
| | | GenUtils.initTable(table, operId); |
| | | table.setDataName(dataName); |
| | | int row = baseMapper.insert(table); |
| | | if (row > 0) { |
| | | // 保存列信息 |
| | | List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); |
| | | List<GenTableColumn> genTableColumns = SpringUtils.getAopProxy(this).selectDbTableColumnsByName(tableName, dataName); |
| | | List<GenTableColumn> saveColumns = new ArrayList<>(); |
| | | for (GenTableColumn column : genTableColumns) { |
| | | GenUtils.initColumnField(column, table); |
| | |
| | | } catch (Exception e) { |
| | | throw new ServiceException("导入失败:" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据表名称查询列信息 |
| | | * |
| | | * @param tableName 表名称 |
| | | * @param dataName 数据源名称 |
| | | * @return 列信息 |
| | | */ |
| | | @DS("#dataName") |
| | | @Override |
| | | public List<GenTableColumn> selectDbTableColumnsByName(String tableName, String dataName) { |
| | | LinkedHashMap<String, Column> columns = ServiceProxy.metadata().columns(tableName); |
| | | List<GenTableColumn> tableColumns = new ArrayList<>(); |
| | | columns.forEach((columnName, column) -> { |
| | | GenTableColumn tableColumn = new GenTableColumn(); |
| | | tableColumn.setIsPk(String.valueOf(column.isPrimaryKey())); |
| | | tableColumn.setColumnName(column.getName()); |
| | | tableColumn.setColumnComment(column.getComment()); |
| | | tableColumn.setColumnType(column.getTypeName().toLowerCase()); |
| | | tableColumn.setSort(column.getPosition()); |
| | | tableColumn.setIsRequired(column.isNullable() == 0 ? "1" : "0"); |
| | | tableColumn.setIsIncrement(column.isAutoIncrement() == -1 ? "0" : "1"); |
| | | tableColumns.add(tableColumn); |
| | | }); |
| | | return tableColumns; |
| | | } |
| | | |
| | | /** |
| | |
| | | /** |
| | | * 生成代码(下载方式) |
| | | * |
| | | * @param tableName 表名称 |
| | | * @param tableId 表名称 |
| | | * @return 数据 |
| | | */ |
| | | @Override |
| | | public byte[] downloadCode(String tableName) { |
| | | public byte[] downloadCode(Long tableId) { |
| | | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| | | ZipOutputStream zip = new ZipOutputStream(outputStream); |
| | | generatorCode(tableName, zip); |
| | | generatorCode(tableId, zip); |
| | | IoUtil.close(zip); |
| | | return outputStream.toByteArray(); |
| | | } |
| | |
| | | /** |
| | | * 生成代码(自定义路径) |
| | | * |
| | | * @param tableName 表名称 |
| | | * @param tableId 表名称 |
| | | */ |
| | | @Override |
| | | public void generatorCode(String tableName) { |
| | | public void generatorCode(Long tableId) { |
| | | // 查询表信息 |
| | | GenTable table = baseMapper.selectGenTableByName(tableName); |
| | | GenTable table = baseMapper.selectGenTableById(tableId); |
| | | // 设置主键列信息 |
| | | setPkColumn(table); |
| | | |
| | |
| | | /** |
| | | * 同步数据库 |
| | | * |
| | | * @param tableName 表名称 |
| | | * @param tableId 表名称 |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @DSTransactional |
| | | @Override |
| | | public void synchDb(String tableName) { |
| | | GenTable table = baseMapper.selectGenTableByName(tableName); |
| | | public void synchDb(Long tableId) { |
| | | GenTable table = baseMapper.selectGenTableById(tableId); |
| | | List<GenTableColumn> tableColumns = table.getColumns(); |
| | | Map<String, GenTableColumn> tableColumnMap = StreamUtils.toIdentityMap(tableColumns, GenTableColumn::getColumnName); |
| | | |
| | | List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); |
| | | List<GenTableColumn> dbTableColumns = SpringUtils.getAopProxy(this).selectDbTableColumnsByName(table.getTableName(), table.getDataName()); |
| | | if (CollUtil.isEmpty(dbTableColumns)) { |
| | | throw new ServiceException("同步数据失败,原表结构不存在"); |
| | | } |
| | |
| | | List<GenTableColumn> delColumns = StreamUtils.filter(tableColumns, column -> !dbTableColumnNames.contains(column.getColumnName())); |
| | | if (CollUtil.isNotEmpty(delColumns)) { |
| | | List<Long> ids = StreamUtils.toList(delColumns, GenTableColumn::getColumnId); |
| | | genTableColumnMapper.deleteBatchIds(ids); |
| | | if (CollUtil.isNotEmpty(ids)) { |
| | | genTableColumnMapper.deleteByIds(ids); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 批量生成代码(下载方式) |
| | | * |
| | | * @param tableNames 表数组 |
| | | * @param tableIds 表ID数组 |
| | | * @return 数据 |
| | | */ |
| | | @Override |
| | | public byte[] downloadCode(String[] tableNames) { |
| | | public byte[] downloadCode(String[] tableIds) { |
| | | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| | | ZipOutputStream zip = new ZipOutputStream(outputStream); |
| | | for (String tableName : tableNames) { |
| | | generatorCode(tableName, zip); |
| | | for (String tableId : tableIds) { |
| | | generatorCode(Long.parseLong(tableId), zip); |
| | | } |
| | | IoUtil.close(zip); |
| | | return outputStream.toByteArray(); |
| | |
| | | /** |
| | | * 查询表信息并生成代码 |
| | | */ |
| | | private void generatorCode(String tableName, ZipOutputStream zip) { |
| | | private void generatorCode(Long tableId, ZipOutputStream zip) { |
| | | // 查询表信息 |
| | | GenTable table = baseMapper.selectGenTableByName(tableName); |
| | | GenTable table = baseMapper.selectGenTableById(tableId); |
| | | List<Long> menuIds = new ArrayList<>(); |
| | | for (int i = 0; i < 6; i++) { |
| | | menuIds.add(identifierGenerator.nextId(null).longValue()); |