diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/controller/GenController.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/controller/GenController.java index 52f78ecd..2e394a05 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/controller/GenController.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/controller/GenController.java @@ -1,5 +1,6 @@ package org.ruoyi.generator.controller; +import cn.hutool.core.net.URLDecoder; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.ruoyi.common.core.domain.R; @@ -8,10 +9,11 @@ import org.ruoyi.generator.service.IGenTableService; import org.ruoyi.generator.service.SchemaFieldService; import org.springframework.context.annotation.Profile; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.nio.charset.StandardCharsets; + /** * 代码生成 操作处理 * @@ -46,4 +48,18 @@ public class GenController extends BaseController { genTableService.generateCodeToClasspathByTableNames(tableNameStr); return R.ok("代码生成成功"); } + + /** + * 生成前端代码 + * + * @param workPath 执行命令路径 + * @param previewCode 执行生成前端文件命令 + */ + @GetMapping("/batchGenFrontendCode") + public R batchGenFrontendCode(@NotNull(message = "路径不能为空") String workPath, @NotNull(message = "指令不能为空") String previewCode) { + String decodedWorkPath = URLDecoder.decode(workPath, StandardCharsets.UTF_8); + String decodedPreviewCode = URLDecoder.decode(previewCode, StandardCharsets.UTF_8); + genTableService.generateFrontendTemplateFiles(decodedWorkPath, decodedPreviewCode); + return R.ok("代码生成成功"); + } } diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/impl/GenTableServiceImpl.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/impl/GenTableServiceImpl.java index 9ef76085..932bb46f 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/impl/GenTableServiceImpl.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/impl/GenTableServiceImpl.java @@ -19,18 +19,9 @@ import org.ruoyi.generator.util.VelocityInitializer; import org.ruoyi.generator.util.VelocityUtils; import org.springframework.stereotype.Service; -import java.io.File; -import java.io.FileWriter; -import java.io.StringWriter; +import java.io.*; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; /** * 业务 服务层实现 @@ -59,6 +50,41 @@ public class GenTableServiceImpl implements IGenTableService { } } + @Override + public void generateFrontendTemplateFiles(String workPath, String previewCode) { + String os = System.getProperty("os.name").toLowerCase(); + + ProcessBuilder builder; + if (os.contains("win")) { + // Windows下用 cmd /c 执行 previewCode + builder = new ProcessBuilder("cmd.exe", "/c", previewCode); + } else { + // macOS/Linux 用 bash -c 执行 previewCode + builder = new ProcessBuilder("bash", "-c", previewCode); + } + + // 设置工作目录 + builder.directory(new File(workPath)); + builder.redirectErrorStream(true); + + try (BufferedReader reader = new BufferedReader( + new InputStreamReader( + builder.start().getInputStream(), + StandardCharsets.UTF_8 + ) + )) { + String line; + log.info("执行结果:"); + while ((line = reader.readLine()) != null) { + log.info(line); + } + + } catch (Exception e) { + log.error("生成前端代码出错", e); + throw new RuntimeException("生成前端代码失败", e); + } + } + /** * 根据表名称生成代码到classpath */ @@ -128,17 +154,17 @@ public class GenTableServiceImpl implements IGenTableService { */ private VelocityContext prepareSchemaContext(SchemaVo schema, List fields) { VelocityContext context = new VelocityContext(); - + // 从配置文件读取基本配置 String packageName = GenConfig.getPackageName(); String author = GenConfig.getAuthor(); String tablePrefix = GenConfig.getTablePrefix(); boolean autoRemovePre = GenConfig.getAutoRemovePre(); - + // 处理表名和类名 String tableName = schema.getTableName(); String baseClassName = schema.getTableName(); - + // 自动去除表前缀 if (autoRemovePre && StrUtil.isNotBlank(tablePrefix)) { String[] prefixes = tablePrefix.split(","); @@ -149,12 +175,12 @@ public class GenTableServiceImpl implements IGenTableService { } } } - + String className = toCamelCase(baseClassName, true); // 首字母大写的类名,如:SysRole String classname = toCamelCase(baseClassName, false); // 首字母小写的类名,如:sysRole String businessName = toCamelCase(baseClassName, false); String moduleName = getModuleName(packageName); - + // 基本信息 context.put("tableName", tableName); context.put("tableComment", schema.getComment()); @@ -168,18 +194,18 @@ public class GenTableServiceImpl implements IGenTableService { context.put("packageName", packageName); context.put("moduleName", moduleName); context.put("businessName", businessName); - + // 权限相关 context.put("permissionPrefix", moduleName + ":" + businessName); context.put("parentMenuId", "2000"); // 默认父菜单ID,可配置 - + // 生成菜单ID List menuIds = new ArrayList<>(); for (int i = 0; i < 6; i++) { menuIds.add(IdUtil.getSnowflakeNextId()); } context.put("menuIds", menuIds); - + // 创建table对象,包含menuIds等信息和方法 Map table = new HashMap<>(); table.put("menuIds", menuIds); @@ -188,29 +214,29 @@ public class GenTableServiceImpl implements IGenTableService { table.put("className", className); table.put("classname", classname); table.put("functionName", schema.getName()); - + // 添加表类型属性(默认为crud类型) table.put("crud", true); table.put("sub", false); table.put("tree", false); - + // 添加isSuperColumn方法 table.put("isSuperColumn", new Object() { public boolean isSuperColumn(String javaField) { // 定义超类字段(BaseEntity中的字段) - return "createBy".equals(javaField) || "createTime".equals(javaField) - || "updateBy".equals(javaField) || "updateTime".equals(javaField) - || "remark".equals(javaField) || "tenantId".equals(javaField); + return "createBy".equals(javaField) || "createTime".equals(javaField) + || "updateBy".equals(javaField) || "updateTime".equals(javaField) + || "remark".equals(javaField) || "tenantId".equals(javaField); } }); - + context.put("table", table); - + // 处理字段信息 List> columns = new ArrayList<>(); Map pkColumn = null; Set importList = new HashSet<>(); - + // 添加基础导入 importList.add("java.io.Serializable"); @@ -218,7 +244,7 @@ public class GenTableServiceImpl implements IGenTableService { Map column = new HashMap<>(); String javaType = getJavaType(field.getType()); String javaField = StrUtil.toCamelCase(field.getCode()); - + column.put("columnName", field.getCode()); column.put("columnComment", field.getName()); column.put("comment", field.getName()); // 添加comment别名 @@ -226,7 +252,7 @@ public class GenTableServiceImpl implements IGenTableService { column.put("javaType", javaType); column.put("javaField", javaField); column.put("capJavaField", toCamelCase(field.getCode(), true)); - + // 布尔值属性(兼容两种格式) boolean isPk = "1".equals(field.getIsPk()); boolean isRequired = "1".equals(field.getIsRequired()); @@ -234,7 +260,7 @@ public class GenTableServiceImpl implements IGenTableService { boolean isEdit = "1".equals(field.getIsEdit()); boolean isList = "1".equals(field.getIsList()); boolean isQuery = "1".equals(field.getIsQuery()); - + column.put("isPk", isPk ? 1 : 0); column.put("pk", isPk); // 添加pk别名 column.put("isRequired", isRequired); @@ -247,27 +273,27 @@ public class GenTableServiceImpl implements IGenTableService { column.put("list", isList); // 添加list别名 column.put("isQuery", isQuery); column.put("query", isQuery); // 添加query别名 - + column.put("queryType", field.getQueryType()); column.put("htmlType", field.getHtmlType()); column.put("dictType", field.getDictType()); column.put("sort", field.getSort()); - + // 添加readConverterExp方法 column.put("readConverterExp", new Object() { }); - + // 根据Java类型添加相应的导入 addImportForJavaType(javaType, importList); - + columns.add(column); - + // 设置主键列 if (isPk) { pkColumn = column; } } - + // 如果没有主键,使用第一个字段作为主键 if (pkColumn == null && !columns.isEmpty()) { pkColumn = columns.get(0); @@ -275,27 +301,28 @@ public class GenTableServiceImpl implements IGenTableService { pkColumn.put("isPk", 1); pkColumn.put("pk", true); } - + context.put("columns", columns); context.put("pkColumn", pkColumn); context.put("importList", new ArrayList<>(importList)); - + return context; } - + /** - * 根据Java类型添加相应的导入 - */ - private void addImportForJavaType(String javaType, Set importList) { - switch (javaType) { - case "BigDecimal" -> importList.add("java.math.BigDecimal"); - case "Date" -> importList.add("java.util.Date"); - case "LocalDateTime" -> importList.add("java.time.LocalDateTime"); - case "LocalDate" -> importList.add("java.time.LocalDate"); - case "LocalTime" -> importList.add("java.time.LocalTime"); - default -> {} - } - } + * 根据Java类型添加相应的导入 + */ + private void addImportForJavaType(String javaType, Set importList) { + switch (javaType) { + case "BigDecimal" -> importList.add("java.math.BigDecimal"); + case "Date" -> importList.add("java.util.Date"); + case "LocalDateTime" -> importList.add("java.time.LocalDateTime"); + case "LocalDate" -> importList.add("java.time.LocalDate"); + case "LocalTime" -> importList.add("java.time.LocalTime"); + default -> { + } + } + } /** * 从包名中提取模块名 @@ -319,10 +346,10 @@ public class GenTableServiceImpl implements IGenTableService { String packageName = GenConfig.getPackageName(); String tablePrefix = GenConfig.getTablePrefix(); boolean autoRemovePre = GenConfig.getAutoRemovePre(); - + // 处理类名 String baseClassName = schema.getTableName(); - + // 自动去除表前缀 if (autoRemovePre && StrUtil.isNotBlank(tablePrefix)) { String[] prefixes = tablePrefix.split(","); @@ -333,13 +360,13 @@ public class GenTableServiceImpl implements IGenTableService { } } } - + String className = toCamelCase(baseClassName, true); // 首字母大写,如:SysRole // 首字母小写,如:sysRole String moduleName = getModuleName(packageName); String javaPath = "src/main/java/"; String mybatisPath = "src/main/resources/mapper/"; - + if (template.contains("domain.java.vm")) { return javaPath + packageName.replace(".", "/") + "/domain/" + className + ".java"; } else if (template.contains("mapper.java.vm")) { diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/service/IGenTableService.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/service/IGenTableService.java index bd8e291a..4403d3b7 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/service/IGenTableService.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/service/IGenTableService.java @@ -13,4 +13,12 @@ public interface IGenTableService { * @param tableName 表名称数组 */ void generateCodeToClasspathByTableNames(String tableName); + + /** + * 生成前端文件 + * + * @param workPath 执行命令路径 + * @param previewCode 执行生成前端文件命令 + */ + void generateFrontendTemplateFiles(String workPath, String previewCode); } diff --git a/script/sql/update/knowledge-role-bak.sql b/script/sql/update/knowledge-role-bak.sql index 5dfd35e7..62a7ce67 100644 --- a/script/sql/update/knowledge-role-bak.sql +++ b/script/sql/update/knowledge-role-bak.sql @@ -74,7 +74,7 @@ SET FOREIGN_KEY_CHECKS = 1; -- 菜单 -INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (1946483381643743233, '知识库角色管理', 1775500307898949634, '12', 'knowledgeRole', 'system/knowledgeRole/index', NULL, 1, 0, 'C', '0', '0', NULL, 'ri:user-3-fill', 103, 1, '2025-07-19 16:41:17', NULL, NULL, '知识库角色管理'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (1946483381643743233, '知识库角色管理', 1775500307898949634, '12', 'knowledgeRole', 'operator/knowledgeRole/index', NULL, 1, 0, 'C', '0', '0', NULL, 'ri:user-3-fill', 103, 1, '2025-07-19 16:41:17', NULL, NULL, '知识库角色管理'); -- 用户表添加字段 ALTER TABLE sys_user