From 5fe8bd7706ad7c463ffdd59e3b7486fd15e2ee8e Mon Sep 17 00:00:00 2001 From: violateer <1828257089@qq.com> Date: Sun, 10 Aug 2025 17:06:32 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feature:=20=E6=96=B0=E5=A2=9E=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=89=8D=E7=AB=AF=E6=96=87=E4=BB=B6=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generator/controller/GenController.java | 18 ++- .../generator/impl/GenTableServiceImpl.java | 137 +++++++++++------- .../generator/service/IGenTableService.java | 8 + script/sql/update/knowledge-role-bak.sql | 2 +- 4 files changed, 108 insertions(+), 57 deletions(-) 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 From e5011e0dd9a7b8a05ff2536703ffe448a2a7af9b Mon Sep 17 00:00:00 2001 From: violateer <1828257089@qq.com> Date: Sun, 10 Aug 2025 17:19:59 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feature:=20=E6=96=B0=E5=A2=9E=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=89=8D=E7=AB=AF=E6=96=87=E4=BB=B6=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generator/controller/GenController.java | 18 ++- .../generator/impl/GenTableServiceImpl.java | 137 +++++++++++------- .../generator/service/IGenTableService.java | 8 + script/sql/update/knowledge-role-bak.sql | 2 +- 4 files changed, 108 insertions(+), 57 deletions(-) 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 From d964e86b232b28b3244a050b4de0503cf2651918 Mon Sep 17 00:00:00 2001 From: likunlong Date: Mon, 11 Aug 2025 09:33:35 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E8=8E=B7=E5=8F=96=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E6=8E=A5=E5=8F=A3=E6=94=AF=E6=8C=81=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E8=83=BD=E5=8A=9B=EF=BC=9B=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E8=A1=A8=E5=A2=9E=E5=8A=A0=E6=A8=A1=E5=9E=8B=E8=83=BD=E5=8A=9B?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/ruoyi/domain/ChatModel.java | 6 + .../java/org/ruoyi/domain/vo/ChatModelVo.java | 140 +++++++++++++++++- script/sql/update/20250808.sql | 3 + 3 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 script/sql/update/20250808.sql diff --git a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatModel.java b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatModel.java index c4e25a1b..b708b0a3 100644 --- a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatModel.java +++ b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatModel.java @@ -8,6 +8,7 @@ import lombok.EqualsAndHashCode; import org.ruoyi.core.domain.BaseEntity; import java.io.Serial; +import java.util.List; /** * 聊天模型对象 chat_model @@ -80,5 +81,10 @@ public class ChatModel extends BaseEntity { */ private String remark; + /** + * 模型能力 + */ + private String modelCapability; + } diff --git a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/vo/ChatModelVo.java b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/vo/ChatModelVo.java index 77afe2f4..8472929d 100644 --- a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/vo/ChatModelVo.java +++ b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/vo/ChatModelVo.java @@ -5,14 +5,14 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; +import lombok.Getter; import org.ruoyi.common.sensitive.annotation.Sensitive; import org.ruoyi.common.sensitive.core.SensitiveStrategy; import org.ruoyi.domain.ChatModel; import java.io.Serial; import java.io.Serializable; - - +import java.util.List; /** @@ -96,4 +96,138 @@ public class ChatModelVo implements Serializable { @ExcelProperty(value = "备注") private String remark; -} + /** + * 模型能力 + */ + @ExcelProperty(value = "模型能力") + private String modelCapability; + + /** + * 模型能力列表 + */ + private List modelAbilities = getModelAbilities(); + + /** + * 模型能力类,类似枚举的静态内部类 + */ + @Getter + public static final class Ability { + // 获取能力名称 + private final String name; + private final String description; + + // 静态字段存储默认能力(类似枚举常量) + public static final Ability IMAGE = new Ability("IMAGE", "图片理解"); + public static final Ability VIDEO = new Ability("VIDEO", "视频理解"); + public static final Ability SPEECH = new Ability("SPEECH", "语音理解"); + + // 动态扩展能力存储 + private static final java.util.Map EXTENDED_ABILITIES = new java.util.HashMap<>(); + + // 私有构造确保受限 + private Ability(String name, String description) { + this.name = name; + this.description = description; + } + + // 静态工厂方法(类似枚举valueOf) + public static Ability valueOf(String name) { + // 先检查默认能力 + switch (name) { + case "IMAGE": return IMAGE; + case "VIDEO": return VIDEO; + case "SPEECH": return SPEECH; + default: + // 检查扩展能力 + Ability ability = EXTENDED_ABILITIES.get(name); + if (ability != null) return ability; + throw new IllegalArgumentException("Unknown ability: " + name); + } + } + + // 动态注册新能力(后期从数据库调用) + public static synchronized Ability registerAbility(String name, String description) { + if (name == null || name.trim().isEmpty()) { + throw new IllegalArgumentException("Ability name cannot be empty"); + } + + // 避免重复注册 + if (EXTENDED_ABILITIES.containsKey(name)) { + return EXTENDED_ABILITIES.get(name); + } + + // 检查是否与默认能力冲突 + try { + valueOf(name); + throw new IllegalArgumentException("Ability already exists as default: " + name); + } catch (IllegalArgumentException e) { + // 正常情况,继续注册 + } + + Ability newAbility = new Ability(name, description); + EXTENDED_ABILITIES.put(name, newAbility); + return newAbility; + } + + // 获取所有能力(默认+扩展) + public static java.util.Set getAllAbilities() { + java.util.Map all = new java.util.HashMap<>(); + all.put(IMAGE.name, IMAGE); + all.put(VIDEO.name, VIDEO); + all.put(SPEECH.name, SPEECH); + all.putAll(EXTENDED_ABILITIES); + return java.util.Collections.unmodifiableSet((java.util.Set) all.values()); + } + + @Override + public String toString() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Ability ability = (Ability) o; + return name.equals(ability.name); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + } + + /** + * 将 modelCapability 字符串转换为 Ability 列表 + * @return Ability 列表 + */ + public java.util.List getModelAbilities() { + if (modelCapability == null || modelCapability.trim().isEmpty()) { + return java.util.Collections.emptyList(); + } + + // 解析 JSON 格式的字符串数组 + String trimmed = modelCapability.trim(); + if (!trimmed.startsWith("[") || !trimmed.endsWith("]")) { + throw new IllegalArgumentException("Invalid modelCapability format: " + modelCapability); + } + + String content = trimmed.substring(1, trimmed.length() - 1).trim(); + if (content.isEmpty()) { + return java.util.Collections.emptyList(); + } + + java.util.List abilities = new java.util.ArrayList<>(); + String[] items = content.split(","); + for (String item : items) { + String cleanedItem = item.trim(); + if (cleanedItem.startsWith("\"") && cleanedItem.endsWith("\"") && cleanedItem.length() >= 2) { + String abilityName = cleanedItem.substring(1, cleanedItem.length() - 1); + abilities.add(Ability.valueOf(abilityName)); + } + } + + return abilities; + } +} \ No newline at end of file diff --git a/script/sql/update/20250808.sql b/script/sql/update/20250808.sql new file mode 100644 index 00000000..3c54c207 --- /dev/null +++ b/script/sql/update/20250808.sql @@ -0,0 +1,3 @@ +-- 聊天模型表添加模型能力字段 +alter table chat_model + add model_capability varchar(255) default '[]' not null comment '模型能力';