Merge pull request #13368 from ulleo/dev-v2

feat(X-Pack): 数据填报插件化支持
This commit is contained in:
fit2cloud-chenyw 2024-11-16 09:29:37 +08:00 committed by GitHub
commit 13db420043
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 231 additions and 8 deletions

View File

@ -1057,7 +1057,27 @@ public class CalciteProvider extends Provider {
if (StringUtils.isEmpty(configuration.getSchema())) {
DEException.throwException(Translator.get("i18n_schema_is_empty"));
}
sql = String.format("SELECT\n" + " a.attname AS ColumnName,\n" + " t.typname,\n" + " b.description AS ColumnDescription,\n" + " 0\n" + "FROM\n" + " pg_class c\n" + " JOIN pg_attribute a ON a.attrelid = c.oid\n" + " LEFT JOIN pg_description b ON a.attrelid = b.objoid AND a.attnum = b.objsubid\n" + " JOIN pg_type t ON a.atttypid = t.oid\n" + "where\n" + " \tc.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = '%s') \n" + " AND c.relname = '%s'\n" + " AND a.attnum > 0\n" + " AND NOT a.attisdropped\n" + "ORDER BY\n" + " a.attnum;", configuration.getSchema(), datasourceRequest.getTable());
sql = String.format("SELECT\n" +
" a.attname AS ColumnName,\n" +
" t.typname,\n" +
" b.description AS ColumnDescription,\n" +
" CASE\n" +
" WHEN d.indisprimary THEN 1\n" +
" ELSE 0\n" +
" END\n" +
"FROM\n" +
" pg_class c\n" +
" JOIN pg_attribute a ON a.attrelid = c.oid\n" +
" LEFT JOIN pg_description b ON a.attrelid = b.objoid AND a.attnum = b.objsubid\n" +
" JOIN pg_type t ON a.atttypid = t.oid\n" +
" LEFT JOIN pg_index d ON d.indrelid = a.attrelid AND d.indisprimary AND a.attnum = ANY(d.indkey)\n" +
"where\n" +
" c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = '%s')\n" +
" AND c.relname = '%s'\n" +
" AND a.attnum > 0\n" +
" AND NOT a.attisdropped\n" +
"ORDER BY\n" +
" a.attnum;", configuration.getSchema(), datasourceRequest.getTable());
break;
case redshift:
configuration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), CK.class);

View File

