mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 10:57:13 +08:00 
			
		
		
		
	feat: 新增生成代码接口(后端代码)
This commit is contained in:
		| @@ -16,11 +16,15 @@ | ||||
|  | ||||
| package top.charles7c.cnadmin.tool.config.properties; | ||||
|  | ||||
| import java.util.Map; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| import cn.hutool.core.map.MapUtil; | ||||
|  | ||||
| /** | ||||
|  * 代码生成器配置属性 | ||||
|  * | ||||
| @@ -36,4 +40,26 @@ public class GeneratorProperties { | ||||
|      * 排除数据表(哪些数据表不展示在代码生成中) | ||||
|      */ | ||||
|     private String[] excludeTables; | ||||
|  | ||||
|     /** | ||||
|      * 模板配置 | ||||
|      */ | ||||
|     private Map<String, TemplateConfig> templateConfigs = MapUtil.newHashMap(true); | ||||
|  | ||||
|     /** | ||||
|      * 模板配置 | ||||
|      */ | ||||
|     @Data | ||||
|     public static class TemplateConfig { | ||||
|  | ||||
|         /** | ||||
|          * 模板路径 | ||||
|          */ | ||||
|         private String templatePath; | ||||
|  | ||||
|         /** | ||||
|          * 包名称 | ||||
|          */ | ||||
|         private String packageName; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -18,19 +18,25 @@ package top.charles7c.cnadmin.tool.model.entity; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.validation.constraints.NotBlank; | ||||
| import javax.validation.constraints.NotNull; | ||||
| import javax.validation.constraints.Pattern; | ||||
|  | ||||
| import lombok.AccessLevel; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
| import lombok.Setter; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import org.hibernate.validator.constraints.Length; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.*; | ||||
| import com.fasterxml.jackson.annotation.JsonIgnore; | ||||
|  | ||||
| import cn.hutool.core.util.StrUtil; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.constant.RegexConsts; | ||||
|  | ||||
| @@ -78,6 +84,7 @@ public class GenConfigDO implements Serializable { | ||||
|      */ | ||||
|     @Schema(description = "前端路径") | ||||
|     @Length(max = 255, message = "前端路径不能超过 {max} 个字符") | ||||
|     @Pattern(regexp = "^(?=.*src\\/views)(?!.*\\/views\\/?$).*", message = "前端路径配置错误") | ||||
|     private String frontendPath; | ||||
|  | ||||
|     /** | ||||
| @@ -123,7 +130,28 @@ public class GenConfigDO implements Serializable { | ||||
|     @TableField(fill = FieldFill.INSERT_UPDATE) | ||||
|     private LocalDateTime updateTime; | ||||
|  | ||||
|     /** | ||||
|      * 类名前缀 | ||||
|      */ | ||||
|     @Setter(AccessLevel.NONE) | ||||
|     @JsonIgnore | ||||
|     @TableField(exist = false) | ||||
|     private String classNamePrefix; | ||||
|  | ||||
|     /** | ||||
|      * 字段配置信息 | ||||
|      */ | ||||
|     @JsonIgnore | ||||
|     @TableField(exist = false) | ||||
|     private List<FieldConfigDO> fieldConfigs; | ||||
|  | ||||
|     public GenConfigDO(String tableName) { | ||||
|         this.tableName = tableName; | ||||
|     } | ||||
|  | ||||
|     public String getClassNamePrefix() { | ||||
|         String rawClassName = StrUtil.isNotBlank(this.tablePrefix) | ||||
|             ? StrUtil.removePrefix(this.tableName, this.tablePrefix) : this.tableName; | ||||
|         return StrUtil.upperFirst(StrUtil.toCamelCase(rawClassName)); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -43,16 +43,16 @@ public class GenConfigRequest implements Serializable { | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 字段配置 | ||||
|      * 字段配置信息 | ||||
|      */ | ||||
|     @Schema(description = "字段配置") | ||||
|     @Schema(description = "字段配置信息") | ||||
|     @NotEmpty(message = "字段配置不能为空") | ||||
|     private List<FieldConfigDO> fieldConfigs = new ArrayList<>(); | ||||
|  | ||||
|     /** | ||||
|      * 生成配置 | ||||
|      * 生成配置信息 | ||||
|      */ | ||||
|     @Schema(description = "生成配置") | ||||
|     @Schema(description = "生成配置信息") | ||||
|     @NotNull(message = "生成配置不能为空") | ||||
|     private GenConfigDO genConfig; | ||||
| } | ||||
|   | ||||
| @@ -79,4 +79,12 @@ public interface GeneratorService { | ||||
|      *            表名称 | ||||
|      */ | ||||
|     void saveConfig(GenConfigRequest request, String tableName); | ||||
|  | ||||
|     /** | ||||
|      * 生成代码 | ||||
|      * | ||||
|      * @param tableName | ||||
|      *            表名称 | ||||
|      */ | ||||
|     void generate(String tableName); | ||||
| } | ||||
|   | ||||
| @@ -16,6 +16,8 @@ | ||||
|  | ||||
| package top.charles7c.cnadmin.tool.service.impl; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.sql.SQLException; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| @@ -35,15 +37,24 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
|  | ||||
| import cn.hutool.core.bean.BeanUtil; | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.date.DateUtil; | ||||
| import cn.hutool.core.io.FileUtil; | ||||
| import cn.hutool.core.io.file.FileNameUtil; | ||||
| import cn.hutool.core.map.MapUtil; | ||||
| import cn.hutool.core.util.ClassUtil; | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import cn.hutool.db.meta.Column; | ||||
| import cn.hutool.system.SystemUtil; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.constant.StringConsts; | ||||
| import top.charles7c.cnadmin.common.enums.QueryTypeEnum; | ||||
| import top.charles7c.cnadmin.common.exception.ServiceException; | ||||
| import top.charles7c.cnadmin.common.model.query.PageQuery; | ||||
| import top.charles7c.cnadmin.common.model.vo.PageDataVO; | ||||
| import top.charles7c.cnadmin.common.util.TemplateUtils; | ||||
| import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||
| import top.charles7c.cnadmin.tool.config.properties.GeneratorProperties; | ||||
| import top.charles7c.cnadmin.tool.config.properties.GeneratorProperties.TemplateConfig; | ||||
| import top.charles7c.cnadmin.tool.mapper.FieldConfigMapper; | ||||
| import top.charles7c.cnadmin.tool.mapper.GenConfigMapper; | ||||
| import top.charles7c.cnadmin.tool.model.entity.FieldConfigDO; | ||||
| @@ -182,6 +193,10 @@ public class GeneratorServiceImpl implements GeneratorService { | ||||
|  | ||||
|         // 保存或更新生成配置信息 | ||||
|         GenConfigDO newGenConfig = request.getGenConfig(); | ||||
|         String frontendPath = newGenConfig.getFrontendPath(); | ||||
|         if (StrUtil.isNotBlank(frontendPath)) { | ||||
|             CheckUtils.throwIf(!StrUtil.containsAll(frontendPath, "src", "views"), "前端路径配置错误"); | ||||
|         } | ||||
|         GenConfigDO oldGenConfig = genConfigMapper.selectById(tableName); | ||||
|         if (null != oldGenConfig) { | ||||
|             BeanUtil.copyProperties(newGenConfig, oldGenConfig); | ||||
| @@ -190,4 +205,122 @@ public class GeneratorServiceImpl implements GeneratorService { | ||||
|             genConfigMapper.insert(newGenConfig); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void generate(String tableName) { | ||||
|         GenConfigDO genConfig = genConfigMapper.selectById(tableName); | ||||
|         CheckUtils.throwIfNull(genConfig, "请先进行数据表 [{}] 生成配置", tableName); | ||||
|         List<FieldConfigDO> fieldConfigList = fieldConfigMapper.selectListByTableName(tableName); | ||||
|         CheckUtils.throwIfEmpty(fieldConfigList, "请先进行数据表 [{}] 字段配置", tableName); | ||||
|         Map<String, Object> genConfigMap = this.pretreatment(genConfig, fieldConfigList); | ||||
|  | ||||
|         try { | ||||
|             String classNamePrefix = genConfig.getClassNamePrefix(); | ||||
|             Boolean isOverride = genConfig.getIsOverride(); | ||||
|             // 生成后端代码 | ||||
|             // 1、确定后端代码基础路径 | ||||
|             // 例如:D:/continew-admin | ||||
|             String projectPath = SystemUtil.getUserInfo().getCurrentDir(); | ||||
|             // 例如:D:/continew-admin/continew-admin-tool | ||||
|             File backendModuleFile = new File(projectPath, genConfig.getModuleName()); | ||||
|             // 例如:D:/continew-admin/continew-admin-tool/src/main/java/top/charles7c/cnadmin/tool | ||||
|             List<String> backendModuleChildPathList = CollUtil.newArrayList("src", "main", "java"); | ||||
|             backendModuleChildPathList.addAll(StrUtil.split(genConfig.getPackageName(), StringConsts.DOT)); | ||||
|             File backendParentFile = | ||||
|                 FileUtil.file(backendModuleFile, backendModuleChildPathList.toArray(new String[0])); | ||||
|             // 2、生成代码 | ||||
|             Map<String, TemplateConfig> templateConfigMap = generatorProperties.getTemplateConfigs(); | ||||
|             for (Map.Entry<String, TemplateConfig> templateConfigEntry : templateConfigMap.entrySet()) { | ||||
|                 // 例如:D:/continew-admin/continew-admin-tool/src/main/java/top/charles7c/cnadmin/tool/service/impl/XxxServiceImpl.java | ||||
|                 TemplateConfig templateConfig = templateConfigEntry.getValue(); | ||||
|                 String subPackageName = templateConfig.getPackageName(); | ||||
|                 genConfigMap.put("subPackageName", subPackageName); | ||||
|                 File classParentFile = | ||||
|                     FileUtil.file(backendParentFile, StrUtil.splitToArray(subPackageName, StringConsts.DOT)); | ||||
|                 String className = classNamePrefix + StrUtil.nullToEmpty(templateConfigEntry.getKey()); | ||||
|                 genConfigMap.put("className", className); | ||||
|                 File classFile = new File(classParentFile, className + FileNameUtil.EXT_JAVA); | ||||
|                 // 如果已经存在,且不允许覆盖,则跳过 | ||||
|                 if (classFile.exists() && !isOverride) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 String content = TemplateUtils.render(templateConfig.getTemplatePath(), genConfigMap); | ||||
|                 FileUtil.writeString(content, classFile, StandardCharsets.UTF_8); | ||||
|             } | ||||
|  | ||||
|             // 生成前端代码 | ||||
|             String frontendPath = genConfig.getFrontendPath(); | ||||
|             if (StrUtil.isBlank(frontendPath)) { | ||||
|                 return; | ||||
|             } | ||||
|             // 1、生成 api 代码 | ||||
|             // 例如:D:/continew-admin/continew-admin-ui | ||||
|             List<String> frontendSubPathList = StrUtil.split(frontendPath, "src"); | ||||
|             String frontendModulePath = frontendSubPathList.get(0); | ||||
|             // 例如:D:/continew-admin/continew-admin-ui/src/api/tool/xxx.ts | ||||
|             String moduleSimpleName = new File(frontendPath).getName(); | ||||
|             File apiParentFile = FileUtil.file(frontendModulePath, "src", "api", moduleSimpleName); | ||||
|             String apiFileName = classNamePrefix.toLowerCase() + ".ts"; | ||||
|             File apiFile = new File(apiParentFile, apiFileName); | ||||
|             if (apiFile.exists() && !isOverride) { | ||||
|                 return; | ||||
|             } | ||||
|             String apiContent = TemplateUtils.render("generator/api.ftl", genConfigMap); | ||||
|             FileUtil.writeString(apiContent, apiFile, StandardCharsets.UTF_8); | ||||
|             // 2、生成 view 代码 | ||||
|             // 例如:D:/continew-admin/continew-admin-ui/src/views/tool/xxx/index.vue | ||||
|             File indexFile = FileUtil.file(frontendPath, classNamePrefix, "index.vue"); | ||||
|             if (indexFile.exists() && !isOverride) { | ||||
|                 return; | ||||
|             } | ||||
|             String indexContent = TemplateUtils.render("generator/index.ftl", genConfigMap); | ||||
|             FileUtil.writeString(indexContent, indexFile, StandardCharsets.UTF_8); | ||||
|         } catch (Exception e) { | ||||
|             log.error("Generate code occurred an error: {}. tableName: {}.", e.getMessage(), tableName, e); | ||||
|             throw new ServiceException("代码生成失败,请手动清理生成文件"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 预处理生成配置 | ||||
|      * | ||||
|      * @param genConfig | ||||
|      *            生成配置 | ||||
|      * @param fieldConfigList | ||||
|      *            字段配置列表 | ||||
|      * @return 处理后的生成配置 | ||||
|      */ | ||||
|     private Map<String, Object> pretreatment(GenConfigDO genConfig, List<FieldConfigDO> fieldConfigList) { | ||||
|         Map<String, Object> genConfigMap = MapUtil.newHashMap(); | ||||
|         genConfigMap.put("date", DateUtil.date().toString("yyyy/MM/dd HH:mm")); | ||||
|         genConfigMap.put("hasLocalDateTime", false); | ||||
|         genConfigMap.put("hasBigDecimal", false); | ||||
|         genConfigMap.put("hasRequiredField", false); | ||||
|         genConfigMap.put("hasListQueryField", false); | ||||
|         for (FieldConfigDO fieldConfig : fieldConfigList) { | ||||
|             String fieldType = fieldConfig.getFieldType(); | ||||
|             if ("LocalDateTime".equals(fieldType)) { | ||||
|                 genConfigMap.put("hasLocalDateTime", true); | ||||
|             } | ||||
|             if ("BigDecimal".equals(fieldType)) { | ||||
|                 genConfigMap.put("hasLocalDateTime", true); | ||||
|             } | ||||
|             if (Boolean.TRUE.equals(fieldConfig.getIsRequired())) { | ||||
|                 genConfigMap.put("hasRequiredField", true); | ||||
|             } | ||||
|             QueryTypeEnum queryType = fieldConfig.getQueryType(); | ||||
|             if (null != queryType && StrUtil.equalsAny(queryType.name(), QueryTypeEnum.IN.name(), | ||||
|                 QueryTypeEnum.NOT_IN.name(), QueryTypeEnum.BETWEEN.name())) { | ||||
|                 genConfigMap.put("hasListQueryField", true); | ||||
|             } | ||||
|         } | ||||
|         genConfig.setFieldConfigs(fieldConfigList); | ||||
|         genConfigMap.putAll(BeanUtil.beanToMap(genConfig)); | ||||
|         String packageName = genConfig.getPackageName(); | ||||
|         String moduleName = | ||||
|             StrUtil.subSuf(packageName, StrUtil.lastIndexOfIgnoreCase(packageName, StringConsts.DOT) + 1); | ||||
|         genConfigMap.put("moduleName", moduleName); | ||||
|         genConfigMap.put("apiName", StrUtil.lowerFirst(genConfig.getClassNamePrefix())); | ||||
|         return genConfigMap; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,42 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package ${packageName}.${subPackageName}; | ||||
|  | ||||
| import static top.charles7c.cnadmin.common.annotation.CrudRequestMapping.Api; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||||
|  | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.annotation.CrudRequestMapping; | ||||
| import top.charles7c.cnadmin.common.base.BaseController; | ||||
| import ${packageName}.model.query.${classNamePrefix}Query; | ||||
| import ${packageName}.model.request.${classNamePrefix}Request; | ||||
| import ${packageName}.model.vo.${classNamePrefix}DetailVO; | ||||
| import ${packageName}.model.vo.${classNamePrefix}VO; | ||||
| import ${packageName}.service.${classNamePrefix}Service; | ||||
|  | ||||
| /** | ||||
|  * ${businessName}管理 API | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @since ${date} | ||||
|  */ | ||||
| @Tag(name = "${businessName}管理 API") | ||||
| @RestController | ||||
| @CrudRequestMapping(value = "/${moduleName}/${apiName}", api = {Api.PAGE, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT}) | ||||
| public class ${className} extends BaseController<${classNamePrefix}Service, ${classNamePrefix}VO, ${classNamePrefix}DetailVO, ${classNamePrefix}Query, ${classNamePrefix}Request> {} | ||||
| @@ -0,0 +1,58 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package ${packageName}.${subPackageName}; | ||||
|  | ||||
| <#if hasLocalDateTime> | ||||
| import java.time.LocalDateTime; | ||||
| </#if> | ||||
| <#if hasBigDecimal> | ||||
| import java.math.BigDecimal; | ||||
| </#if> | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.base.BaseDetailVO; | ||||
|  | ||||
| /** | ||||
|  * ${businessName}详情信息 | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @since ${date} | ||||
|  */ | ||||
| @Data | ||||
| @ExcelIgnoreUnannotated | ||||
| @Schema(description = "${businessName}详情信息") | ||||
| public class ${className} extends BaseDetailVO { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
| <#if fieldConfigs??> | ||||
|   <#list fieldConfigs as fieldConfig> | ||||
|  | ||||
|     /** | ||||
|      * ${fieldConfig.comment} | ||||
|      */ | ||||
|     @Schema(description = "${fieldConfig.comment}") | ||||
|     @ExcelProperty(value = "${fieldConfig.comment}") | ||||
|     private ${fieldConfig.fieldType} ${fieldConfig.fieldName}; | ||||
|   </#list> | ||||
| </#if> | ||||
| } | ||||
| @@ -0,0 +1,52 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package ${packageName}.${subPackageName}; | ||||
|  | ||||
| <#if hasLocalDateTime> | ||||
| import java.time.LocalDateTime; | ||||
| </#if> | ||||
| <#if hasBigDecimal> | ||||
| import java.math.BigDecimal; | ||||
| </#if> | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.base.BaseDO; | ||||
|  | ||||
| /** | ||||
|  * ${businessName}实体 | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @since ${date} | ||||
|  */ | ||||
| @Data | ||||
| @TableName("${tableName}") | ||||
| public class ${className} extends BaseDO { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
| <#if fieldConfigs??> | ||||
|   <#list fieldConfigs as fieldConfig> | ||||
|  | ||||
|     /** | ||||
|      * ${fieldConfig.comment} | ||||
|      */ | ||||
|     private ${fieldConfig.fieldType} ${fieldConfig.fieldName}; | ||||
|   </#list> | ||||
| </#if> | ||||
| } | ||||
| @@ -0,0 +1,28 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package ${packageName}.${subPackageName}; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.base.BaseMapper; | ||||
| import ${packageName}.model.entity.${classNamePrefix}DO; | ||||
|  | ||||
| /** | ||||
| * ${businessName} Mapper | ||||
| * | ||||
| * @author ${author} | ||||
| * @since ${date} | ||||
| */ | ||||
| public interface ${className} extends BaseMapper<${classNamePrefix}DO> {} | ||||
| @@ -0,0 +1,65 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package ${packageName}.${subPackageName}; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| <#if hasLocalDateTime> | ||||
| import java.time.LocalDateTime; | ||||
| </#if> | ||||
| <#if hasBigDecimal> | ||||
| import java.math.BigDecimal; | ||||
| </#if> | ||||
| <#if hasListQueryField> | ||||
| import java.util.List; | ||||
| </#if> | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.annotation.Query; | ||||
| import top.charles7c.cnadmin.common.enums.QueryTypeEnum; | ||||
|  | ||||
| /** | ||||
|  * ${businessName}查询条件 | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @since ${date} | ||||
|  */ | ||||
| @Data | ||||
| @Schema(description = "${businessName}查询条件") | ||||
| public class ${className} implements Serializable { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
| <#if fieldConfigs??> | ||||
|   <#list fieldConfigs as fieldConfig> | ||||
|     <#if fieldConfig.showInQuery> | ||||
|  | ||||
|     /** | ||||
|      * ${fieldConfig.comment} | ||||
|      */ | ||||
|     @Schema(description = "${fieldConfig.comment}") | ||||
|     @Query(type = QueryTypeEnum.${fieldConfig.queryType}) | ||||
|     <#if fieldConfig.queryType == 'IN' || fieldConfig.queryType == 'NOT_IN' || fieldConfig.queryType == 'BETWEEN'> | ||||
|     private List<${fieldConfig.fieldType}> ${fieldConfig.fieldName}; | ||||
|     <#else> | ||||
|     private ${fieldConfig.fieldType} ${fieldConfig.fieldName}; | ||||
|     </#if> | ||||
|     </#if> | ||||
|   </#list> | ||||
| </#if> | ||||
| } | ||||
| @@ -0,0 +1,66 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package ${packageName}.${subPackageName}; | ||||
|  | ||||
| <#if hasLocalDateTime> | ||||
| import java.time.LocalDateTime; | ||||
| </#if> | ||||
| <#if hasBigDecimal> | ||||
| import java.math.BigDecimal; | ||||
| </#if> | ||||
|  | ||||
| <#if hasRequiredField> | ||||
| import javax.validation.constraints.*; | ||||
| </#if> | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.base.BaseRequest; | ||||
|  | ||||
| /** | ||||
|  * 创建或修改${businessName}信息 | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @since ${date} | ||||
|  */ | ||||
| @Data | ||||
| @Schema(description = "创建或修改${businessName}信息") | ||||
| public class ${className} extends BaseRequest { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
| <#if fieldConfigs??> | ||||
|   <#list fieldConfigs as fieldConfig> | ||||
|     <#if fieldConfig.showInForm> | ||||
|  | ||||
|     /** | ||||
|      * ${fieldConfig.comment} | ||||
|      */ | ||||
|     @Schema(description = "${fieldConfig.comment}") | ||||
|     <#if fieldConfig.isRequired> | ||||
|     <#if fieldConfig.fieldType = 'String'> | ||||
|     @NotBlank(message = "${fieldConfig.comment}不能为空") | ||||
|     <#else> | ||||
|     @NotNull(message = "${fieldConfig.comment}不能为空") | ||||
|     </#if> | ||||
|     </#if> | ||||
|     private ${fieldConfig.fieldType} ${fieldConfig.fieldName}; | ||||
|     </#if> | ||||
|   </#list> | ||||
| </#if> | ||||
| } | ||||
| @@ -0,0 +1,31 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package ${packageName}.${subPackageName}; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.base.BaseService; | ||||
| import ${packageName}.model.query.${classNamePrefix}Query; | ||||
| import ${packageName}.model.request.${classNamePrefix}Request; | ||||
| import ${packageName}.model.vo.${classNamePrefix}DetailVO; | ||||
| import ${packageName}.model.vo.${classNamePrefix}VO; | ||||
|  | ||||
| /** | ||||
|  * ${businessName}业务接口 | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @since ${date} | ||||
|  */ | ||||
| public interface ${className} extends BaseService<${classNamePrefix}VO, ${classNamePrefix}DetailVO, ${classNamePrefix}Query, ${classNamePrefix}Request> {} | ||||
| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package ${packageName}.${subPackageName}; | ||||
|  | ||||
| import lombok.RequiredArgsConstructor; | ||||
|  | ||||
| import org.springframework.stereotype.Service; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.base.BaseServiceImpl; | ||||
| import ${packageName}.mapper.${classNamePrefix}Mapper; | ||||
| import ${packageName}.model.entity.${classNamePrefix}DO; | ||||
| import ${packageName}.model.query.${classNamePrefix}Query; | ||||
| import ${packageName}.model.request.${classNamePrefix}Request; | ||||
| import ${packageName}.model.vo.${classNamePrefix}DetailVO; | ||||
| import ${packageName}.model.vo.${classNamePrefix}VO; | ||||
| import ${packageName}.service.${classNamePrefix}Service; | ||||
|  | ||||
| /** | ||||
|  * ${businessName}业务实现 | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @since ${date} | ||||
|  */ | ||||
| @Service | ||||
| @RequiredArgsConstructor | ||||
| public class ${className} extends BaseServiceImpl<${classNamePrefix}Mapper, ${classNamePrefix}DO, ${classNamePrefix}VO, ${classNamePrefix}DetailVO, ${classNamePrefix}Query, ${classNamePrefix}Request> implements ${classNamePrefix}Service {} | ||||
| @@ -0,0 +1,55 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package ${packageName}.${subPackageName}; | ||||
|  | ||||
| <#if hasLocalDateTime> | ||||
| import java.time.LocalDateTime; | ||||
| </#if> | ||||
| <#if hasBigDecimal> | ||||
| import java.math.BigDecimal; | ||||
| </#if> | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.base.BaseVO; | ||||
|  | ||||
| /** | ||||
|  * ${businessName}信息 | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @since ${date} | ||||
|  */ | ||||
| @Data | ||||
| @Schema(description = "${businessName}信息") | ||||
| public class ${className} extends BaseVO { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
| <#if fieldConfigs??> | ||||
|   <#list fieldConfigs as fieldConfig> | ||||
|     <#if fieldConfig.showInList> | ||||
|  | ||||
|     /** | ||||
|      * ${fieldConfig.comment} | ||||
|      */ | ||||
|     @Schema(description = "${fieldConfig.comment}") | ||||
|     private ${fieldConfig.fieldType} ${fieldConfig.fieldName}; | ||||
|     </#if> | ||||
|   </#list> | ||||
| </#if> | ||||
| } | ||||
| @@ -75,3 +75,7 @@ export interface GeneratorConfigRecord { | ||||
| export function saveConfig(tableName: string, req: GeneratorConfigRecord) { | ||||
|   return axios.post(`${BASE_URL}/config/${tableName}`, req); | ||||
| } | ||||
|  | ||||
| export function generate(tableName: string) { | ||||
|   return axios.post(`${BASE_URL}/${tableName}`); | ||||
| } | ||||
|   | ||||
| @@ -298,6 +298,7 @@ | ||||
|     getGenConfig, | ||||
|     GeneratorConfigRecord, | ||||
|     saveConfig, | ||||
|     generate, | ||||
|   } from '@/api/tool/generator'; | ||||
|  | ||||
|   const { proxy } = getCurrentInstance() as any; | ||||
| @@ -434,7 +435,9 @@ | ||||
|    * @param tableName 表名称 | ||||
|    */ | ||||
|   const handleGenerate = (tableName: string) => { | ||||
|     proxy.$message.info('功能尚在开发中'); | ||||
|     generate(tableName).then((res) => { | ||||
|       proxy.$message.success(res.msg); | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   /** | ||||
|   | ||||
| @@ -27,9 +27,12 @@ import io.swagger.v3.oas.annotations.tags.Tag; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import cn.hutool.extra.spring.SpringUtil; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.model.query.PageQuery; | ||||
| import top.charles7c.cnadmin.common.model.vo.PageDataVO; | ||||
| import top.charles7c.cnadmin.common.model.vo.R; | ||||
| import top.charles7c.cnadmin.common.util.validate.ValidationUtils; | ||||
| import top.charles7c.cnadmin.tool.model.entity.FieldConfigDO; | ||||
| import top.charles7c.cnadmin.tool.model.entity.GenConfigDO; | ||||
| import top.charles7c.cnadmin.tool.model.query.TableQuery; | ||||
| @@ -77,4 +80,12 @@ public class GeneratorController { | ||||
|         generatorService.saveConfig(request, tableName); | ||||
|         return R.ok("保存成功"); | ||||
|     } | ||||
|  | ||||
|     @Operation(summary = "生成代码", description = "生成代码") | ||||
|     @PostMapping("/{tableName}") | ||||
|     public R generate(@PathVariable String tableName) { | ||||
|         ValidationUtils.throwIf("prod".equals(SpringUtil.getActiveProfile()), "仅支持在开发环境生成代码"); | ||||
|         generatorService.generate(tableName); | ||||
|         return R.ok("生成成功,请查看生成代码是否正确"); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -45,15 +45,6 @@ logging: | ||||
|       - password | ||||
|       - Authorization | ||||
|  | ||||
| --- ### 代码生成器配置 | ||||
| generator: | ||||
|   # 排除数据表 | ||||
|   excludeTables: | ||||
|     - DATABASECHANGELOG | ||||
|     - DATABASECHANGELOGLOCK | ||||
|     - gen_config | ||||
|     - gen_field_config | ||||
|  | ||||
| --- ### 接口文档配置 | ||||
| springdoc: | ||||
|   # 设置对象型参数的展示形式(设为 true 表示将对象型参数平展开,即对象内的属性直接作为参数展示而不是嵌套在对象内,默认为 false) | ||||
| @@ -214,3 +205,41 @@ thread-pool: | ||||
|   queueCapacity: 128 | ||||
|   # 活跃时间 | ||||
|   keepAliveSeconds: 300 | ||||
|  | ||||
| --- ### 代码生成器配置 | ||||
| generator: | ||||
|   # 排除数据表 | ||||
|   excludeTables: | ||||
|     - DATABASECHANGELOG | ||||
|     - DATABASECHANGELOGLOCK | ||||
|     - gen_config | ||||
|     - gen_field_config | ||||
|   # 模板配置 | ||||
|   templateConfigs: | ||||
|     DO: | ||||
|       templatePath: generator/Entity.ftl | ||||
|       packageName: model.entity | ||||
|     Query: | ||||
|       templatePath: generator/Query.ftl | ||||
|       packageName: model.query | ||||
|     Request: | ||||
|       templatePath: generator/Request.ftl | ||||
|       packageName: model.request | ||||
|     VO: | ||||
|       templatePath: generator/VO.ftl | ||||
|       packageName: model.vo | ||||
|     DetailVO: | ||||
|       templatePath: generator/DetailVO.ftl | ||||
|       packageName: model.vo | ||||
|     Mapper: | ||||
|       templatePath: generator/Mapper.ftl | ||||
|       packageName: mapper | ||||
|     Service: | ||||
|       templatePath: generator/Service.ftl | ||||
|       packageName: service | ||||
|     ServiceImpl: | ||||
|       templatePath: generator/ServiceImpl.ftl | ||||
|       packageName: service.impl | ||||
|     Controller: | ||||
|       templatePath: generator/Controller.ftl | ||||
|       packageName: controller | ||||
		Reference in New Issue
	
	Block a user