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.cool.modules.plugin.service.PluginInfoService;
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@@ -25,6 +26,7 @@ import java.nio.file.Paths;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.ibatis.exceptions.PersistenceException;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@@ -87,10 +89,37 @@ public class CoolPluginService {
|
|||||||
* 安装jar
|
* 安装jar
|
||||||
*/
|
*/
|
||||||
public void install(MultipartFile file, boolean force) {
|
public void install(MultipartFile file, boolean force) {
|
||||||
String fileName;
|
|
||||||
File jarFile = null;
|
File jarFile = null;
|
||||||
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
|
||||||
try {
|
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;
|
String pathStr = pluginPath;
|
||||||
if (!PathUtils.isAbsolutePath(pluginPath)) {
|
if (!PathUtils.isAbsolutePath(pluginPath)) {
|
||||||
// 相对路径
|
// 相对路径
|
||||||
@@ -103,25 +132,11 @@ public class CoolPluginService {
|
|||||||
// 如果路径不存在,则创建目录(包括父目录)
|
// 如果路径不存在,则创建目录(包括父目录)
|
||||||
Files.createDirectories(path);
|
Files.createDirectories(path);
|
||||||
}
|
}
|
||||||
fileName =
|
String jarFilePath =
|
||||||
path + File.separator + System.currentTimeMillis() + "_" + file.getOriginalFilename() + ".jar";
|
path + File.separator + System.currentTimeMillis() + "_" + file.getOriginalFilename() + ".jar";
|
||||||
jarFile = new File(fileName);
|
File jarFile = new File(jarFilePath);
|
||||||
file.transferTo(jarFile);
|
file.transferTo(jarFile);
|
||||||
// 加载jar
|
return jarFile;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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) {
|
boolean force) {
|
||||||
CoolPreconditions.checkEmpty(pluginJson, "插件安装失败");
|
CoolPreconditions.checkEmpty(pluginJson, "插件安装失败");
|
||||||
pluginJson.setJarPath(fileName);
|
pluginJson.setJarPath(jarFilePath);
|
||||||
PluginInfoEntity pluginInfo = new PluginInfoEntity();
|
PluginInfoEntity pluginInfo = new PluginInfoEntity();
|
||||||
BeanUtil.copyProperties(pluginJson, pluginInfo);
|
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())) {
|
if (ObjUtil.isNotEmpty(pluginJson.getLogo())) {
|
||||||
DynamicJarClassLoader dynamicJarClassLoader = dynamicJarLoaderService
|
DynamicJarClassLoader dynamicJarClassLoader = dynamicJarLoaderService
|
||||||
.getDynamicJarClassLoader(pluginJson.getKey());
|
.getDynamicJarClassLoader(pluginJson.getKey());
|
||||||
@@ -165,34 +244,6 @@ public class CoolPluginService {
|
|||||||
pluginInfo.setReadme(StrUtil.str(IoUtil.readBytes(inputStream), "UTF-8"));
|
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) {
|
public void updatePlugin(PluginInfoEntity entity) {
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
package com.cool.core.request;
|
package com.cool.core.request;
|
||||||
|
|
||||||
|
|
||||||
import cn.hutool.core.annotation.AnnotationUtil;
|
import cn.hutool.core.annotation.AnnotationUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import com.mybatisflex.annotation.Table;
|
import com.mybatisflex.annotation.Table;
|
||||||
import com.mybatisflex.core.query.QueryColumn;
|
import com.mybatisflex.core.query.QueryColumn;
|
||||||
import com.mybatisflex.core.query.QueryCondition;
|
import com.mybatisflex.core.query.QueryCondition;
|
||||||
|
import com.mybatisflex.core.query.QueryTable;
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
@@ -31,7 +35,7 @@ public class CrudOption<T> {
|
|||||||
|
|
||||||
public CrudOption(JSONObject requestParams) {
|
public CrudOption(JSONObject requestParams) {
|
||||||
this.requestParams = requestParams;
|
this.requestParams = requestParams;
|
||||||
this.queryWrapper = new QueryWrapper();
|
this.queryWrapper = QueryWrapper.create();
|
||||||
this.evn = SpringUtil.getBean(Environment.class);
|
this.evn = SpringUtil.getBean(Environment.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,17 +76,17 @@ public class CrudOption<T> {
|
|||||||
}
|
}
|
||||||
Object keyWord = requestParams.get("keyWord");
|
Object keyWord = requestParams.get("keyWord");
|
||||||
if (ObjectUtil.isNotEmpty(this.keyWordLikeFields) && ObjectUtil.isNotEmpty(keyWord)) {
|
if (ObjectUtil.isNotEmpty(this.keyWordLikeFields) && ObjectUtil.isNotEmpty(keyWord)) {
|
||||||
QueryCondition queryCondition = new QueryCondition();
|
// 初始化一个空的 QueryCondition
|
||||||
Arrays.stream(keyWordLikeFields).toList().forEach(likeQueryColumn -> {
|
QueryCondition orCondition = null;
|
||||||
if (ObjectUtil.isEmpty(queryCondition.getColumn())) {
|
for (QueryColumn queryColumn : keyWordLikeFields) {
|
||||||
queryCondition.setColumn(likeQueryColumn);
|
QueryCondition condition = queryColumn.like(keyWord);
|
||||||
queryCondition.setLogic(" LIKE ");
|
if (orCondition == null) {
|
||||||
queryCondition.setValue("%" + keyWord + "%");
|
orCondition = condition;
|
||||||
} else {
|
} else {
|
||||||
queryCondition.or(likeQueryColumn.like(keyWord));
|
orCondition = orCondition.or(condition);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
queryWrapper.and(queryCondition);
|
queryWrapper.and(orCondition);
|
||||||
}
|
}
|
||||||
if (ObjectUtil.isNotEmpty(select)) {
|
if (ObjectUtil.isNotEmpty(select)) {
|
||||||
queryWrapper.select(select);
|
queryWrapper.select(select);
|
||||||
@@ -98,12 +102,19 @@ public class CrudOption<T> {
|
|||||||
// 该对象没有@Table注解,非Entity对象
|
// 该对象没有@Table注解,非Entity对象
|
||||||
return;
|
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",
|
String order = requestParams.getStr("order",
|
||||||
tableAnnotation.camelToUnderline() ? "create_time" : "createTime");
|
tableAnnotation.camelToUnderline() ? "create_time" : "createTime");
|
||||||
String sort = requestParams.getStr("sort", "desc");
|
String sort = requestParams.getStr("sort", "desc");
|
||||||
if (StrUtil.isNotEmpty(order) && StrUtil.isNotEmpty(sort)) {
|
if (StrUtil.isNotEmpty(order) && StrUtil.isNotEmpty(sort)) {
|
||||||
queryWrapper.orderBy(
|
queryWrapper.orderBy(
|
||||||
tableAnnotation.camelToUnderline() ? StrUtil.toUnderlineCase(order) : order,
|
tableAlias + (tableAnnotation.camelToUnderline() ? StrUtil.toUnderlineCase(order) : order) + "`",
|
||||||
sort.equals("asc"));
|
sort.equals("asc"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.cool.modules.base.controller.admin.sys;
|
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 cn.hutool.json.JSONObject;
|
||||||
import com.cool.core.annotation.CoolRestController;
|
import com.cool.core.annotation.CoolRestController;
|
||||||
import com.cool.core.base.BaseController;
|
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 com.cool.modules.base.service.sys.BaseSysParamService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统参数配置
|
* 系统参数配置
|
||||||
@@ -20,6 +21,8 @@ public class AdminBaseSysParamController extends BaseController<BaseSysParamServ
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void init(HttpServletRequest request, JSONObject requestParams) {
|
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 = "根据键返回网页的参数值")
|
@Operation(summary = "根据键返回网页的参数值")
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public class BaseSysUserServiceImpl extends BaseServiceImpl<BaseSysUserMapper, B
|
|||||||
!coolSecurityUtil.username().equals("admin")));
|
!coolSecurityUtil.username().equals("admin")));
|
||||||
|
|
||||||
qw.groupBy(BASE_SYS_USER_ENTITY.ID);
|
qw.groupBy(BASE_SYS_USER_ENTITY.ID);
|
||||||
return mapper.paginateWithRelations(page, qw);
|
return mapper.paginate(page, qw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user