@ -1582,6 +1582,12 @@ const getMenuList = (val: boolean) => {
</el-col>
</el-row>
</template>
<!-- 数据填报 -->
<XpackComponent
:nodeInfo="nodeInfo"
jsname="L2NvbXBvbmVudC9kYXRhLWZpbGxpbmcvRGF0YXNvdXJjZURhdGFGaWxsaW5nSW5mbw=="
/>
</template>
<template v-if="['es'].includes(nodeInfo.type) && nodeInfo.weight >= 7">
<el-row :gutter="24">

View File

@ -1,6 +1,7 @@
package io.dataease.api.xpack.component;
import io.dataease.api.xpack.component.vo.XpackMenuVO;
import io.dataease.extensions.datafilling.vo.XpackPluginsDfVO;
import io.dataease.extensions.datasource.vo.XpackPluginsDatasourceVO;
import io.dataease.extensions.view.vo.XpackPluginsViewVO;
import org.springframework.web.bind.annotation.GetMapping;
@ -25,6 +26,9 @@ public interface XpackComponentApi {
@GetMapping("/dsPlugins")
List<XpackPluginsDatasourceVO> dsPlugins();
@GetMapping("/dfPlugins")
List<XpackPluginsDfVO> dfPlugins();
@GetMapping("/pluginStaticInfo/{moduleName}")
void pluginStaticInfo(@PathVariable("moduleName") String moduleName);
}

View File

@ -17,6 +17,12 @@
<artifactId>extensions-datasource</artifactId>
<version>${dataease.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.5.0-M2</version>
</dependency>
</dependencies>
<properties>

View File

@ -0,0 +1,9 @@
package io.dataease.extensions.datafilling.api;
import io.dataease.extensions.datafilling.vo.XpackPluginsDfVO;
import java.util.List;
public interface DfPluginManageApi {
List<XpackPluginsDfVO> queryPluginDf();
}

View File

@ -1,21 +1,60 @@
package io.dataease.extensions.datafilling.factory;
import io.dataease.exception.DEException;
import io.dataease.extensions.datafilling.plugin.DataFillingPlugin;
import io.dataease.extensions.datafilling.provider.ExtDDLProvider;
import io.dataease.extensions.datafilling.vo.XpackPluginsDfVO;
import io.dataease.extensions.datasource.utils.SpringContextUtil;
import io.dataease.extensions.datasource.vo.DatasourceConfiguration;
import io.dataease.extensions.datafilling.provider.ExtDDLProvider;
import io.dataease.license.utils.LicenseUtil;
import io.dataease.license.utils.LogUtil;
import io.dataease.plugins.factory.DataEasePluginFactory;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ExtDDLProviderFactory {
private static final Map<String, DataFillingPlugin> templateMap = new ConcurrentHashMap<>();
public static ExtDDLProvider getExtDDLProvider(String type) {
DatasourceConfiguration.DatasourceType datasourceType = DatasourceConfiguration.DatasourceType.valueOf(type);
switch (datasourceType) {
case mysql:
case mariadb:
case mysql, mariadb -> {
return SpringContextUtil.getApplicationContext().getBean("mysqlExtDDLProvider", ExtDDLProvider.class);
}
}
return null;
ExtDDLProvider instance = getInstance(type);
if (instance == null) {
DEException.throwException("插件异常,请检查插件");
}
return instance;
}
public static ExtDDLProvider getInstance(String type) {
if (!LicenseUtil.licenseValid()) DEException.throwException("插件功能只对企业版本可用!");
String key = "df_" + type;
return templateMap.get(key);
}
public static void loadPlugin(String type, DataFillingPlugin plugin) {
if (!LicenseUtil.licenseValid()) DEException.throwException("插件功能只对企业版本可用!");
String key = "df_" + type;
if (templateMap.containsKey(key)) return;
templateMap.put(key, plugin);
try {
String moduleName = plugin.getPluginInfo().getModuleName();
DataEasePluginFactory.loadTemplate(moduleName, plugin);
} catch (Exception e) {
LogUtil.error(e.getMessage(), new Throwable(e));
DEException.throwException(e);
}
}
public static List<XpackPluginsDfVO> getDfConfigList() {
if (!LicenseUtil.licenseValid()) DEException.throwException("插件功能只对企业版本可用!");
return templateMap.values().stream().map(DataFillingPlugin::getConfig).toList();
}
}

View File

@ -0,0 +1,37 @@
package io.dataease.extensions.datafilling.plugin;
import io.dataease.exception.DEException;
import io.dataease.extensions.datafilling.factory.ExtDDLProviderFactory;
import io.dataease.extensions.datafilling.provider.ExtDDLProvider;
import io.dataease.extensions.datafilling.vo.XpackPluginsDfVO;
import io.dataease.license.utils.JsonUtil;
import io.dataease.plugins.template.DataEasePlugin;
import io.dataease.plugins.vo.DataEasePluginVO;
public abstract class DataFillingPlugin extends ExtDDLProvider implements DataEasePlugin {
@Override
public void loadPlugin() {
XpackPluginsDfVO viewConfig = getConfig();
ExtDDLProviderFactory.loadPlugin(viewConfig.getType(), this);
}
public XpackPluginsDfVO getConfig() {
DataEasePluginVO pluginInfo = null;
try {
pluginInfo = getPluginInfo();
} catch (Exception e) {
DEException.throwException(e);
}
String config = pluginInfo.getConfig();
XpackPluginsDfVO vo = JsonUtil.parseObject(config, XpackPluginsDfVO.class);
vo.setIcon(pluginInfo.getIcon());
return vo;
}
@Override
public void unloadPlugin() {
}
}

View File

@ -15,8 +15,6 @@ public abstract class ExtDDLProvider {
public final String DEFAULT_DATE_FORMAT_STR = "yyyy-MM-dd HH:mm:ss";
public abstract boolean supportDataFilling();
public abstract String createTableSql(String table, List<ExtTableField> formFields);
public abstract String getTableFieldsSql(String table);

View File

@ -0,0 +1,81 @@
package io.dataease.extensions.datafilling.utils;
import io.dataease.license.utils.LogUtil;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class BeanUtils {
public static <T> T copyBean(T target, Object source) {
try {
org.springframework.beans.BeanUtils.copyProperties(source, target);
return target;
} catch (Exception e) {
throw new RuntimeException("Failed to copy object: ", e);
}
}
public static <T> T copyBean(T target, Object source, String... ignoreProperties) {
try {
org.springframework.beans.BeanUtils.copyProperties(source, target, ignoreProperties);
return target;
} catch (Exception e) {
throw new RuntimeException("Failed to copy object: ", e);
}
}
public static Object getFieldValueByName(String fieldName, Object bean) {
try {
if (StringUtils.isBlank(fieldName)) {
return null;
}
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = bean.getClass().getMethod(getter);
return method.invoke(bean);
} catch (Exception e) {
LogUtil.error("failed to getFieldValueByName. ", e);
return null;
}
}
public static void setFieldValueByName(Object bean, String fieldName, Object value, Class<?> type) {
try {
if (StringUtils.isBlank(fieldName)) {
return;
}
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String setter = "set" + firstLetter + fieldName.substring(1);
Method method = bean.getClass().getMethod(setter, type);
method.invoke(bean, value);
} catch (Exception e) {
LogUtil.error("failed to setFieldValueByName. ", e);
}
}
public static Method getMethod(Object bean, String fieldName, Class<?> type) {
try {
if (StringUtils.isBlank(fieldName)) {
return null;
}
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String setter = "set" + firstLetter + fieldName.substring(1);
return bean.getClass().getMethod(setter, type);
} catch (Exception e) {
return null;
}
}
public static List<String> getFieldNames(Class<?> clazz) {
List<String> fieldNames = new ArrayList<>();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
fieldNames.add(field.getName());
}
return fieldNames;
}
}

View File

@ -0,0 +1,23 @@
package io.dataease.extensions.datafilling.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class XpackPluginsDfVO implements Serializable {
@Serial
private static final long serialVersionUID = 5059944608544058565L;
private Long id;
private String icon;
private String category;
private String type;
private Integer flag;
}