Merge branch 'dev' of github.com:dataease/dataease into dev

This commit is contained in:
taojinlong 2022-04-05 11:57:38 +08:00
commit 0c4789689b
8 changed files with 114 additions and 16 deletions

View File

@ -35,5 +35,7 @@ public class MyPlugin implements Serializable {
private String icon; private String icon;
private String require = "1.9.0";
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }

View File

@ -195,4 +195,16 @@ public class CodingUtil {
} }
return shortBuffer.toString(); 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;
}
} }

View File

@ -1101,10 +1101,10 @@ public class DataSetTableService {
Map<String, String[]> customInfo = new TreeMap<>(); Map<String, String[]> customInfo = new TreeMap<>();
for (DataTableInfoCustomUnion ele : dataTableInfoDTO.getList()) { for (DataTableInfoCustomUnion ele : dataTableInfoDTO.getList()) {
DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(ele.getTableId()); DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(ele.getTableId());
String table = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class).getTable();
if (ObjectUtils.isEmpty(datasetTable)) { if (ObjectUtils.isEmpty(datasetTable)) {
throw new RuntimeException(Translator.get("i18n_custom_ds_delete")); throw new RuntimeException(Translator.get("i18n_custom_ds_delete"));
} }
String table = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class).getTable();
List<DatasetTableField> fields = dataSetTableFieldsService.getListByIdsEach(ele.getCheckedFields()); List<DatasetTableField> fields = dataSetTableFieldsService.getListByIdsEach(ele.getCheckedFields());
if (CollectionUtils.isEmpty(fields)) { if (CollectionUtils.isEmpty(fields)) {
throw new RuntimeException(Translator.get("i18n_cst_ds_tb_or_field_deleted")); throw new RuntimeException(Translator.get("i18n_cst_ds_tb_or_field_deleted"));

View File

@ -1,17 +1,22 @@
package io.dataease.service.sys; package io.dataease.service.sys;
import cn.hutool.core.io.FileUtil;
import com.google.gson.Gson; import com.google.gson.Gson;
import io.dataease.base.domain.MyPlugin; import io.dataease.base.domain.MyPlugin;
import io.dataease.base.mapper.MyPluginMapper; import io.dataease.base.mapper.MyPluginMapper;
import io.dataease.base.mapper.ext.ExtSysPluginMapper; import io.dataease.base.mapper.ext.ExtSysPluginMapper;
import io.dataease.base.mapper.ext.query.GridExample; import io.dataease.base.mapper.ext.query.GridExample;
import io.dataease.commons.constants.AuthConstants; 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.DeFileUtils;
import io.dataease.commons.utils.LogUtil;
import io.dataease.commons.utils.ZipUtils; import io.dataease.commons.utils.ZipUtils;
import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.listener.util.CacheUtils; import io.dataease.listener.util.CacheUtils;
import io.dataease.plugins.config.LoadjarUtil; import io.dataease.plugins.config.LoadjarUtil;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -22,8 +27,10 @@ import javax.annotation.Resource;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
@Service @Service
@ -43,6 +50,9 @@ public class PluginService {
@Autowired @Autowired
private LoadjarUtil loadjarUtil; private LoadjarUtil loadjarUtil;
@Value("${version}")
private String version;
public List<MyPlugin> query(BaseGridRequest request) { public List<MyPlugin> query(BaseGridRequest request) {
GridExample gridExample = request.convertExample(); GridExample gridExample = request.convertExample();
@ -66,7 +76,9 @@ public class PluginService {
DeFileUtils.deleteFile(pluginDir + "temp/"); DeFileUtils.deleteFile(pluginDir + "temp/");
DeFileUtils.deleteFile(folder); DeFileUtils.deleteFile(folder);
// 需要删除文件 // 需要删除文件
e.printStackTrace(); // e.printStackTrace();
LogUtil.error(e.getMessage(), e);
DEException.throwException(e);
} }
//3.解析plugin.json 失败则 直接返回错误 删除文件 //3.解析plugin.json 失败则 直接返回错误 删除文件
File folderFile = new File(folder); File folderFile = new File(folder);
@ -74,15 +86,31 @@ public class PluginService {
if (ArrayUtils.isEmpty(jsonFiles)) { if (ArrayUtils.isEmpty(jsonFiles)) {
DeFileUtils.deleteFile(pluginDir + "temp/"); DeFileUtils.deleteFile(pluginDir + "temp/");
DeFileUtils.deleteFile(folder); DeFileUtils.deleteFile(folder);
throw new RuntimeException("缺少插件描述文件"); String msg = "缺少插件描述文件【plugin.json】";
LogUtil.error(msg);
DEException.throwException(new RuntimeException(msg));
} }
MyPlugin myPlugin = formatJsonFile(jsonFiles[0]); MyPlugin myPlugin = formatJsonFile(jsonFiles[0]);
if (!versionMatch(myPlugin.getRequire())) {
String msg = "当前插件要求系统版本最低为:" + myPlugin.getRequire();
LogUtil.error(msg);
DEException.throwException(new RuntimeException(msg));
}
//4.加载jar包 失败则 直接返回错误 删除文件 //4.加载jar包 失败则 直接返回错误 删除文件
File[] jarFiles = folderFile.listFiles(this::isPluginJar); File[] jarFiles = folderFile.listFiles(this::isPluginJar);
if (ArrayUtils.isEmpty(jarFiles)) { if (ArrayUtils.isEmpty(jarFiles)) {
DeFileUtils.deleteFile(pluginDir + "temp/"); DeFileUtils.deleteFile(pluginDir + "temp/");
DeFileUtils.deleteFile(folder); 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; String targetDir = null;
try { try {
@ -100,7 +128,8 @@ public class PluginService {
if (StringUtils.isNotEmpty(targetDir)) { if (StringUtils.isNotEmpty(targetDir)) {
DeFileUtils.deleteFile(targetDir); DeFileUtils.deleteFile(targetDir);
} }
e.printStackTrace(); LogUtil.error(e.getMessage(), e);
DEException.throwException(e);
} finally { } finally {
DeFileUtils.deleteFile(pluginDir + "temp/"); DeFileUtils.deleteFile(pluginDir + "temp/");
DeFileUtils.deleteFile(folder); DeFileUtils.deleteFile(folder);
@ -122,6 +151,19 @@ public class PluginService {
return dir; 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 * @return
*/ */
public Boolean uninstall(Long pluginId) { 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_CACHE_NAME);
CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME); CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME);
CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME); CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME);
@ -136,6 +185,15 @@ public class PluginService {
return true; 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) { public Map<String, Object> remoteInstall(Map<String, Object> params) {
return null; 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;
}
} }

View File

@ -1646,7 +1646,9 @@ export default {
uninstall_cancel: 'Cancel uninstall plugin', uninstall_cancel: 'Cancel uninstall plugin',
setting_background: 'BackGround', setting_background: 'BackGround',
setting_jump: 'Jump Setting', 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: { display: {
logo: 'Head system logo', logo: 'Head system logo',

View File

@ -1645,9 +1645,11 @@ export default {
creator: '作者', creator: '作者',
install_time: '安裝時間', install_time: '安裝時間',
release_time: '時間', release_time: '時間',
un_install: '卸載', un_install: '卸載(重啟服務後生效)',
uninstall_confirm: '確定卸載該插件', uninstall_confirm: '確定卸載該插件',
uninstall_cancel: '取消卸載插件' uninstall_cancel: '取消卸載插件',
un_install_success: '卸載成功,重啟生效',
un_install_error: '卸載失敗,請聯系管理員'
}, },
display: { display: {
logo: '頭部繫統logo', logo: '頭部繫統logo',

View File

@ -1654,9 +1654,11 @@ export default {
creator: '作者', creator: '作者',
install_time: '安装时间', install_time: '安装时间',
release_time: '时间', release_time: '时间',
un_install: '卸载', un_install: '卸载(卸载并重启服务后生效)',
uninstall_confirm: '确定卸载该插件', uninstall_confirm: '确定卸载该插件',
uninstall_cancel: '取消卸载插件' uninstall_cancel: '取消卸载插件',
un_install_success: '卸载成功,重启生效',
un_install_error: '卸载失败,请联系管理员'
}, },
display: { display: {
logo: '头部系统logo', logo: '头部系统logo',

View File

@ -8,7 +8,6 @@
@search="search" @search="search"
> >
<template #toolbar> <template #toolbar>
<!-- <el-button @click="create">{{ $t('plugin.local_install') }}</el-button> -->
<el-upload <el-upload
:action="baseUrl+'api/plugin/upload'" :action="baseUrl+'api/plugin/upload'"
@ -46,7 +45,7 @@
<span>{{ scope.row.installTime | timestampFormatDate }}</span> <span>{{ scope.row.installTime | timestampFormatDate }}</span>
</template> </template>
</el-table-column> </el-table-column>
<!-- <fu-table-operations :buttons="buttons" label="操作" fix /> --> <fu-table-operations :buttons="buttons" :label="$t('commons.operating')" fix />
</complex-table> </complex-table>
</layout-content> </layout-content>
@ -72,6 +71,10 @@ export default {
// label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this.del, // label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this.del,
// show: checkPermission(['user:del']) // show: checkPermission(['user:del'])
// } // }
{
label: this.$t('plugin.un_install'), icon: 'el-icon-delete', type: 'danger', click: this.del,
disabled: this.btnDisabled
}
], ],
searchConfig: { searchConfig: {
useQuickSearch: true, useQuickSearch: true,
@ -113,6 +116,8 @@ export default {
this.uploading = true this.uploading = true
}, },
uploadFail(response, file, fileList) { uploadFail(response, file, fileList) {
const msg = response && response.message || '安装失败'
this.$error(msg)
this.uploading = false this.uploading = false
}, },
uploadSuccess(response, file, fileList) { uploadSuccess(response, file, fileList) {
@ -121,20 +126,23 @@ export default {
}, },
del(row) { del(row) {
this.$confirm(this.$t('user.delete_confirm'), '', { this.$confirm(this.$t('plugin.uninstall_confirm'), '', {
confirmButtonText: this.$t('commons.confirm'), confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'), cancelButtonText: this.$t('commons.cancel'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
uninstall(row.pluginId).then(res => { uninstall(row.pluginId).then(res => {
this.search() this.search()
this.$success('卸载成功') this.$success(this.$t('plugin.un_install_success'))
}).catch(() => { }).catch(() => {
this.$error('卸载失败') this.$error(this.$t('plugin.un_install_error'))
}) })
}).catch(() => { }).catch(() => {
this.$info(this.$t('commons.delete_cancel')) this.$info(this.$t('plugin.uninstall_cancel'))
}) })
},
btnDisabled(row) {
return row.pluginId < 4
} }
} }