From 81e88bee37ab3a68abe427e9b4159e3a8af26359 Mon Sep 17 00:00:00 2001 From: ruying408 <1877972603@qq.com> Date: Fri, 19 Jul 2024 05:38:51 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81controller=20join=E8=A1=A8=E6=8E=92?= =?UTF-8?q?=E5=BA=8F=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D=202=E3=80=81?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8F=92=E4=BB=B6=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/service/CoolPluginService.java | 149 ++++++++++++------ .../com/cool/core/request/CrudOption.java | 33 ++-- .../sys/AdminBaseSysParamController.java | 7 +- .../sys/impl/BaseSysUserServiceImpl.java | 2 +- 4 files changed, 128 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/cool/core/plugin/service/CoolPluginService.java b/src/main/java/com/cool/core/plugin/service/CoolPluginService.java index 10d97cf..49fae6f 100644 --- a/src/main/java/com/cool/core/plugin/service/CoolPluginService.java +++ b/src/main/java/com/cool/core/plugin/service/CoolPluginService.java @@ -18,6 +18,7 @@ import com.cool.modules.plugin.entity.PluginInfoEntity; import com.cool.modules.plugin.service.PluginInfoService; import com.mybatisflex.core.query.QueryWrapper; import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; @@ -25,6 +26,7 @@ import java.nio.file.Paths; import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.exceptions.PersistenceException; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -87,32 +89,22 @@ public class CoolPluginService { * 安装jar */ public void install(MultipartFile file, boolean force) { - String fileName; File jarFile = null; ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); try { - String pathStr = pluginPath; - if (!PathUtils.isAbsolutePath(pluginPath)) { - // 相对路径 - pathStr = System.getProperty("user.dir") + File.separator + pluginPath; - } - // 将路径字符串转换为 Path 对象 - Path path = Paths.get(pathStr); - // 检查路径是否存在 - if (!Files.exists(path)) { - // 如果路径不存在,则创建目录(包括父目录) - Files.createDirectories(path); - } - fileName = - path + File.separator + System.currentTimeMillis() + "_" + file.getOriginalFilename() + ".jar"; - jarFile = new File(fileName); - file.transferTo(jarFile); + // 保存jar文件 + jarFile = saveJarFile(file); + String jarFilePath = jarFile.getAbsolutePath(); // 加载jar - PluginJson pluginJson = dynamicJarLoaderService.install(fileName, force); + PluginJson pluginJson = dynamicJarLoaderService.install(jarFilePath, force); // 保存插件信息入库 - savePluginInfo(pluginJson, fileName, jarFile, force); + savePluginInfo(pluginJson, jarFilePath, jarFile, force); // 把 ApplicationContext 对象传递打插件类中,使其在插件中也能正常使用spring bean对象 CoolPluginInvokers.setApplicationContext(pluginJson.getKey()); + } catch (PersistenceException persistenceException) { + // 唯一键冲突 + CoolPreconditions.returnData( + new CoolPreconditions.ReturnData(1, "插件已存在,继续安装将覆盖")); } catch (CoolException e) { FileUtil.del(jarFile); throw e; @@ -124,6 +116,29 @@ public class CoolPluginService { } } + /** + * 保存jar文件 + */ + private File saveJarFile(MultipartFile file) throws IOException { + String pathStr = pluginPath; + if (!PathUtils.isAbsolutePath(pluginPath)) { + // 相对路径 + pathStr = System.getProperty("user.dir") + File.separator + pluginPath; + } + // 将路径字符串转换为 Path 对象 + Path path = Paths.get(pathStr); + // 检查路径是否存在 + if (!Files.exists(path)) { + // 如果路径不存在,则创建目录(包括父目录) + Files.createDirectories(path); + } + String jarFilePath = + path + File.separator + System.currentTimeMillis() + "_" + file.getOriginalFilename() + ".jar"; + File jarFile = new File(jarFilePath); + file.transferTo(jarFile); + return jarFile; + } + /** * 卸载 */ @@ -141,12 +156,76 @@ public class CoolPluginService { /** * 保存插件信息 */ - private void savePluginInfo(PluginJson pluginJson, String fileName, File jarFile, + private void savePluginInfo(PluginJson pluginJson, String jarFilePath, File jarFile, boolean force) { CoolPreconditions.checkEmpty(pluginJson, "插件安装失败"); - pluginJson.setJarPath(fileName); + pluginJson.setJarPath(jarFilePath); PluginInfoEntity pluginInfo = new PluginInfoEntity(); BeanUtil.copyProperties(pluginJson, pluginInfo); + setLogoOrReadme(pluginJson, pluginInfo); + pluginInfo.setKey(pluginJson.getKey()); + pluginInfo.setPluginJson(pluginJson); + // 转二进制 + pluginInfo.setJarFile(FileUtil.readBytes(jarFile)); + if (force) { + // 判断是否有同名插件, 有将其关闭 + closeSameNamePlugin(pluginJson); + // 覆盖插件 + coverPlugin(pluginJson, pluginInfo); + return; + } + pluginInfo.save(); + } + + /** + * 覆盖插件 + */ + private void coverPlugin(PluginJson pluginJson, PluginInfoEntity pluginInfo) { + // 通过key 找到id + PluginInfoEntity one = pluginInfoService.getByKeyNoJarFile(pluginJson.getKey()); + if (ObjUtil.isNotEmpty(one)) { + // 重新加载配置不更新 + pluginInfo.setConfig(one.getConfig()); + pluginInfo.getPluginJson().setConfig(one.getConfig()); + CopyOptions options = CopyOptions.create().setIgnoreNullValue(true); + BeanUtil.copyProperties(pluginInfo, one, options); + // 忽略为更新的字段 + ignoreNoChange(pluginInfo, one); + one.updateById(); + } + } + + /** + * 关闭同名插件 + */ + private void closeSameNamePlugin(PluginJson pluginJson) { + if (ObjUtil.isNotEmpty(pluginJson.getSameHookId())) { + // 存在同名,已强制安装,需将原插件关闭 + PluginInfoEntity sameHookPlugin = new PluginInfoEntity(); + sameHookPlugin.setStatus(0); + sameHookPlugin.setId(pluginJson.getSameHookId()); + updatePlugin(sameHookPlugin); + } + } + + /** + * 忽略为更新的字段 + */ + private static void ignoreNoChange(PluginInfoEntity pluginInfo, PluginInfoEntity one) { + if (ObjUtil.equals(pluginInfo.getLogo(), one.getLogo())) { + // 头像没变,不更新 + one.setLogo(null); + } + if (ObjUtil.equals(pluginInfo.getReadme(), one.getReadme())) { + // readme没变,不更新 + one.setReadme(null); + } + } + + /** + * 设置logo或readme + */ + private void setLogoOrReadme(PluginJson pluginJson, PluginInfoEntity pluginInfo) { if (ObjUtil.isNotEmpty(pluginJson.getLogo())) { DynamicJarClassLoader dynamicJarClassLoader = dynamicJarLoaderService .getDynamicJarClassLoader(pluginJson.getKey()); @@ -165,34 +244,6 @@ public class CoolPluginService { pluginInfo.setReadme(StrUtil.str(IoUtil.readBytes(inputStream), "UTF-8")); } } - pluginInfo.setKey(pluginJson.getKey()); - pluginInfo.setPluginJson(pluginJson); - // 转二进制 - pluginInfo.setJarFile(FileUtil.readBytes(jarFile)); - - if (force) { - CopyOptions options = CopyOptions.create().setIgnoreNullValue(true); - if (ObjUtil.isNotEmpty(pluginJson.getSameHookId())) { - // 存在同名,已强制安装,需将原插件关闭 - PluginInfoEntity sameHookPlugin = new PluginInfoEntity(); - sameHookPlugin.setStatus(0); - sameHookPlugin.setId(pluginJson.getSameHookId()); - updatePlugin(sameHookPlugin); - } - // 通过key 找到id - PluginInfoEntity one = pluginInfoService.getByKeyNoJarFile(pluginJson.getKey()); - if (ObjUtil.isNotEmpty(one)) { - // 重新加载配置不更新 - pluginInfo.setConfig(one.getConfig()); - pluginInfo.getPluginJson().setConfig(one.getConfig()); - BeanUtil.copyProperties(pluginInfo, one, options); - one.updateById(); - // 重新安装了调用设置插件历史配置信息 - CoolPluginInvokers.setPluginJson(pluginJson.getKey(), one); - return; - } - } - pluginInfo.save(); } public void updatePlugin(PluginInfoEntity entity) { diff --git a/src/main/java/com/cool/core/request/CrudOption.java b/src/main/java/com/cool/core/request/CrudOption.java index fd18a2a..87acfce 100644 --- a/src/main/java/com/cool/core/request/CrudOption.java +++ b/src/main/java/com/cool/core/request/CrudOption.java @@ -1,15 +1,19 @@ package com.cool.core.request; + import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import cn.hutool.json.JSONObject; import com.mybatisflex.annotation.Table; import com.mybatisflex.core.query.QueryColumn; import com.mybatisflex.core.query.QueryCondition; +import com.mybatisflex.core.query.QueryTable; import com.mybatisflex.core.query.QueryWrapper; import java.util.Arrays; +import java.util.List; import lombok.Data; import org.springframework.core.env.Environment; @@ -31,7 +35,7 @@ public class CrudOption { public CrudOption(JSONObject requestParams) { this.requestParams = requestParams; - this.queryWrapper = new QueryWrapper(); + this.queryWrapper = QueryWrapper.create(); this.evn = SpringUtil.getBean(Environment.class); } @@ -72,17 +76,17 @@ public class CrudOption { } Object keyWord = requestParams.get("keyWord"); if (ObjectUtil.isNotEmpty(this.keyWordLikeFields) && ObjectUtil.isNotEmpty(keyWord)) { - QueryCondition queryCondition = new QueryCondition(); - Arrays.stream(keyWordLikeFields).toList().forEach(likeQueryColumn -> { - if (ObjectUtil.isEmpty(queryCondition.getColumn())) { - queryCondition.setColumn(likeQueryColumn); - queryCondition.setLogic(" LIKE "); - queryCondition.setValue("%" + keyWord + "%"); + // 初始化一个空的 QueryCondition + QueryCondition orCondition = null; + for (QueryColumn queryColumn : keyWordLikeFields) { + QueryCondition condition = queryColumn.like(keyWord); + if (orCondition == null) { + orCondition = condition; } else { - queryCondition.or(likeQueryColumn.like(keyWord)); + orCondition = orCondition.or(condition); } - }); - queryWrapper.and(queryCondition); + } + queryWrapper.and(orCondition); } if (ObjectUtil.isNotEmpty(select)) { queryWrapper.select(select); @@ -98,12 +102,19 @@ public class CrudOption { // 该对象没有@Table注解,非Entity对象 return; } + String tableAlias = ""; + List queryTables = (List) ReflectUtil.getFieldValue(queryWrapper, "queryTables"); + if (ObjectUtil.isNotEmpty(queryTables)) { + // 取主表作为排序字段别名 + QueryTable queryTable = queryTables.get(0); + tableAlias = "`" + queryTable.getName() + "`.`"; + } String order = requestParams.getStr("order", tableAnnotation.camelToUnderline() ? "create_time" : "createTime"); String sort = requestParams.getStr("sort", "desc"); if (StrUtil.isNotEmpty(order) && StrUtil.isNotEmpty(sort)) { queryWrapper.orderBy( - tableAnnotation.camelToUnderline() ? StrUtil.toUnderlineCase(order) : order, + tableAlias + (tableAnnotation.camelToUnderline() ? StrUtil.toUnderlineCase(order) : order) + "`", sort.equals("asc")); } } diff --git a/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysParamController.java b/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysParamController.java index 00fd851..56f7291 100644 --- a/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysParamController.java +++ b/src/main/java/com/cool/modules/base/controller/admin/sys/AdminBaseSysParamController.java @@ -1,5 +1,7 @@ package com.cool.modules.base.controller.admin.sys; +import static com.cool.modules.base.entity.sys.table.BaseSysParamEntityTableDef.BASE_SYS_PARAM_ENTITY; + import cn.hutool.json.JSONObject; import com.cool.core.annotation.CoolRestController; import com.cool.core.base.BaseController; @@ -7,9 +9,8 @@ import com.cool.modules.base.entity.sys.BaseSysParamEntity; import com.cool.modules.base.service.sys.BaseSysParamService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.web.bind.annotation.GetMapping; - import jakarta.servlet.http.HttpServletRequest; +import org.springframework.web.bind.annotation.GetMapping; /** * 系统参数配置 @@ -20,6 +21,8 @@ public class AdminBaseSysParamController extends BaseController