1、controller join表排序问题修复
2、优化插件逻辑
This commit is contained in:
@@ -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,10 +89,37 @@ public class CoolPluginService {
|
||||
* 安装jar
|
||||
*/
|
||||
public void install(MultipartFile file, boolean force) {
|
||||
String fileName;
|
||||
File jarFile = null;
|
||||
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
// 保存jar文件
|
||||
jarFile = saveJarFile(file);
|
||||
String jarFilePath = jarFile.getAbsolutePath();
|
||||
// 加载jar
|
||||
PluginJson pluginJson = dynamicJarLoaderService.install(jarFilePath, 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;
|
||||
} catch (Exception e) {
|
||||
log.error("插件安装失败", e);
|
||||
CoolPreconditions.alwaysThrow("插件安装失败", e);
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(originalClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存jar文件
|
||||
*/
|
||||
private File saveJarFile(MultipartFile file) throws IOException {
|
||||
String pathStr = pluginPath;
|
||||
if (!PathUtils.isAbsolutePath(pluginPath)) {
|
||||
// 相对路径
|
||||
@@ -103,25 +132,11 @@ public class CoolPluginService {
|
||||
// 如果路径不存在,则创建目录(包括父目录)
|
||||
Files.createDirectories(path);
|
||||
}
|
||||
fileName =
|
||||
String jarFilePath =
|
||||
path + File.separator + System.currentTimeMillis() + "_" + file.getOriginalFilename() + ".jar";
|
||||
jarFile = new File(fileName);
|
||||
File jarFile = new File(jarFilePath);
|
||||
file.transferTo(jarFile);
|
||||
// 加载jar
|
||||
PluginJson pluginJson = dynamicJarLoaderService.install(fileName, force);
|
||||
// 保存插件信息入库
|
||||
savePluginInfo(pluginJson, fileName, jarFile, force);
|
||||
// 把 ApplicationContext 对象传递打插件类中,使其在插件中也能正常使用spring bean对象
|
||||
CoolPluginInvokers.setApplicationContext(pluginJson.getKey());
|
||||
} catch (CoolException e) {
|
||||
FileUtil.del(jarFile);
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("插件安装失败", e);
|
||||
CoolPreconditions.alwaysThrow("插件安装失败", e);
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(originalClassLoader);
|
||||
}
|
||||
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) {
|
||||
|
||||
@@ -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<T> {
|
||||
|
||||
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<T> {
|
||||
}
|
||||
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<T> {
|
||||
// 该对象没有@Table注解,非Entity对象
|
||||
return;
|
||||
}
|
||||
String tableAlias = "";
|
||||
List<QueryTable> queryTables = (List<QueryTable>) 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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<BaseSysParamServ
|
||||
|
||||
@Override
|
||||
protected void init(HttpServletRequest request, JSONObject requestParams) {
|
||||
setPageOption(createOp().fieldEq(BASE_SYS_PARAM_ENTITY.DATA_TYPE)
|
||||
.keyWordLikeFields(BASE_SYS_PARAM_ENTITY.NAME, BASE_SYS_PARAM_ENTITY.KEY_NAME));
|
||||
}
|
||||
|
||||
@Operation(summary = "根据键返回网页的参数值")
|
||||
|
||||
@@ -83,7 +83,7 @@ public class BaseSysUserServiceImpl extends BaseServiceImpl<BaseSysUserMapper, B
|
||||
!coolSecurityUtil.username().equals("admin")));
|
||||
|
||||
qw.groupBy(BASE_SYS_USER_ENTITY.ID);
|
||||
return mapper.paginateWithRelations(page, qw);
|
||||
return mapper.paginate(page, qw);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user