forked from github/dataease
fix: 插件上传增加版本验证
This commit is contained in:
parent
f4d0988251
commit
c716dee725
@ -35,5 +35,7 @@ public class MyPlugin implements Serializable {
|
||||
|
||||
private String icon;
|
||||
|
||||
private String require = "1.9.0";
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -195,4 +195,16 @@ public class CodingUtil {
|
||||
}
|
||||
return shortBuffer.toString();
|
||||
}
|
||||
|
||||
public static Integer string2Integer(String str) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (StringUtils.isBlank(str)) return null;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char c = str.charAt(i);
|
||||
if (Character.isDigit(c)) {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.length() > 0 ? Integer.parseInt(sb.toString()) : null;
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,22 @@
|
||||
package io.dataease.service.sys;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.base.domain.MyPlugin;
|
||||
import io.dataease.base.mapper.MyPluginMapper;
|
||||
import io.dataease.base.mapper.ext.ExtSysPluginMapper;
|
||||
import io.dataease.base.mapper.ext.query.GridExample;
|
||||
import io.dataease.commons.constants.AuthConstants;
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.utils.CodingUtil;
|
||||
import io.dataease.commons.utils.DeFileUtils;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.commons.utils.ZipUtils;
|
||||
import io.dataease.controller.sys.base.BaseGridRequest;
|
||||
import io.dataease.listener.util.CacheUtils;
|
||||
import io.dataease.plugins.config.LoadjarUtil;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -22,8 +27,10 @@ import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Service
|
||||
@ -43,6 +50,9 @@ public class PluginService {
|
||||
@Autowired
|
||||
private LoadjarUtil loadjarUtil;
|
||||
|
||||
@Value("${version}")
|
||||
private String version;
|
||||
|
||||
|
||||
public List<MyPlugin> query(BaseGridRequest request) {
|
||||
GridExample gridExample = request.convertExample();
|
||||
@ -66,7 +76,9 @@ public class PluginService {
|
||||
DeFileUtils.deleteFile(pluginDir + "temp/");
|
||||
DeFileUtils.deleteFile(folder);
|
||||
// 需要删除文件
|
||||
e.printStackTrace();
|
||||
// e.printStackTrace();
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
DEException.throwException(e);
|
||||
}
|
||||
//3.解析plugin.json 失败则 直接返回错误 删除文件
|
||||
File folderFile = new File(folder);
|
||||
@ -74,15 +86,31 @@ public class PluginService {
|
||||
if (ArrayUtils.isEmpty(jsonFiles)) {
|
||||
DeFileUtils.deleteFile(pluginDir + "temp/");
|
||||
DeFileUtils.deleteFile(folder);
|
||||
throw new RuntimeException("缺少插件描述文件");
|
||||
String msg = "缺少插件描述文件【plugin.json】";
|
||||
LogUtil.error(msg);
|
||||
DEException.throwException(new RuntimeException(msg));
|
||||
}
|
||||
MyPlugin myPlugin = formatJsonFile(jsonFiles[0]);
|
||||
|
||||
if (!versionMatch(myPlugin.getRequire())) {
|
||||
String msg = "当前插件要求系统版本最低为:" + myPlugin.getRequire();
|
||||
LogUtil.error(msg);
|
||||
DEException.throwException(new RuntimeException(msg));
|
||||
}
|
||||
//4.加载jar包 失败则 直接返回错误 删除文件
|
||||
File[] jarFiles = folderFile.listFiles(this::isPluginJar);
|
||||
if (ArrayUtils.isEmpty(jarFiles)) {
|
||||
DeFileUtils.deleteFile(pluginDir + "temp/");
|
||||
DeFileUtils.deleteFile(folder);
|
||||
throw new RuntimeException("缺少插件jar文件");
|
||||
String msg = "缺少插件jar文件";
|
||||
LogUtil.error(msg);
|
||||
DEException.throwException(new RuntimeException(msg));
|
||||
}
|
||||
|
||||
if (pluginExist(myPlugin)) {
|
||||
String msg = "插件【"+myPlugin.getName()+"】已存在,请先卸载";
|
||||
LogUtil.error(msg);
|
||||
DEException.throwException(new RuntimeException(msg));
|
||||
}
|
||||
String targetDir = null;
|
||||
try {
|
||||
@ -100,7 +128,8 @@ public class PluginService {
|
||||
if (StringUtils.isNotEmpty(targetDir)) {
|
||||
DeFileUtils.deleteFile(targetDir);
|
||||
}
|
||||
e.printStackTrace();
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
DEException.throwException(e);
|
||||
} finally {
|
||||
DeFileUtils.deleteFile(pluginDir + "temp/");
|
||||
DeFileUtils.deleteFile(folder);
|
||||
@ -122,6 +151,19 @@ public class PluginService {
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测插件是否已存在
|
||||
* @param myPlugin
|
||||
* @return
|
||||
*/
|
||||
public boolean pluginExist(MyPlugin myPlugin) {
|
||||
GridExample gridExample = new GridExample();
|
||||
List<MyPlugin> plugins = extSysPluginMapper.query(gridExample);
|
||||
return plugins.stream().anyMatch(plugin -> {
|
||||
return StringUtils.equals(myPlugin.getName(), plugin.getName()) || StringUtils.equals(myPlugin.getModuleName(), plugin.getModuleName());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 卸载插件
|
||||
*
|
||||
@ -129,6 +171,13 @@ public class PluginService {
|
||||
* @return
|
||||
*/
|
||||
public Boolean uninstall(Long pluginId) {
|
||||
MyPlugin myPlugin = myPluginMapper.selectByPrimaryKey(pluginId);
|
||||
if (ObjectUtils.isEmpty(myPlugin)) {
|
||||
String msg = "当前插件不存在";
|
||||
LogUtil.error(msg);
|
||||
DEException.throwException(new RuntimeException(msg));
|
||||
}
|
||||
deleteJarFile(myPlugin);
|
||||
CacheUtils.removeAll(AuthConstants.USER_CACHE_NAME);
|
||||
CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME);
|
||||
CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME);
|
||||
@ -136,6 +185,15 @@ public class PluginService {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void deleteJarFile(MyPlugin plugin) {
|
||||
String version = plugin.getVersion();
|
||||
String moduleName = plugin.getModuleName();
|
||||
String fileName = moduleName + "-" + version + ".jar";
|
||||
String path = pluginDir + plugin.getStore() + "/" + fileName;
|
||||
File jarFile = new File(path);
|
||||
FileUtil.del(jarFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变插件状态
|
||||
*
|
||||
@ -195,4 +253,16 @@ public class PluginService {
|
||||
public Map<String, Object> remoteInstall(Map<String, Object> params) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean versionMatch(String pluginVersion) {
|
||||
List<Integer> versionLists = Arrays.stream(version.split(".")).map(CodingUtil::string2Integer).collect(Collectors.toList());
|
||||
List<Integer> requireVersionLists = Arrays.stream(pluginVersion.split(".")).map(CodingUtil::string2Integer).collect(Collectors.toList());
|
||||
int maxSize = Math.max(versionLists.size(), requireVersionLists.size());
|
||||
for (int i = 0; i < maxSize; i++) {
|
||||
Integer currentV = versionLists.size() == i ? 0 : versionLists.get(i);
|
||||
Integer requireV = requireVersionLists.size() == i ? 0 : requireVersionLists.get(i);
|
||||
if (requireV > currentV) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1645,7 +1645,9 @@ export default {
|
||||
uninstall_cancel: 'Cancel uninstall plugin',
|
||||
setting_background: 'BackGround',
|
||||
setting_jump: 'Jump Setting',
|
||||
select_view: 'Select View'
|
||||
select_view: 'Select View',
|
||||
un_install_success: 'Uninstall is successful and restart takes effect',
|
||||
un_install_error: 'Uninstall failed, please contact the administrator'
|
||||
},
|
||||
display: {
|
||||
logo: 'Head system logo',
|
||||
|
@ -1644,9 +1644,11 @@ export default {
|
||||
creator: '作者',
|
||||
install_time: '安裝時間',
|
||||
release_time: '時間',
|
||||
un_install: '卸載',
|
||||
un_install: '卸載(重啟服務後生效)',
|
||||
uninstall_confirm: '確定卸載該插件',
|
||||
uninstall_cancel: '取消卸載插件'
|
||||
uninstall_cancel: '取消卸載插件',
|
||||
un_install_success: '卸載成功,重啟生效',
|
||||
un_install_error: '卸載失敗,請聯系管理員'
|
||||
},
|
||||
display: {
|
||||
logo: '頭部繫統logo',
|
||||
|
@ -1653,9 +1653,11 @@ export default {
|
||||
creator: '作者',
|
||||
install_time: '安装时间',
|
||||
release_time: '时间',
|
||||
un_install: '卸载',
|
||||
un_install: '卸载(卸载并重启服务后生效)',
|
||||
uninstall_confirm: '确定卸载该插件',
|
||||
uninstall_cancel: '取消卸载插件'
|
||||
uninstall_cancel: '取消卸载插件',
|
||||
un_install_success: '卸载成功,重启生效',
|
||||
un_install_error: '卸载失败,请联系管理员'
|
||||
},
|
||||
display: {
|
||||
logo: '头部系统logo',
|
||||
|
@ -8,7 +8,6 @@
|
||||
@search="search"
|
||||
>
|
||||
<template #toolbar>
|
||||
<!-- <el-button @click="create">{{ $t('plugin.local_install') }}</el-button> -->
|
||||
|
||||
<el-upload
|
||||
:action="baseUrl+'api/plugin/upload'"
|
||||
@ -46,7 +45,7 @@
|
||||
<span>{{ scope.row.installTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <fu-table-operations :buttons="buttons" label="操作" fix /> -->
|
||||
<fu-table-operations :buttons="buttons" :label="$t('commons.operating')" fix />
|
||||
</complex-table>
|
||||
|
||||
</layout-content>
|
||||
@ -72,6 +71,10 @@ export default {
|
||||
// label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this.del,
|
||||
// show: checkPermission(['user:del'])
|
||||
// }
|
||||
{
|
||||
label: this.$t('plugin.un_install'), icon: 'el-icon-delete', type: 'danger', click: this.del,
|
||||
disabled: this.btnDisabled
|
||||
}
|
||||
],
|
||||
searchConfig: {
|
||||
useQuickSearch: true,
|
||||
@ -113,6 +116,8 @@ export default {
|
||||
this.uploading = true
|
||||
},
|
||||
uploadFail(response, file, fileList) {
|
||||
const msg = response && response.message || '安装失败'
|
||||
this.$error(msg)
|
||||
this.uploading = false
|
||||
},
|
||||
uploadSuccess(response, file, fileList) {
|
||||
@ -121,20 +126,23 @@ export default {
|
||||
},
|
||||
|
||||
del(row) {
|
||||
this.$confirm(this.$t('user.delete_confirm'), '', {
|
||||
this.$confirm(this.$t('plugin.uninstall_confirm'), '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
uninstall(row.pluginId).then(res => {
|
||||
this.search()
|
||||
this.$success('卸载成功')
|
||||
this.$success(this.$t('plugin.un_install_success'))
|
||||
}).catch(() => {
|
||||
this.$error('卸载失败')
|
||||
this.$error(this.$t('plugin.un_install_error'))
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$info(this.$t('commons.delete_cancel'))
|
||||
this.$info(this.$t('plugin.uninstall_cancel'))
|
||||
})
|
||||
},
|
||||
btnDisabled(row) {
|
||||
return row.pluginId < 4
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user