diff --git a/pom.xml b/pom.xml index 5ba30552a..890e617d9 100644 --- a/pom.xml +++ b/pom.xml @@ -16,13 +16,15 @@ youlai-system youlai-auth + + youlai-generator + mall-sale mall-member mall-product mall-order - youlai-generator - youlai-generator + @@ -73,6 +75,8 @@ 3.5.6 2.3 + + 4.2.0 @@ -286,6 +290,12 @@ ${velocity.version} + + com.baomidou + dynamic-datasource-spring-boot3-starter + ${dynamic-datasource.version} + + diff --git a/youlai-generator/pom.xml b/youlai-generator/pom.xml index 5418f1193..f8ad02e6f 100644 --- a/youlai-generator/pom.xml +++ b/youlai-generator/pom.xml @@ -24,11 +24,16 @@ common-core + com.youlai common-mybatis + + com.baomidou + dynamic-datasource-spring-boot3-starter + diff --git a/youlai-generator/src/main/java/com/youlai/generator/controller/DatasourceController.java b/youlai-generator/src/main/java/com/youlai/generator/controller/DatasourceController.java new file mode 100644 index 000000000..09ccec951 --- /dev/null +++ b/youlai-generator/src/main/java/com/youlai/generator/controller/DatasourceController.java @@ -0,0 +1,44 @@ +package com.youlai.generator.controller; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.youlai.common.result.PageResult; +import com.youlai.generator.model.query.TablePageQuery; +import com.youlai.generator.model.vo.TablePageVO; +import com.youlai.generator.service.DatasourceService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 数据源控制器 + * + * @author Ray + * @since 2.10.0 + */ +@Tag(name = "数据源接口") +@RestController +@RequestMapping("/api/v1/datasources") +@RequiredArgsConstructor +public class DatasourceController { + + private final DatasourceService datasourceService; + + @GetMapping("/keys") + @Operation(summary = "获取所有数据源的key") + public List getAllDatasourceKeys() { + return datasourceService.getAllDatasourceKeys(); + } + + @Operation(summary = "获取数据表分页列表") + @GetMapping("/tables") + public PageResult getTablePage( + TablePageQuery queryParams + ) { + Page result = datasourceService.getTablePage(queryParams); + return PageResult.success(result); + } + +} diff --git a/youlai-generator/src/main/java/com/youlai/generator/controller/GeneratorController.java b/youlai-generator/src/main/java/com/youlai/generator/controller/GeneratorController.java index a102799d2..65f660bd2 100644 --- a/youlai-generator/src/main/java/com/youlai/generator/controller/GeneratorController.java +++ b/youlai-generator/src/main/java/com/youlai/generator/controller/GeneratorController.java @@ -1,14 +1,10 @@ package com.youlai.generator.controller; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.common.result.PageResult; import com.youlai.common.result.Result; import com.youlai.generator.config.GeneratorProperties; import com.youlai.generator.model.form.GenConfigForm; -import com.youlai.generator.model.query.TablePageQuery; -import com.youlai.generator.model.vo.GeneratorPreviewVO; -import com.youlai.generator.model.vo.TablePageVO; -import com.youlai.generator.service.GeneratorService; +import com.youlai.generator.model.vo.CodePreviewVO; +import com.youlai.generator.service.GenConfigService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -33,31 +29,23 @@ import java.util.List; @RequiredArgsConstructor public class GeneratorController { - private final GeneratorService generatorService; + private final GenConfigService genConfigService; private final GeneratorProperties generatorProperties; - @Operation(summary = "获取数据表分页列表") - @GetMapping("/table/page") - public PageResult getTablePage( - TablePageQuery queryParams - ) { - Page result = generatorService.getTablePage(queryParams); - return PageResult.success(result); - } @Operation(summary = "获取代码生成配置") @GetMapping("/{tableName}/config") public Result getGenConfigFormData( @Parameter(description = "表名", example = "sys_user") @PathVariable String tableName ) { - GenConfigForm formData = generatorService.getGenConfigFormData(tableName); + GenConfigForm formData = genConfigService.getGenConfigFormData(tableName); return Result.success(formData); } @Operation(summary = "保存代码生成配置") @PostMapping("/{tableName}/config") public Result saveGenConfig(@RequestBody GenConfigForm formData) { - generatorService.saveGenConfig(formData); + genConfigService.saveGenConfig(formData); return Result.success(); } @@ -66,14 +54,14 @@ public class GeneratorController { public Result deleteGenConfig( @Parameter(description = "表名", example = "sys_user") @PathVariable String tableName ) { - generatorService.deleteGenConfig(tableName); + genConfigService.deleteGenConfig(tableName); return Result.success(); } @Operation(summary = "获取预览生成代码") @GetMapping("/{tableName}/preview") - public Result> getTablePreviewData(@PathVariable String tableName) { - List list = generatorService.getTablePreviewData(tableName); + public Result> getCodePreviewData(@PathVariable String tableName) { + List list = genConfigService.getCodePreviewData(tableName); return Result.success(list); } @@ -81,7 +69,7 @@ public class GeneratorController { @GetMapping("/{tableName}/download") public void downloadZip(HttpServletResponse response, @PathVariable String tableName) throws IOException { String[] tableNames = tableName.split(","); - byte[] data = generatorService.downloadCode(tableNames); + byte[] data = genConfigService.downloadCode(tableNames); response.reset(); response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(generatorProperties.getDownloadFileName(), StandardCharsets.UTF_8)); response.addHeader("Access-Control-Allow-Origin", "*"); diff --git a/youlai-generator/src/main/java/com/youlai/generator/model/vo/GeneratorPreviewVO.java b/youlai-generator/src/main/java/com/youlai/generator/model/vo/CodePreviewVO.java similarity index 92% rename from youlai-generator/src/main/java/com/youlai/generator/model/vo/GeneratorPreviewVO.java rename to youlai-generator/src/main/java/com/youlai/generator/model/vo/CodePreviewVO.java index d18a4137d..16ec4e10b 100644 --- a/youlai-generator/src/main/java/com/youlai/generator/model/vo/GeneratorPreviewVO.java +++ b/youlai-generator/src/main/java/com/youlai/generator/model/vo/CodePreviewVO.java @@ -5,7 +5,7 @@ import lombok.Data; @Schema(description = "代码生成代码预览VO") @Data -public class GeneratorPreviewVO { +public class CodePreviewVO { @Schema(description = "生成文件路径") private String path; diff --git a/youlai-generator/src/main/java/com/youlai/generator/service/DatasourceService.java b/youlai-generator/src/main/java/com/youlai/generator/service/DatasourceService.java new file mode 100644 index 000000000..9dff8fb39 --- /dev/null +++ b/youlai-generator/src/main/java/com/youlai/generator/service/DatasourceService.java @@ -0,0 +1,35 @@ +package com.youlai.generator.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.youlai.generator.model.query.TablePageQuery; +import com.youlai.generator.model.vo.TablePageVO; + +import java.util.List; + +/** + * 数据源服务接口 + * + * @author Ray + * @since 4.0.0 + */ +public interface DatasourceService { + + /** + * 获取所有数据源 + * + * @return + */ + List getAllDatasourceKeys() ; + + + /** + * 获取数据表分页列表 + * + * @param queryParams 查询参数 + * @return + */ + Page getTablePage(TablePageQuery queryParams); + + + +} diff --git a/youlai-generator/src/main/java/com/youlai/generator/service/GenConfigService.java b/youlai-generator/src/main/java/com/youlai/generator/service/GenConfigService.java index 6c06e9908..b7ec96960 100644 --- a/youlai-generator/src/main/java/com/youlai/generator/service/GenConfigService.java +++ b/youlai-generator/src/main/java/com/youlai/generator/service/GenConfigService.java @@ -1,8 +1,11 @@ package com.youlai.generator.service; - import com.baomidou.mybatisplus.extension.service.IService; import com.youlai.generator.model.entity.GenConfig; +import com.youlai.generator.model.form.GenConfigForm; +import com.youlai.generator.model.vo.CodePreviewVO; + +import java.util.List; /** * 代码生成配置接口 @@ -13,5 +16,42 @@ import com.youlai.generator.model.entity.GenConfig; public interface GenConfigService extends IService { + /** + * 代码预览 + * + * @param tableName + * @return + */ + List getCodePreviewData(String tableName); + /** + * 获取代码生成配置 + * + * @param tableName 表名 + * @return + */ + GenConfigForm getGenConfigFormData(String tableName); + + /** + * 保存代码生成配置 + * + * @param formData 表单数据 + * @return + */ + void saveGenConfig(GenConfigForm formData); + + /** + * 删除代码生成配置 + * + * @param tableName 表名 + * @return + */ + void deleteGenConfig(String tableName); + + /** + * 下载代码 + * @param tableNames 表名 + * @return + */ + byte[] downloadCode(String[] tableNames); } diff --git a/youlai-generator/src/main/java/com/youlai/generator/service/GeneratorService.java b/youlai-generator/src/main/java/com/youlai/generator/service/GeneratorService.java deleted file mode 100644 index b7d7a1cb3..000000000 --- a/youlai-generator/src/main/java/com/youlai/generator/service/GeneratorService.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.youlai.generator.service; - -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.generator.model.form.GenConfigForm; -import com.youlai.generator.model.query.TablePageQuery; -import com.youlai.generator.model.vo.GeneratorPreviewVO; -import com.youlai.generator.model.vo.TablePageVO; - -import java.util.List; - -/** - * 代码生成配置接口 - * - * @author Ray - * @since 2.10.0 - */ -public interface GeneratorService { - - /** - * 获取数据表分页列表 - * - * @param queryParams 查询参数 - * @return - */ - Page getTablePage(TablePageQuery queryParams); - - /** - * 获取预览生成代码 - * - * @param tableName 表名 - * @return - */ - List getTablePreviewData(String tableName); - - /** - * 获取代码生成配置 - * - * @param tableName 表名 - * @return - */ - GenConfigForm getGenConfigFormData(String tableName); - - /** - * 保存代码生成配置 - * - * @param formData 表单数据 - * @return - */ - void saveGenConfig(GenConfigForm formData); - - /** - * 删除代码生成配置 - * - * @param tableName 表名 - * @return - */ - void deleteGenConfig(String tableName); - - /** - * 下载代码 - * @param tableNames 表名 - * @return - */ - byte[] downloadCode(String[] tableNames); -} diff --git a/youlai-generator/src/main/java/com/youlai/generator/service/impl/DatasourceServiceImpl.java b/youlai-generator/src/main/java/com/youlai/generator/service/impl/DatasourceServiceImpl.java new file mode 100644 index 000000000..cbe0b77e6 --- /dev/null +++ b/youlai-generator/src/main/java/com/youlai/generator/service/impl/DatasourceServiceImpl.java @@ -0,0 +1,62 @@ +package com.youlai.generator.service.impl; + +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.youlai.generator.config.GeneratorProperties; +import com.youlai.generator.mapper.DatabaseMapper; +import com.youlai.generator.model.query.TablePageQuery; +import com.youlai.generator.model.vo.TablePageVO; +import com.youlai.generator.service.DatasourceService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import javax.sql.DataSource; +import java.util.ArrayList; +import java.util.List; + +/** + * 数据源服务实现类 + * + * @author haoxr + * @since 4.0.0 + */ +@Service +@RequiredArgsConstructor +public class DatasourceServiceImpl implements DatasourceService { + + + private final DataSource dataSource; + private final DatabaseMapper databaseMapper; + private final GeneratorProperties generatorProperties; + + + /** + * 获取所有数据源 + * + * @return 数据源列表 + */ + + @Override + public List getAllDatasourceKeys() { + DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource; + return new ArrayList<>(ds.getDataSources().keySet()); + } + + + /** + * 数据表分页列表 + * + * @param queryParams 查询参数 + * @return 分页结果 + */ + public Page getTablePage(TablePageQuery queryParams) { + Page page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize()); + // 设置排除的表 + List excludeTables = generatorProperties.getExcludeTables(); + queryParams.setExcludeTables(excludeTables); + + return databaseMapper.getTablePage(page, queryParams); + } + + +} diff --git a/youlai-generator/src/main/java/com/youlai/generator/service/impl/GenConfigServiceImpl.java b/youlai-generator/src/main/java/com/youlai/generator/service/impl/GenConfigServiceImpl.java index fc50d2f23..ee15d1037 100644 --- a/youlai-generator/src/main/java/com/youlai/generator/service/impl/GenConfigServiceImpl.java +++ b/youlai-generator/src/main/java/com/youlai/generator/service/impl/GenConfigServiceImpl.java @@ -1,12 +1,43 @@ package com.youlai.generator.service.impl; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.template.Template; +import cn.hutool.extra.template.TemplateConfig; +import cn.hutool.extra.template.TemplateEngine; +import cn.hutool.extra.template.TemplateUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.youlai.common.core.exception.BusinessException; +import com.youlai.generator.config.GeneratorProperties; +import com.youlai.generator.converter.GenConfigConverter; +import com.youlai.generator.enums.FormTypeEnum; +import com.youlai.generator.enums.JavaTypeEnum; +import com.youlai.generator.enums.QueryTypeEnum; +import com.youlai.generator.mapper.DatabaseMapper; import com.youlai.generator.mapper.GenConfigMapper; +import com.youlai.generator.model.bo.ColumnMetaData; +import com.youlai.generator.model.bo.TableMetaData; import com.youlai.generator.model.entity.GenConfig; +import com.youlai.generator.model.entity.GenFieldConfig; +import com.youlai.generator.model.form.GenConfigForm; +import com.youlai.generator.model.vo.CodePreviewVO; import com.youlai.generator.service.GenConfigService; +import com.youlai.generator.service.GenFieldConfigService; import lombok.RequiredArgsConstructor; +import org.apache.tomcat.util.http.fileupload.IOUtils; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.zip.ZipOutputStream; + /** * 数据库服务实现类 * @@ -17,4 +48,413 @@ import org.springframework.stereotype.Service; @RequiredArgsConstructor public class GenConfigServiceImpl extends ServiceImpl implements GenConfigService { + private final DatabaseMapper databaseMapper; + private final GeneratorProperties generatorProperties; + private final GenFieldConfigService genFieldConfigService; + private final GenConfigConverter genConfigConverter; + /* private final MenuService menuService;*/ + + @Value("${spring.profiles.active}") + private String springProfilesActive; + + /** + * 获取代码生成配置 + * + * @param tableName 表名 eg: sys_user + * @return 代码生成配置 + */ + @Override + public GenConfigForm getGenConfigFormData(String tableName) { + // 查询表生成配置 + GenConfig genConfig = this.getOne( + new LambdaQueryWrapper<>(GenConfig.class) + .eq(GenConfig::getTableName, tableName) + .last("LIMIT 1") + ); + + // 是否有代码生成配置 + boolean hasGenConfig = genConfig != null; + + // 如果没有代码生成配置,则根据表的元数据生成默认配置 + if (genConfig == null) { + TableMetaData tableMetadata = databaseMapper.getTableMetadata(tableName); + Assert.isTrue(tableMetadata != null, "未找到表元数据"); + + genConfig = new GenConfig(); + genConfig.setTableName(tableName); + + String tableComment = tableMetadata.getTableComment(); + if (StrUtil.isNotBlank(tableComment)) { + genConfig.setBusinessName(tableComment.replace("表", "")); + } + // 实体类名 = 表名去掉前缀后转驼峰,前缀默认为下划线分割的第一个元素 + String entityName = StrUtil.toCamelCase(StrUtil.removePrefix(tableName, tableName.split("_")[0])); + genConfig.setEntityName(entityName); + + genConfig.setPackageName("com.youlai"); + // 默认模块名 + genConfig.setModuleName(generatorProperties.getDefaultConfig().getModuleName()); + genConfig.setAuthor(generatorProperties.getDefaultConfig().getAuthor()); + } + + // 根据表的列 + 已经存在的字段生成配置 得到 组合后的字段生成配置 + List genFieldConfigs = new ArrayList<>(); + + // 获取表的列 + List tableColumns = databaseMapper.getTableColumns(tableName); + if (CollectionUtil.isNotEmpty(tableColumns)) { + // 查询字段生成配置 + List fieldConfigList = genFieldConfigService.list( + new LambdaQueryWrapper() + .eq(GenFieldConfig::getConfigId, genConfig.getId()) + .orderByAsc(GenFieldConfig::getFieldSort) + ); + Integer maxSort = fieldConfigList.stream() + .map(GenFieldConfig::getFieldSort) + .filter(Objects::nonNull) // 过滤掉空值 + .max(Integer::compareTo) + .orElse(0); + for (ColumnMetaData tableColumn : tableColumns) { + // 根据列名获取字段生成配置 + String columnName = tableColumn.getColumnName(); + GenFieldConfig fieldConfig = fieldConfigList.stream() + .filter(item -> StrUtil.equals(item.getColumnName(), columnName)) + .findFirst() + .orElseGet(() -> createDefaultFieldConfig(tableColumn)); + if (fieldConfig.getFieldSort() == null) { + fieldConfig.setFieldSort(++maxSort); + } + // 根据列类型设置字段类型 + String fieldType = fieldConfig.getFieldType(); + if (StrUtil.isBlank(fieldType)) { + String javaType = JavaTypeEnum.getJavaTypeByColumnType(fieldConfig.getColumnType()); + fieldConfig.setFieldType(javaType); + } + // 如果没有代码生成配置,则默认展示在列表和表单 + if (!hasGenConfig) { + fieldConfig.setIsShowInList(1); + fieldConfig.setIsShowInForm(1); + } + genFieldConfigs.add(fieldConfig); + } + } + //对genFieldConfigs按照fieldSort排序 + genFieldConfigs = genFieldConfigs.stream().sorted(Comparator.comparing(GenFieldConfig::getFieldSort)).toList(); + GenConfigForm genConfigForm = genConfigConverter.toGenConfigForm(genConfig, genFieldConfigs); + + genConfigForm.setFrontendAppName(generatorProperties.getFrontendAppName()); + genConfigForm.setBackendAppName(generatorProperties.getBackendAppName()); + return genConfigForm; + } + + + /** + * 创建默认字段配置 + * + * @param columnMetaData 表字段元数据 + * @return + */ + private GenFieldConfig createDefaultFieldConfig(ColumnMetaData columnMetaData) { + GenFieldConfig fieldConfig = new GenFieldConfig(); + fieldConfig.setColumnName(columnMetaData.getColumnName()); + fieldConfig.setColumnType(columnMetaData.getDataType()); + fieldConfig.setFieldComment(columnMetaData.getColumnComment()); + fieldConfig.setFieldName(StrUtil.toCamelCase(columnMetaData.getColumnName())); + fieldConfig.setIsRequired("YES".equals(columnMetaData.getIsNullable()) ? 1 : 0); + + if (fieldConfig.getColumnType().equals("date")) { + fieldConfig.setFormType(FormTypeEnum.DATE); + } else if (fieldConfig.getColumnType().equals("datetime")) { + fieldConfig.setFormType(FormTypeEnum.DATE_TIME); + } else { + fieldConfig.setFormType(FormTypeEnum.INPUT); + } + + fieldConfig.setQueryType(QueryTypeEnum.EQ); + fieldConfig.setMaxLength(columnMetaData.getCharacterMaximumLength()); + return fieldConfig; + } + + /** + * 保存代码生成配置 + * + * @param formData 代码生成配置表单 + */ + @Override + public void saveGenConfig(GenConfigForm formData) { + GenConfig genConfig = genConfigConverter.toGenConfig(formData); + this.saveOrUpdate(genConfig); + + // 如果选择上级菜单 + Long parentMenuId = formData.getParentMenuId(); + if (parentMenuId != null && springProfilesActive.equals("dev")) { + // menuService.saveMenu(parentMenuId, genConfig); + } + + List genFieldConfigs = genConfigConverter.toGenFieldConfig(formData.getFieldConfigs()); + + if (CollectionUtil.isEmpty(genFieldConfigs)) { + throw new BusinessException("字段配置不能为空"); + } + genFieldConfigs.forEach(genFieldConfig -> { + genFieldConfig.setConfigId(genConfig.getId()); + }); + genFieldConfigService.saveOrUpdateBatch(genFieldConfigs); + } + + /** + * 删除代码生成配置 + * + * @param tableName 表名 + */ + @Override + public void deleteGenConfig(String tableName) { + GenConfig genConfig = this.getOne(new LambdaQueryWrapper() + .eq(GenConfig::getTableName, tableName)); + + boolean result = this.remove(new LambdaQueryWrapper() + .eq(GenConfig::getTableName, tableName) + ); + if (result) { + genFieldConfigService.remove(new LambdaQueryWrapper() + .eq(GenFieldConfig::getConfigId, genConfig.getId()) + ); + } + } + + + /** + * 获取预览生成代码 + * + * @param tableName 表名 + * @return 预览数据 + */ + @Override + public List getCodePreviewData(String tableName) { + + List list = new ArrayList<>(); + + GenConfig genConfig = this.getOne(new LambdaQueryWrapper() + .eq(GenConfig::getTableName, tableName) + ); + if (genConfig == null) { + throw new BusinessException("未找到表生成配置"); + } + + List fieldConfigs = genFieldConfigService.list(new LambdaQueryWrapper() + .eq(GenFieldConfig::getConfigId, genConfig.getId()) + .orderByAsc(GenFieldConfig::getFieldSort) + + ); + if (CollectionUtil.isEmpty(fieldConfigs)) { + throw new BusinessException("未找到字段生成配置"); + } + + // 遍历模板配置 + Map templateConfigs = generatorProperties.getTemplateConfigs(); + for (Map.Entry templateConfigEntry : templateConfigs.entrySet()) { + CodePreviewVO previewVO = new CodePreviewVO(); + + GeneratorProperties.TemplateConfig templateConfig = templateConfigEntry.getValue(); + + /* 1. 生成文件名 UserController */ + // User Role Menu Dept + String entityName = genConfig.getEntityName(); + // Controller Service Mapper Entity + String templateName = templateConfigEntry.getKey(); + // .java .ts .vue + String extension = templateConfig.getExtension(); + + // 文件名 UserController.java + String fileName = getFileName(entityName, templateName, extension); + previewVO.setFileName(fileName); + + /* 2. 生成文件路径 */ + // 包名:com.youlai.boot + String packageName = genConfig.getPackageName(); + // 模块名:system + String moduleName = genConfig.getModuleName(); + // 子包名:controller + String subpackageName = templateConfig.getSubpackageName(); + // 组合成文件路径:src/main/java/com/youlai/boot/system/controller + String filePath = getFilePath(templateName, moduleName, packageName, subpackageName, entityName); + previewVO.setPath(filePath); + + /* 3. 生成文件内容 */ + // 将模板文件中的变量替换为具体的值 生成代码内容 + String content = getCodeContent(templateConfig, genConfig, fieldConfigs); + previewVO.setContent(content); + + list.add(previewVO); + } + return list; + } + + /** + * 生成文件名 + * + * @param entityName 实体类名 UserController + * @param templateName 模板名 Entity + * @param extension 文件后缀 .java + * @return 文件名 + */ + private String getFileName(String entityName, String templateName, String extension) { + if ("Entity".equals(templateName)) { + return entityName + extension; + } else if ("MapperXml".equals(templateName)) { + return entityName + "Mapper" + extension; + } else if ("API".equals(templateName)) { + return StrUtil.toSymbolCase(entityName, '-') + extension; + } else if ("VIEW".equals(templateName)) { + return "index.vue"; + } + return entityName + templateName + extension; + } + + /** + * 生成文件路径 + * + * @param templateName 模板名 Entity + * @param moduleName 模块名 system + * @param packageName 包名 com.youlai + * @param subPackageName 子包名 controller + * @param entityName 实体类名 UserController + * @return 文件路径 src/main/java/com/youlai/system/controller + */ + private String getFilePath(String templateName, String moduleName, String packageName, String subPackageName, String entityName) { + String path; + if ("MapperXml".equals(templateName)) { + path = (generatorProperties.getBackendAppName() + + File.separator + + "src" + File.separator + "main" + File.separator + "resources" + + File.separator + subPackageName + ); + } else if ("API".equals(templateName)) { + path = (generatorProperties.getFrontendAppName() + + File.separator + + "src" + File.separator + subPackageName + ); + } else if ("VIEW".equals(templateName)) { + path = (generatorProperties.getFrontendAppName() + + File.separator + "src" + + File.separator + subPackageName + + File.separator + moduleName + + File.separator + StrUtil.toSymbolCase(entityName, '-') + ); + } else { + path = (generatorProperties.getBackendAppName() + + File.separator + + "src" + File.separator + "main" + File.separator + "java" + + File.separator + packageName + + File.separator + moduleName + + File.separator + subPackageName + ); + } + + // subPackageName = model.entity => model/entity + path = path.replace(".", File.separator); + + return path; + } + + /** + * 生成代码内容 + * + * @param templateConfig 模板配置 + * @param genConfig 生成配置 + * @param fieldConfigs 字段配置 + * @return 代码内容 + */ + private String getCodeContent(GeneratorProperties.TemplateConfig templateConfig, GenConfig genConfig, List fieldConfigs) { + + Map bindMap = new HashMap<>(); + + String entityName = genConfig.getEntityName(); + + bindMap.put("packageName", genConfig.getPackageName()); + bindMap.put("moduleName", genConfig.getModuleName()); + bindMap.put("subpackageName", templateConfig.getSubpackageName()); + bindMap.put("date", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm")); + bindMap.put("entityName", entityName); + bindMap.put("tableName", genConfig.getTableName()); + bindMap.put("author", genConfig.getAuthor()); + // UserTest → userTest + bindMap.put("lowerFirstEntityName", StrUtil.lowerFirst(entityName)); + // UserTest → user-test + bindMap.put("kebabCaseEntityName", StrUtil.toSymbolCase(entityName, '-')); + bindMap.put("businessName", genConfig.getBusinessName()); + bindMap.put("fieldConfigs", fieldConfigs); + + boolean hasLocalDateTime = false; + boolean hasBigDecimal = false; + boolean hasRequiredField = false; + + for (GenFieldConfig fieldConfig : fieldConfigs) { + + if ("LocalDateTime".equals(fieldConfig.getFieldType())) { + hasLocalDateTime = true; + } + if ("BigDecimal".equals(fieldConfig.getFieldType())) { + hasBigDecimal = true; + } + if (ObjectUtil.equals(fieldConfig.getIsRequired(), 1)) { + hasRequiredField = true; + } + fieldConfig.setTsType(JavaTypeEnum.getTsTypeByJavaType(fieldConfig.getFieldType())); + + + } + + bindMap.put("hasLocalDateTime", hasLocalDateTime); + bindMap.put("hasBigDecimal", hasBigDecimal); + bindMap.put("hasRequiredField", hasRequiredField); + + TemplateEngine templateEngine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH)); + Template template = templateEngine.getTemplate(templateConfig.getTemplatePath()); + String content = template.render(bindMap); + + return content; + } + + /** + * 下载代码 + * + * @param tableNames 表名,可以支持多张表。 + * @return 压缩文件字节数组 + */ + @Override + public byte[] downloadCode(String[] tableNames) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + for (String tableName : tableNames) { + generatorCode(tableName, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + + + /** + * 根据表名生成代码并且压缩到zip文件中 + * + * @param tableName 单个表名 + * @param zip 压缩文件 + */ + private void generatorCode(String tableName, ZipOutputStream zip) { + List previewVOList = getCodePreviewData(tableName); + for (CodePreviewVO previewVO : previewVOList) { + String fileName = previewVO.getFileName(); + String content = previewVO.getContent(); + String path = previewVO.getPath(); + try { + zip.putNextEntry(new java.util.zip.ZipEntry(path + File.separator + fileName)); + zip.write(content.getBytes(StandardCharsets.UTF_8)); + zip.closeEntry(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } diff --git a/youlai-generator/src/main/java/com/youlai/generator/service/impl/GenFieldConfigServiceImpl.java b/youlai-generator/src/main/java/com/youlai/generator/service/impl/GenFieldConfigServiceImpl.java index 8a39c1484..465878ea4 100644 --- a/youlai-generator/src/main/java/com/youlai/generator/service/impl/GenFieldConfigServiceImpl.java +++ b/youlai-generator/src/main/java/com/youlai/generator/service/impl/GenFieldConfigServiceImpl.java @@ -1,9 +1,9 @@ package com.youlai.generator.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.youlai.boot.platform.generator.mapper.GenFieldConfigMapper; -import com.youlai.boot.platform.generator.model.entity.GenFieldConfig; -import com.youlai.boot.platform.generator.service.GenFieldConfigService; +import com.youlai.generator.mapper.GenFieldConfigMapper; +import com.youlai.generator.model.entity.GenFieldConfig; +import com.youlai.generator.service.GenFieldConfigService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,4 +18,5 @@ import org.springframework.stereotype.Service; public class GenFieldConfigServiceImpl extends ServiceImpl implements GenFieldConfigService { + } diff --git a/youlai-generator/src/main/java/com/youlai/generator/service/impl/GeneratorServiceImpl.java b/youlai-generator/src/main/java/com/youlai/generator/service/impl/GeneratorServiceImpl.java deleted file mode 100644 index 8533d9f8c..000000000 --- a/youlai-generator/src/main/java/com/youlai/generator/service/impl/GeneratorServiceImpl.java +++ /dev/null @@ -1,473 +0,0 @@ -package com.youlai.generator.service.impl; - -import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.template.Template; -import cn.hutool.extra.template.TemplateConfig; -import cn.hutool.extra.template.TemplateEngine; -import cn.hutool.extra.template.TemplateUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.common.core.exception.BusinessException; -import com.youlai.generator.config.GeneratorProperties; -import com.youlai.generator.converter.GenConfigConverter; -import com.youlai.generator.enums.FormTypeEnum; -import com.youlai.generator.enums.JavaTypeEnum; -import com.youlai.generator.enums.QueryTypeEnum; -import com.youlai.generator.mapper.DatabaseMapper; -import com.youlai.generator.model.bo.ColumnMetaData; -import com.youlai.generator.model.bo.TableMetaData; -import com.youlai.generator.model.entity.GenConfig; -import com.youlai.generator.model.entity.GenFieldConfig; -import com.youlai.generator.model.form.GenConfigForm; -import com.youlai.generator.model.query.TablePageQuery; -import com.youlai.generator.model.vo.GeneratorPreviewVO; -import com.youlai.generator.model.vo.TablePageVO; -import com.youlai.generator.service.GenConfigService; -import com.youlai.generator.service.GenFieldConfigService; -import com.youlai.generator.service.GeneratorService; -import lombok.RequiredArgsConstructor; -import org.apache.tomcat.util.http.fileupload.IOUtils; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.zip.ZipOutputStream; - -/** - * 数据库服务实现类 - * - * @author Ray - * @since 2.10.0 - */ -@Service -@RequiredArgsConstructor -public class GeneratorServiceImpl implements GeneratorService { - - private final DatabaseMapper databaseMapper; - private final GeneratorProperties generatorProperties; - private final GenConfigService genConfigService; - private final GenFieldConfigService genFieldConfigService; - private final GenConfigConverter genConfigConverter; - /* private final MenuService menuService;*/ - - @Value("${spring.profiles.active}") - private String springProfilesActive; - - /** - * 数据表分页列表 - * - * @param queryParams 查询参数 - * @return 分页结果 - */ - public Page getTablePage(TablePageQuery queryParams) { - Page page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize()); - // 设置排除的表 - List excludeTables = generatorProperties.getExcludeTables(); - queryParams.setExcludeTables(excludeTables); - - return databaseMapper.getTablePage(page, queryParams); - } - - /** - * 获取代码生成配置 - * - * @param tableName 表名 eg: sys_user - * @return 代码生成配置 - */ - @Override - public GenConfigForm getGenConfigFormData(String tableName) { - // 查询表生成配置 - GenConfig genConfig = genConfigService.getOne( - new LambdaQueryWrapper<>(GenConfig.class) - .eq(GenConfig::getTableName, tableName) - .last("LIMIT 1") - ); - - // 是否有代码生成配置 - boolean hasGenConfig = genConfig != null; - - // 如果没有代码生成配置,则根据表的元数据生成默认配置 - if (genConfig == null) { - TableMetaData tableMetadata = databaseMapper.getTableMetadata(tableName); - Assert.isTrue(tableMetadata != null, "未找到表元数据"); - - genConfig = new GenConfig(); - genConfig.setTableName(tableName); - - String tableComment = tableMetadata.getTableComment(); - if (StrUtil.isNotBlank(tableComment)) { - genConfig.setBusinessName(tableComment.replace("表", "")); - } - // 实体类名 = 表名去掉前缀后转驼峰,前缀默认为下划线分割的第一个元素 - String entityName = StrUtil.toCamelCase(StrUtil.removePrefix(tableName, tableName.split("_")[0])); - genConfig.setEntityName(entityName); - - genConfig.setPackageName("com.youlai"); - genConfig.setModuleName(generatorProperties.getDefaultConfig().getModuleName()); // 默认模块名 - genConfig.setAuthor(generatorProperties.getDefaultConfig().getAuthor()); - } - - // 根据表的列 + 已经存在的字段生成配置 得到 组合后的字段生成配置 - List genFieldConfigs = new ArrayList<>(); - - // 获取表的列 - List tableColumns = databaseMapper.getTableColumns(tableName); - if (CollectionUtil.isNotEmpty(tableColumns)) { - // 查询字段生成配置 - List fieldConfigList = genFieldConfigService.list( - new LambdaQueryWrapper() - .eq(GenFieldConfig::getConfigId, genConfig.getId()) - .orderByAsc(GenFieldConfig::getFieldSort) - ); - Integer maxSort = fieldConfigList.stream() - .map(GenFieldConfig::getFieldSort) - .filter(Objects::nonNull) // 过滤掉空值 - .max(Integer::compareTo) - .orElse(0); - for (ColumnMetaData tableColumn : tableColumns) { - // 根据列名获取字段生成配置 - String columnName = tableColumn.getColumnName(); - GenFieldConfig fieldConfig = fieldConfigList.stream() - .filter(item -> StrUtil.equals(item.getColumnName(), columnName)) - .findFirst() - .orElseGet(() -> createDefaultFieldConfig(tableColumn)); - if (fieldConfig.getFieldSort() == null) { - fieldConfig.setFieldSort(++maxSort); - } - // 根据列类型设置字段类型 - String fieldType = fieldConfig.getFieldType(); - if (StrUtil.isBlank(fieldType)) { - String javaType = JavaTypeEnum.getJavaTypeByColumnType(fieldConfig.getColumnType()); - fieldConfig.setFieldType(javaType); - } - // 如果没有代码生成配置,则默认展示在列表和表单 - if (!hasGenConfig) { - fieldConfig.setIsShowInList(1); - fieldConfig.setIsShowInForm(1); - } - genFieldConfigs.add(fieldConfig); - } - } - //对genFieldConfigs按照fieldSort排序 - genFieldConfigs = genFieldConfigs.stream().sorted(Comparator.comparing(GenFieldConfig::getFieldSort)).toList(); - GenConfigForm genConfigForm = genConfigConverter.toGenConfigForm(genConfig, genFieldConfigs); - - genConfigForm.setFrontendAppName(generatorProperties.getFrontendAppName()); - genConfigForm.setBackendAppName(generatorProperties.getBackendAppName()); - return genConfigForm; - } - - - /** - * 创建默认字段配置 - * - * @param columnMetaData 表字段元数据 - * @return - */ - private GenFieldConfig createDefaultFieldConfig(ColumnMetaData columnMetaData) { - GenFieldConfig fieldConfig = new GenFieldConfig(); - fieldConfig.setColumnName(columnMetaData.getColumnName()); - fieldConfig.setColumnType(columnMetaData.getDataType()); - fieldConfig.setFieldComment(columnMetaData.getColumnComment()); - fieldConfig.setFieldName(StrUtil.toCamelCase(columnMetaData.getColumnName())); - fieldConfig.setIsRequired("YES".equals(columnMetaData.getIsNullable()) ? 1 : 0); - - if (fieldConfig.getColumnType().equals("date")) { - fieldConfig.setFormType(FormTypeEnum.DATE); - } else if (fieldConfig.getColumnType().equals("datetime")) { - fieldConfig.setFormType(FormTypeEnum.DATE_TIME); - } else { - fieldConfig.setFormType(FormTypeEnum.INPUT); - } - - fieldConfig.setQueryType(QueryTypeEnum.EQ); - fieldConfig.setMaxLength(columnMetaData.getCharacterMaximumLength()); - return fieldConfig; - } - - /** - * 保存代码生成配置 - * - * @param formData 代码生成配置表单 - */ - @Override - public void saveGenConfig(GenConfigForm formData) { - GenConfig genConfig = genConfigConverter.toGenConfig(formData); - genConfigService.saveOrUpdate(genConfig); - - // 如果选择上级菜单 - Long parentMenuId = formData.getParentMenuId(); - if (parentMenuId != null && springProfilesActive.equals("dev")) { - // menuService.saveMenu(parentMenuId, genConfig); - } - - List genFieldConfigs = genConfigConverter.toGenFieldConfig(formData.getFieldConfigs()); - - if (CollectionUtil.isEmpty(genFieldConfigs)) { - throw new BusinessException("字段配置不能为空"); - } - genFieldConfigs.forEach(genFieldConfig -> { - genFieldConfig.setConfigId(genConfig.getId()); - }); - genFieldConfigService.saveOrUpdateBatch(genFieldConfigs); - } - - /** - * 删除代码生成配置 - * - * @param tableName 表名 - */ - @Override - public void deleteGenConfig(String tableName) { - GenConfig genConfig = genConfigService.getOne(new LambdaQueryWrapper() - .eq(GenConfig::getTableName, tableName)); - - boolean result = genConfigService.remove(new LambdaQueryWrapper() - .eq(GenConfig::getTableName, tableName) - ); - if (result) { - genFieldConfigService.remove(new LambdaQueryWrapper() - .eq(GenFieldConfig::getConfigId, genConfig.getId()) - ); - } - } - - - /** - * 获取预览生成代码 - * - * @param tableName 表名 - * @return 预览数据 - */ - @Override - public List getTablePreviewData(String tableName) { - - List list = new ArrayList<>(); - - GenConfig genConfig = genConfigService.getOne(new LambdaQueryWrapper() - .eq(GenConfig::getTableName, tableName) - ); - if (genConfig == null) { - throw new BusinessException("未找到表生成配置"); - } - - List fieldConfigs = genFieldConfigService.list(new LambdaQueryWrapper() - .eq(GenFieldConfig::getConfigId, genConfig.getId()) - .orderByAsc(GenFieldConfig::getFieldSort) - - ); - if (CollectionUtil.isEmpty(fieldConfigs)) { - throw new BusinessException("未找到字段生成配置"); - } - - // 遍历模板配置 - Map templateConfigs = generatorProperties.getTemplateConfigs(); - for (Map.Entry templateConfigEntry : templateConfigs.entrySet()) { - GeneratorPreviewVO previewVO = new GeneratorPreviewVO(); - - GeneratorProperties.TemplateConfig templateConfig = templateConfigEntry.getValue(); - - /* 1. 生成文件名 UserController */ - // User Role Menu Dept - String entityName = genConfig.getEntityName(); - // Controller Service Mapper Entity - String templateName = templateConfigEntry.getKey(); - // .java .ts .vue - String extension = templateConfig.getExtension(); - - // 文件名 UserController.java - String fileName = getFileName(entityName, templateName, extension); - previewVO.setFileName(fileName); - - /* 2. 生成文件路径 */ - // 包名:com.youlai.boot - String packageName = genConfig.getPackageName(); - // 模块名:system - String moduleName = genConfig.getModuleName(); - // 子包名:controller - String subpackageName = templateConfig.getSubpackageName(); - // 组合成文件路径:src/main/java/com/youlai/boot/system/controller - String filePath = getFilePath(templateName, moduleName, packageName, subpackageName, entityName); - previewVO.setPath(filePath); - - /* 3. 生成文件内容 */ - // 将模板文件中的变量替换为具体的值 生成代码内容 - String content = getCodeContent(templateConfig, genConfig, fieldConfigs); - previewVO.setContent(content); - - list.add(previewVO); - } - return list; - } - - /** - * 生成文件名 - * - * @param entityName 实体类名 UserController - * @param templateName 模板名 Entity - * @param extension 文件后缀 .java - * @return 文件名 - */ - private String getFileName(String entityName, String templateName, String extension) { - if ("Entity".equals(templateName)) { - return entityName + extension; - } else if ("MapperXml".equals(templateName)) { - return entityName + "Mapper" + extension; - } else if ("API".equals(templateName)) { - return StrUtil.toSymbolCase(entityName, '-') + extension; - } else if ("VIEW".equals(templateName)) { - return "index.vue"; - } - return entityName + templateName + extension; - } - - /** - * 生成文件路径 - * - * @param templateName 模板名 Entity - * @param moduleName 模块名 system - * @param packageName 包名 com.youlai - * @param subPackageName 子包名 controller - * @param entityName 实体类名 UserController - * @return 文件路径 src/main/java/com/youlai/system/controller - */ - private String getFilePath(String templateName, String moduleName, String packageName, String subPackageName, String entityName) { - String path; - if ("MapperXml".equals(templateName)) { - path = (generatorProperties.getBackendAppName() - + File.separator - + "src" + File.separator + "main" + File.separator + "resources" - + File.separator + subPackageName - ); - } else if ("API".equals(templateName)) { - path = (generatorProperties.getFrontendAppName() - + File.separator - + "src" + File.separator + subPackageName - ); - } else if ("VIEW".equals(templateName)) { - path = (generatorProperties.getFrontendAppName() - + File.separator + "src" - + File.separator + subPackageName - + File.separator + moduleName - + File.separator + StrUtil.toSymbolCase(entityName, '-') - ); - } else { - path = (generatorProperties.getBackendAppName() - + File.separator - + "src" + File.separator + "main" + File.separator + "java" - + File.separator + packageName - + File.separator + moduleName - + File.separator + subPackageName - ); - } - - // subPackageName = model.entity => model/entity - path = path.replace(".", File.separator); - - return path; - } - - /** - * 生成代码内容 - * - * @param templateConfig 模板配置 - * @param genConfig 生成配置 - * @param fieldConfigs 字段配置 - * @return 代码内容 - */ - private String getCodeContent(GeneratorProperties.TemplateConfig templateConfig, GenConfig genConfig, List fieldConfigs) { - - Map bindMap = new HashMap<>(); - - String entityName = genConfig.getEntityName(); - - bindMap.put("packageName", genConfig.getPackageName()); - bindMap.put("moduleName", genConfig.getModuleName()); - bindMap.put("subpackageName", templateConfig.getSubpackageName()); - bindMap.put("date", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm")); - bindMap.put("entityName", entityName); - bindMap.put("tableName", genConfig.getTableName()); - bindMap.put("author", genConfig.getAuthor()); - bindMap.put("lowerFirstEntityName", StrUtil.lowerFirst(entityName)); // UserTest → userTest - bindMap.put("kebabCaseEntityName", StrUtil.toSymbolCase(entityName, '-')); // UserTest → user-test - bindMap.put("businessName", genConfig.getBusinessName()); - bindMap.put("fieldConfigs", fieldConfigs); - - boolean hasLocalDateTime = false; - boolean hasBigDecimal = false; - boolean hasRequiredField = false; - - for (GenFieldConfig fieldConfig : fieldConfigs) { - - if ("LocalDateTime".equals(fieldConfig.getFieldType())) { - hasLocalDateTime = true; - } - if ("BigDecimal".equals(fieldConfig.getFieldType())) { - hasBigDecimal = true; - } - if (ObjectUtil.equals(fieldConfig.getIsRequired(), 1)) { - hasRequiredField = true; - } - fieldConfig.setTsType(JavaTypeEnum.getTsTypeByJavaType(fieldConfig.getFieldType())); - - - } - - bindMap.put("hasLocalDateTime", hasLocalDateTime); - bindMap.put("hasBigDecimal", hasBigDecimal); - bindMap.put("hasRequiredField", hasRequiredField); - - TemplateEngine templateEngine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH)); - Template template = templateEngine.getTemplate(templateConfig.getTemplatePath()); - String content = template.render(bindMap); - - return content; - } - - /** - * 下载代码 - * - * @param tableNames 表名,可以支持多张表。 - * @return 压缩文件字节数组 - */ - @Override - public byte[] downloadCode(String[] tableNames) { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - ZipOutputStream zip = new ZipOutputStream(outputStream); - for (String tableName : tableNames) { - generatorCode(tableName, zip); - } - IOUtils.closeQuietly(zip); - return outputStream.toByteArray(); - } - - /** - * 根据表名生成代码并且压缩到zip文件中 - * - * @param tableName 单个表名 - * @param zip 压缩文件 - */ - private void generatorCode(String tableName, ZipOutputStream zip) { - List previewVOList = getTablePreviewData(tableName); - for (GeneratorPreviewVO previewVO : previewVOList) { - String fileName = previewVO.getFileName(); - String content = previewVO.getContent(); - String path = previewVO.getPath(); - try { - zip.putNextEntry(new java.util.zip.ZipEntry(path + File.separator + fileName)); - zip.write(content.getBytes(StandardCharsets.UTF_8)); - zip.closeEntry(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - -} diff --git a/youlai-generator/src/main/resources/bootstrap-dev.yml b/youlai-generator/src/main/resources/bootstrap-dev.yml new file mode 100644 index 000000000..5f27cc1fd --- /dev/null +++ b/youlai-generator/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,56 @@ +server: + port: 8810 + +spring: + main: + allow-circular-references: true + mvc: + path-match: + matching-strategy: ant_path_matcher + cloud: + nacos: + # 注册中心 + discovery: + server-addr: http://localhost:8848 + # 配置中心 + config: + server-addr: http://localhost:8848 + file-extension: yaml + shared-configs[0]: + data-id: youlai-common.yaml + refresh: true + datasource: + dynamic: + primary: youlai_system #设置默认的数据源或者数据源组,默认值即为 master + strict: false # 设置严格模式,当数据源找不到时,是否抛出异常,默认为false不抛出 + datasource: + youlai_system: # 系统库 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置 + url: jdbc:mysql://localhost:3306/youlai_system?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true + username: youlai + password: 123456 + youlai_mall_oms: # 订单库 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/youlai_mall_oms?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true + username: youlai + password: 123456 + youlai_mall_pms: # 商品库 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/youlai_mall_pms?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true + username: youlai + password: 123456 + youlai_mall_sms: # 营销库 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/youlai_mall_sms?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true + username: youlai + password: 123456 + youlai_mall_ums: # 会员库 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/youlai_mall_ums?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true + username: youlai + password: 123456 \ No newline at end of file diff --git a/youlai-generator/src/main/resources/bootstrap-prod.yml b/youlai-generator/src/main/resources/bootstrap-prod.yml new file mode 100644 index 000000000..ee419540a --- /dev/null +++ b/youlai-generator/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,56 @@ +server: + port: 8810 + +spring: + main: + allow-circular-references: true + mvc: + pathmatch: + matching-strategy: ant_path_matcher + cloud: + nacos: + discovery: + server-addr: http://localhost:8848 + namespace: youlai-mall-prod + config: + server-addr: ${spring.cloud.nacos.discovery.server-addr} + file-extension: yaml + namespace: youlai-mall-prod + shared-configs[0]: + data-id: youlai-common.yaml + refresh: true + datasource: + dynamic: + primary: youlai_system #设置默认的数据源或者数据源组,默认值即为 master + strict: false # 设置严格模式,当数据源找不到时,是否抛出异常,默认为false不抛出 + datasource: + youlai_system: # 系统库 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置 + url: jdbc:mysql://localhost:3306/youlai_system?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true + username: youlai + password: 123456 + youlai_mall_oms: # 订单库 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/youlai_mall_oms?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true + username: youlai + password: 123456 + youlai_mall_pms: # 商品库 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/youlai_mall_pms?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true + username: youlai + password: 123456 + youlai_mall_sms: # 营销库 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/youlai_mall_sms?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true + username: youlai + password: 123456 + youlai_mall_ums: # 会员库 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/youlai_mall_ums?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true + username: youlai + password: 123456 \ No newline at end of file diff --git a/youlai-generator/src/main/resources/bootstrap.yml b/youlai-generator/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..184a6d087 --- /dev/null +++ b/youlai-generator/src/main/resources/bootstrap.yml @@ -0,0 +1,66 @@ +spring: + application: + name: youlai-generator + profiles: + active: dev + +# 代码生成器配置 +generator: + # 下载代码文件名称 + downloadFileName: youlai-mall-code.zip + # 后端项目名称 + backendAppName: youlai-mall + # 前端项目名称 + frontendAppName: mall-admin + # 默认配置 + defaultConfig: + author: youlaitech + moduleName: system + # 排除数据表 + excludeTables: + - gen_config + - gen_field_config + ## 模板配置 + templateConfigs: + API: + templatePath: api.ts.vm + subpackageName: api + extension: .ts + VIEW: + templatePath: index.vue.vm + subpackageName: views + extension: .vue + Controller: + templatePath: controller.java.vm + subpackageName: controller + Service: + templatePath: service.java.vm + subpackageName: service + ServiceImpl: + templatePath: serviceImpl.java.vm + subpackageName: service.impl + Mapper: + templatePath: mapper.java.vm + subpackageName: mapper + MapperXml: + templatePath: mapper.xml.vm + subpackageName: mapper + extension: .xml + Converter: + templatePath: converter.java.vm + subpackageName: converter + Query: + templatePath: query.java.vm + subpackageName: model.query + Form: + templatePath: form.java.vm + subpackageName: model.form + VO: + templatePath: vo.java.vm + subpackageName: model.vo + Entity: + templatePath: entity.java.vm + subpackageName: model.entity + + +