mirror of
https://github.com/dataease/dataease.git
synced 2026-06-10 23:09:59 +08:00
perf: SQLBot 数据源接口 行列权限机制
This commit is contained in:
committed by
fit2cloud-chenyw
parent
23fbf9bab8
commit
7d43f7bdca
@@ -14,24 +14,49 @@ public interface DataSetAssistantMapper {
|
||||
@Select(
|
||||
"""
|
||||
select
|
||||
cdt.id, cdt.datasource_id, cdt.table_name, cdt.info,
|
||||
cdg.name as dataset_name,
|
||||
cd.name as ds_name,
|
||||
cd.description as ds_desc,
|
||||
cd.type as ds_type,
|
||||
cd.configuration as ds_config,
|
||||
cd.id as cd_id,
|
||||
cd.name as cd_name,
|
||||
cd.description as cd_description,
|
||||
cd.type as cd_type,
|
||||
cd.configuration as cd_configuration,
|
||||
|
||||
cdtf.id as field_id,
|
||||
cdtf.origin_name,
|
||||
cdtf.name as field_show_name,
|
||||
cdtf.description as field_desc,
|
||||
cdtf.dataease_name,
|
||||
cdtf.type as field_type
|
||||
cdg.id as cdg_id,
|
||||
cdg.name as cdg_name,
|
||||
cdg.type as cdg_type,
|
||||
cdg.mode as cdg_model,
|
||||
cdg.info as cdg_info,
|
||||
cdg.union_sql as cdg_union_sql,
|
||||
cdg.is_cross as cdg_is_cross,
|
||||
|
||||
from `core_dataset_table` cdt
|
||||
left join `core_datasource` cd on cdt.datasource_id = cd.id
|
||||
left join `core_dataset_table_field` cdtf on cdtf.dataset_table_id = cdt.id
|
||||
left join `core_dataset_group` cdg on cdg.id = cdt.dataset_group_id
|
||||
cdt.id as cdt_id,
|
||||
cdt.table_name as cdt_table_name,
|
||||
cdt.type as cdt_type,
|
||||
cdt.info as cdt_info,
|
||||
cdt.sql_variable_details as cdt_sql_variable_details,
|
||||
|
||||
cdtf.id as cdtf_id,
|
||||
cdtf.origin_name as cdtf_origin_name,
|
||||
cdtf.name as cdtf_name,
|
||||
cdtf.description as cdtf_description,
|
||||
cdtf.dataease_name as cdtf_dataease_name,
|
||||
cdtf.field_short_name as cdtf_field_short_name,
|
||||
cdtf.group_list as cdtf_group_list,
|
||||
cdtf.other_group as cdtf_other_group,
|
||||
cdtf.group_type as cdtf_group_type,
|
||||
cdtf.type as cdtf_type,
|
||||
cdtf.de_type as cdtf_de_type,
|
||||
cdtf.de_extract_type as cdtf_de_extract_type,
|
||||
cdtf.ext_field as cdtf_ext_field,
|
||||
cdtf.checked as cdtf_checked,
|
||||
cdtf.accuracy as cdtf_accuracy,
|
||||
cdtf.date_format as cdtf_date_format,
|
||||
cdtf.date_format_type as cdtf_date_format_type,
|
||||
cdtf.params as cdtf_params
|
||||
|
||||
from `core_dataset_group` cdg
|
||||
left join `core_dataset_table` cdt on cdg.id = cdt.dataset_group_id
|
||||
left join `core_dataset_table_field` cdtf on cdtf.dataset_group_id = cdg.id
|
||||
inner join `core_datasource` cd on cdt.datasource_id = cd.id
|
||||
where cdg.is_cross != 1 and (cd.STATUS IS NULL OR cd.STATUS != 'Error')
|
||||
${ew.customSqlSegment}
|
||||
"""
|
||||
@@ -52,23 +77,49 @@ public interface DataSetAssistantMapper {
|
||||
) temp
|
||||
)
|
||||
SELECT
|
||||
cdt.id, cdt.datasource_id, cdt.table_name, cdt.info,
|
||||
cdg.name as dataset_name,
|
||||
cd.name as ds_name,
|
||||
cd.description as ds_desc,
|
||||
cd.type as ds_type,
|
||||
cd.configuration as ds_config,
|
||||
cdtf.id as field_id,
|
||||
cdtf.origin_name,
|
||||
cdtf.name as field_show_name,
|
||||
cdtf.description as field_desc,
|
||||
cdtf.dataease_name,
|
||||
cdtf.type as field_type
|
||||
cd.id as cd_id,
|
||||
cd.name as cd_name,
|
||||
cd.description as cd_description,
|
||||
cd.type as cd_type,
|
||||
cd.configuration as cd_configuration,
|
||||
|
||||
cdg.id as cdg_id,
|
||||
cdg.name as cdg_name,
|
||||
cdg.type as cdg_type,
|
||||
cdg.mode as cdg_model,
|
||||
cdg.info as cdg_info,
|
||||
cdg.union_sql as cdg_union_sql,
|
||||
cdg.is_cross as cdg_is_cross,
|
||||
|
||||
cdt.id as cdt_id,
|
||||
cdt.table_name as cdt_table_name,
|
||||
cdt.type as cdt_type,
|
||||
cdt.info as cdt_info,
|
||||
cdt.sql_variable_details as cdt_sql_variable_details,
|
||||
|
||||
cdtf.id as cdtf_id,
|
||||
cdtf.origin_name as cdtf_origin_name,
|
||||
cdtf.name as cdtf_name,
|
||||
cdtf.description as cdtf_description,
|
||||
cdtf.dataease_name as cdtf_dataease_name,
|
||||
cdtf.field_short_name as cdtf_field_short_name,
|
||||
cdtf.group_list as cdtf_group_list,
|
||||
cdtf.other_group as cdtf_other_group,
|
||||
cdtf.group_type as cdtf_group_type,
|
||||
cdtf.type as cdtf_type,
|
||||
cdtf.de_type as cdtf_de_type,
|
||||
cdtf.de_extract_type as cdtf_de_extract_type,
|
||||
cdtf.ext_field as cdtf_ext_field,
|
||||
cdtf.checked as cdtf_checked,
|
||||
cdtf.accuracy as cdtf_accuracy,
|
||||
cdtf.date_format as cdtf_date_format,
|
||||
cdtf.date_format_type as cdtf_date_format_type,
|
||||
cdtf.params as cdtf_params
|
||||
FROM `core_dataset_table` cdt
|
||||
INNER JOIN `core_datasource` cd ON cdt.datasource_id = cd.id and (cd.STATUS IS NULL OR cd.STATUS != 'Error')
|
||||
INNER JOIN `core_dataset_group` cdg ON cdg.id = cdt.dataset_group_id
|
||||
AND cdg.is_cross != 1
|
||||
INNER JOIN `core_dataset_table_field` cdtf ON cdtf.dataset_table_id = cdt.id
|
||||
INNER JOIN `core_dataset_table_field` cdtf ON cdtf.dataset_group_id = cdg.id
|
||||
where not exists( select 1 from user_ds_permissions ds_p where cd.id = ds_p.resource_id )
|
||||
and not exists( select 1 from user_dg_permissions dg_p where cdg.id = dg_p.resource_id )
|
||||
${ew.customSqlSegment}
|
||||
@@ -118,33 +169,50 @@ public interface DataSetAssistantMapper {
|
||||
</choose>
|
||||
)
|
||||
SELECT
|
||||
cdt.id, cdt.datasource_id, cdt.table_name, cdt.info,
|
||||
cdg.id as dataset_group_id,
|
||||
cdg.name as dataset_name,
|
||||
cd.name as ds_name,
|
||||
cd.description as ds_desc,
|
||||
cd.type as ds_type,
|
||||
cd.configuration as ds_config,
|
||||
cdtf.id as field_id,
|
||||
cdtf.origin_name,
|
||||
cdtf.name as field_show_name,
|
||||
cdtf.description as field_desc,
|
||||
cdtf.dataease_name,
|
||||
cdtf.field_short_name,
|
||||
cdtf.group_type,
|
||||
cdtf.de_type,
|
||||
cdtf.de_extract_type,
|
||||
cdtf.ext_field,
|
||||
cdtf.date_format,
|
||||
cdtf.date_format_type,
|
||||
cdtf.params,
|
||||
cdtf.type as field_type
|
||||
cd.id as cd_id,
|
||||
cd.name as cd_name,
|
||||
cd.description as cd_description,
|
||||
cd.type as cd_type,
|
||||
cd.configuration as cd_configuration,
|
||||
|
||||
cdg.id as cdg_id,
|
||||
cdg.name as cdg_name,
|
||||
cdg.type as cdg_type,
|
||||
cdg.mode as cdg_model,
|
||||
cdg.info as cdg_info,
|
||||
cdg.union_sql as cdg_union_sql,
|
||||
cdg.is_cross as cdg_is_cross,
|
||||
|
||||
cdt.id as cdt_id,
|
||||
cdt.table_name as cdt_table_name,
|
||||
cdt.type as cdt_type,
|
||||
cdt.info as cdt_info,
|
||||
cdt.sql_variable_details as cdt_sql_variable_details,
|
||||
|
||||
cdtf.id as cdtf_id,
|
||||
cdtf.origin_name as cdtf_origin_name,
|
||||
cdtf.name as cdtf_name,
|
||||
cdtf.description as cdtf_description,
|
||||
cdtf.dataease_name as cdtf_dataease_name,
|
||||
cdtf.field_short_name as cdtf_field_short_name,
|
||||
cdtf.group_list as cdtf_group_list,
|
||||
cdtf.other_group as cdtf_other_group,
|
||||
cdtf.group_type as cdtf_group_type,
|
||||
cdtf.type as cdtf_type,
|
||||
cdtf.de_type as cdtf_de_type,
|
||||
cdtf.de_extract_type as cdtf_de_extract_type,
|
||||
cdtf.ext_field as cdtf_ext_field,
|
||||
cdtf.checked as cdtf_checked,
|
||||
cdtf.accuracy as cdtf_accuracy,
|
||||
cdtf.date_format as cdtf_date_format,
|
||||
cdtf.date_format_type as cdtf_date_format_type,
|
||||
cdtf.params as cdtf_params
|
||||
FROM `core_dataset_table` cdt
|
||||
INNER JOIN `core_datasource` cd ON cdt.datasource_id = cd.id
|
||||
AND (cd.STATUS IS NULL OR cd.STATUS != 'Error')
|
||||
INNER JOIN `core_dataset_group` cdg ON cdg.id = cdt.dataset_group_id
|
||||
AND cdg.is_cross != 1
|
||||
INNER JOIN `core_dataset_table_field` cdtf ON cdtf.dataset_table_id = cdt.id
|
||||
INNER JOIN `core_dataset_table_field` cdtf ON cdtf.dataset_group_id = cdg.id
|
||||
INNER JOIN user_ds_permissions ds_p ON cd.id = ds_p.resource_id
|
||||
INNER JOIN user_dg_permissions dg_p ON cdg.id = dg_p.resource_id
|
||||
${ew.customSqlSegment}
|
||||
|
||||
@@ -1,41 +1,64 @@
|
||||
package io.dataease.dataset.manage;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.dataease.api.dataset.union.DatasetGroupInfoDTO;
|
||||
import io.dataease.api.dataset.union.DatasetTableInfoDTO;
|
||||
import io.dataease.api.dataset.union.UnionDTO;
|
||||
import io.dataease.api.dataset.vo.DataSQLBotAssistantVO;
|
||||
import io.dataease.api.dataset.vo.SQLBotAssistanTable;
|
||||
import io.dataease.api.dataset.vo.SQLBotAssistantField;
|
||||
import io.dataease.api.permissions.dataset.api.ColumnPermissionsApi;
|
||||
import io.dataease.api.permissions.dataset.api.RowPermissionsApi;
|
||||
import io.dataease.api.permissions.dataset.dto.DataSetColumnPermissionsDTO;
|
||||
import io.dataease.api.permissions.dataset.dto.DataSetRowPermissionsTreeDTO;
|
||||
import io.dataease.api.permissions.dataset.dto.DatasetRowPermissionsTreeRequest;
|
||||
import io.dataease.api.permissions.role.api.RoleApi;
|
||||
import io.dataease.api.permissions.role.dto.RoleRequest;
|
||||
import io.dataease.api.permissions.role.vo.RoleVO;
|
||||
import io.dataease.auth.bo.TokenUserBO;
|
||||
import io.dataease.commons.utils.EncryptUtils;
|
||||
import io.dataease.constant.ColumnPermissionConstants;
|
||||
import io.dataease.dataset.dao.auto.entity.CoreDatasetGroup;
|
||||
import io.dataease.dataset.dao.ext.mapper.DataSetAssistantMapper;
|
||||
import io.dataease.dataset.utils.TableUtils;
|
||||
import io.dataease.datasource.dao.auto.entity.CoreDatasource;
|
||||
import io.dataease.datasource.manage.EngineManage;
|
||||
import io.dataease.engine.constant.ExtFieldConstant;
|
||||
import io.dataease.engine.sql.SQLProvider;
|
||||
import io.dataease.engine.trans.Field2SQLObj;
|
||||
import io.dataease.engine.trans.Order2SQLObj;
|
||||
import io.dataease.engine.trans.Table2SQLObj;
|
||||
import io.dataease.engine.trans.WhereTree2Str;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.extensions.datasource.api.PluginManageApi;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.extensions.datasource.factory.ProviderFactory;
|
||||
import io.dataease.extensions.datasource.model.SQLMeta;
|
||||
import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.extensions.datasource.vo.Configuration;
|
||||
import io.dataease.extensions.datasource.vo.DatasourceConfiguration;
|
||||
import io.dataease.extensions.view.dto.ColumnPermissionItem;
|
||||
import io.dataease.extensions.view.dto.ColumnPermissions;
|
||||
import io.dataease.extensions.view.dto.DatasetRowPermissionsTreeItem;
|
||||
import io.dataease.extensions.view.dto.DatasetRowPermissionsTreeObj;
|
||||
import io.dataease.home.manage.DeIndexManage;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.utils.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
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;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Component
|
||||
public class DatasetSQLBotManage {
|
||||
|
||||
@@ -56,6 +79,12 @@ public class DatasetSQLBotManage {
|
||||
@Resource
|
||||
private PermissionManage permissionManage;
|
||||
|
||||
@Resource
|
||||
private DatasetSQLManage datasetSQLManage;
|
||||
|
||||
@Autowired(required = false)
|
||||
private PluginManageApi pluginManage;
|
||||
|
||||
@Value("${dataease.sqlbot.encrypt:false}")
|
||||
private boolean encryptEnabled;
|
||||
|
||||
@@ -102,29 +131,8 @@ public class DatasetSQLBotManage {
|
||||
}
|
||||
|
||||
private Map<Long, List<DataSetRowPermissionsTreeDTO>> getRowPermission(Long uid, List<Long> roleIds) {
|
||||
RowPermissionsApi rowPermissionsApi = CommonBeanFactory.getBean(RowPermissionsApi.class);
|
||||
Objects.requireNonNull(rowPermissionsApi);
|
||||
|
||||
DatasetRowPermissionsTreeRequest request = new DatasetRowPermissionsTreeRequest();
|
||||
request.setEnable(true);
|
||||
|
||||
request.setAuthTargetId(uid);
|
||||
request.setAuthTargetType("user");
|
||||
List<DataSetRowPermissionsTreeDTO> permissionsTreeDTOS = rowPermissionsApi.list(request);
|
||||
|
||||
if (ObjectUtils.isNotEmpty(roleIds)) {
|
||||
request.setAuthTargetId(null);
|
||||
request.setAuthTargetIds(roleIds);
|
||||
request.setAuthTargetType("role");
|
||||
List<DataSetRowPermissionsTreeDTO> rolePermissionDTOS = rowPermissionsApi.list(request);
|
||||
if (CollectionUtils.isNotEmpty(rolePermissionDTOS)) {
|
||||
permissionsTreeDTOS.addAll(rolePermissionDTOS);
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isEmpty(permissionsTreeDTOS)) {
|
||||
return null;
|
||||
}
|
||||
return permissionsTreeDTOS.stream().collect(Collectors.groupingBy(DataSetRowPermissionsTreeDTO::getDatasetId));
|
||||
List<DataSetRowPermissionsTreeDTO> datasetRowPermissions = permissionManage.getRowPermissionsTree(null, uid);
|
||||
return datasetRowPermissions.stream().collect(Collectors.groupingBy(DataSetRowPermissionsTreeDTO::getDatasetId));
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +146,6 @@ public class DatasetSQLBotManage {
|
||||
Boolean model = deIndexManage.xpackModel();
|
||||
List<Map<String, Object>> list = null;
|
||||
boolean isAdmin = uid == 1;
|
||||
boolean withColsOrRowsPermission = false;
|
||||
QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtils.isNotEmpty(datasetId)) {
|
||||
queryWrapper.eq("cdg.id", datasetId);
|
||||
@@ -165,9 +172,8 @@ public class DatasetSQLBotManage {
|
||||
isRootRole = roleVOS.stream().anyMatch(RoleVO::isRoot);
|
||||
roleIds = roleVOS.stream().map(RoleVO::getId).toList();
|
||||
|
||||
/*colPermissionMap = getColPermission(uid, roleIds);
|
||||
colPermissionMap = getColPermission(uid, roleIds);
|
||||
rowPermissionMap = getRowPermission(uid, roleIds);
|
||||
withColsOrRowsPermission = MapUtils.isNotEmpty(colPermissionMap) || MapUtils.isNotEmpty(rowPermissionMap);*/
|
||||
}
|
||||
list = dataSetAssistantMapper.queryEnterprise(oid, uid, isRootRole, queryWrapper);
|
||||
}
|
||||
@@ -180,7 +186,7 @@ public class DatasetSQLBotManage {
|
||||
deEngine = engineManage.getDeEngine();
|
||||
for (Map<String, Object> row : list) {
|
||||
// build ds
|
||||
String datasourceId = row.get("datasource_id").toString();
|
||||
String datasourceId = row.get("cd_id").toString();
|
||||
DataSQLBotAssistantVO vo = dsFlagMap.get(datasourceId);
|
||||
if (ObjectUtils.isEmpty(vo)) {
|
||||
vo = buildDs(row);
|
||||
@@ -190,7 +196,7 @@ public class DatasetSQLBotManage {
|
||||
result.add(vo);
|
||||
}
|
||||
// build table
|
||||
String tableId = row.get("id").toString();
|
||||
String tableId = row.get("cdg_id").toString();
|
||||
SQLBotAssistanTable table = tableFlagMap.get(tableId);
|
||||
if (ObjectUtils.isEmpty(table)) {
|
||||
table = buildTable(row);
|
||||
@@ -200,7 +206,7 @@ public class DatasetSQLBotManage {
|
||||
vo.getTables().add(table);
|
||||
}
|
||||
// build field
|
||||
String fieldId = row.get("field_id").toString();
|
||||
String fieldId = row.get("cdtf_id").toString();
|
||||
SQLBotAssistantField field = fieldFlagMap.get(fieldId);
|
||||
if (ObjectUtils.isEmpty(field)) {
|
||||
field = buildField(row);
|
||||
@@ -208,71 +214,200 @@ public class DatasetSQLBotManage {
|
||||
continue;
|
||||
fieldFlagMap.put(fieldId, field);
|
||||
table.getFields().add(field);
|
||||
if (field.isNeedTransform()) {
|
||||
table.setNeedTransform(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*if (withColsOrRowsPermission) {
|
||||
result = filterPermissions(result, list, colPermissionMap, rowPermissionMap);
|
||||
}*/
|
||||
filterPermissions(result, list, colPermissionMap, rowPermissionMap);
|
||||
LogUtil.info("sqlbot ds api result: {}", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<DataSQLBotAssistantVO> filterPermissions(
|
||||
public void buildFieldName(Map<String, Object> sqlMap, List<DatasetTableFieldDTO> fields) {
|
||||
// 获取内层union sql和字段
|
||||
List<DatasetTableFieldDTO> unionFields = (List<DatasetTableFieldDTO>) sqlMap.get("field");
|
||||
for (DatasetTableFieldDTO datasetTableFieldDTO : fields) {
|
||||
if (Objects.equals(datasetTableFieldDTO.getExtField(), ExtFieldConstant.EXT_NORMAL)) {
|
||||
for (DatasetTableFieldDTO fieldDTO : unionFields) {
|
||||
if (Objects.equals(datasetTableFieldDTO.getDatasetTableId(), fieldDTO.getDatasetTableId())
|
||||
&& Objects.equals(datasetTableFieldDTO.getOriginName(), fieldDTO.getOriginName())) {
|
||||
datasetTableFieldDTO.setDataeaseName(fieldDTO.getDataeaseName());
|
||||
datasetTableFieldDTO.setFieldShortName(fieldDTO.getFieldShortName());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Objects.equals(datasetTableFieldDTO.getExtField(), ExtFieldConstant.EXT_CALC)) {
|
||||
String dataeaseName = TableUtils.fieldNameShort(datasetTableFieldDTO.getId() + "_" + datasetTableFieldDTO.getOriginName());
|
||||
datasetTableFieldDTO.setDataeaseName(dataeaseName);
|
||||
datasetTableFieldDTO.setFieldShortName(dataeaseName);
|
||||
datasetTableFieldDTO.setDeExtractType(datasetTableFieldDTO.getDeType());
|
||||
}
|
||||
if (Objects.equals(datasetTableFieldDTO.getExtField(), ExtFieldConstant.EXT_GROUP)) {
|
||||
String dataeaseName = TableUtils.fieldNameShort(datasetTableFieldDTO.getId() + "_" + datasetTableFieldDTO.getOriginName());
|
||||
datasetTableFieldDTO.setDataeaseName(dataeaseName);
|
||||
datasetTableFieldDTO.setFieldShortName(dataeaseName);
|
||||
datasetTableFieldDTO.setDeExtractType(0);
|
||||
datasetTableFieldDTO.setDeType(0);
|
||||
datasetTableFieldDTO.setGroupType("d");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void getField(DatasetRowPermissionsTreeObj tree, Map<Long, DatasetTableFieldDTO> fieldMap) {
|
||||
if (ObjectUtils.isNotEmpty(tree)) {
|
||||
if (ObjectUtils.isNotEmpty(tree.getItems())) {
|
||||
for (DatasetRowPermissionsTreeItem item : tree.getItems()) {
|
||||
if (ObjectUtils.isNotEmpty(item)) {
|
||||
if (StringUtils.equalsIgnoreCase(item.getType(), "item") || ObjectUtils.isEmpty(item.getSubTree())) {
|
||||
item.setField(fieldMap.get(item.getFieldId()));
|
||||
} else if (StringUtils.equalsIgnoreCase(item.getType(), "tree") || (ObjectUtils.isNotEmpty(item.getSubTree()) && StringUtils.isNotEmpty(item.getSubTree().getLogic()))) {
|
||||
getField(item.getSubTree(), fieldMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void rebuildTable(SQLBotAssistanTable table, List<DataSetColumnPermissionsDTO> columnPermissionsDTOS, List<DataSetRowPermissionsTreeDTO> rowPermissionsTree) {
|
||||
Map<String, Object> rowData = table.getRowData();
|
||||
CoreDatasetGroup coreDatasetGroup = BeanUtils.mapToBean(rowData, CoreDatasetGroup.class);
|
||||
|
||||
DatasetGroupInfoDTO datasetGroupInfoDTO = new DatasetGroupInfoDTO();
|
||||
BeanUtils.copyBean(datasetGroupInfoDTO, coreDatasetGroup);
|
||||
|
||||
datasetGroupInfoDTO.setUnionSql(null);
|
||||
List<UnionDTO> unionDTOList = JsonUtil.parseList(coreDatasetGroup.getInfo(), new TypeReference<>() {
|
||||
});
|
||||
datasetGroupInfoDTO.setUnion(unionDTOList);
|
||||
|
||||
List<SQLBotAssistantField> sqlbotFields = table.getFields();
|
||||
|
||||
List<DatasetTableFieldDTO> dsFields = sqlbotFields.stream().map(field -> {
|
||||
Map<String, Object> fieldRowData = field.getRowData();
|
||||
DatasetTableFieldDTO fieldDTO = BeanUtils.mapToBean(fieldRowData, DatasetTableFieldDTO.class);
|
||||
fieldDTO.setFieldShortName(fieldDTO.getDataeaseName());
|
||||
return fieldDTO;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
datasetGroupInfoDTO.setAllFields(dsFields);
|
||||
Map<Long, DatasetTableFieldDTO> fieldMap = dsFields.stream().collect(Collectors.toMap(DatasetTableFieldDTO::getId, Function.identity()));
|
||||
if (CollectionUtils.isNotEmpty(rowPermissionsTree)) {
|
||||
rowPermissionsTree.forEach(treeDTO -> {
|
||||
DatasetRowPermissionsTreeObj tree = treeDTO.getTree();
|
||||
getField(tree, fieldMap);
|
||||
});
|
||||
}
|
||||
|
||||
Map<String, Object> sqlMap = null;
|
||||
try {
|
||||
sqlMap = datasetSQLManage.getUnionSQLForEdit(datasetGroupInfoDTO, null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String sql = (String) sqlMap.get("sql");
|
||||
|
||||
// 获取allFields
|
||||
List<DatasetTableFieldDTO> fields = datasetGroupInfoDTO.getAllFields();
|
||||
if (ObjectUtils.isEmpty(fields)) {
|
||||
DEException.throwException(Translator.get("i18n_no_fields"));
|
||||
}
|
||||
|
||||
List<DatasetTableFieldDTO> originFields = new ArrayList<>(fields);
|
||||
Map<String, ColumnPermissionItem> desensitizationList = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(columnPermissionsDTOS)) {
|
||||
List<ColumnPermissionItem> columnPermissionItems = new ArrayList<>();
|
||||
for (DataSetColumnPermissionsDTO dataSetColumnPermissionsDTO : columnPermissionsDTOS) {
|
||||
ColumnPermissions columnPermissions = JsonUtil.parseObject(dataSetColumnPermissionsDTO.getPermissions(), ColumnPermissions.class);
|
||||
if (!columnPermissions.getEnable()) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.equalsAnyIgnoreCase(dataSetColumnPermissionsDTO.getAuthTargetType(), "user", "role")) {
|
||||
columnPermissionItems.addAll(columnPermissions.getColumns().stream().filter(columnPermissionItem -> columnPermissionItem.getSelected()).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
fields = fields.stream().filter(field -> {
|
||||
List<ColumnPermissionItem> fieldColumnPermissionItems = columnPermissionItems.stream().filter(columnPermissionItem -> columnPermissionItem.getId().equals(field.getId())).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(fieldColumnPermissionItems)) {
|
||||
return true;
|
||||
}
|
||||
return fieldColumnPermissionItems.stream().map(ColumnPermissionItem::getOpt).toList().contains(ColumnPermissionConstants.Desensitization);
|
||||
}).collect(Collectors.toList());
|
||||
// fields = permissionManage.filterColumnPermissions(fields, desensitizationList, datasetGroupInfoDTO.getId(), null);
|
||||
if (ObjectUtils.isEmpty(fields)) {
|
||||
DEException.throwException(Translator.get("i18n_no_column_permission"));
|
||||
}
|
||||
}
|
||||
buildFieldName(sqlMap, originFields);
|
||||
Map<Long, DatasourceSchemaDTO> dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
List<String> dsList = new ArrayList<>();
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
dsList.add(next.getValue().getType());
|
||||
}
|
||||
boolean needOrder = Utils.isNeedOrder(dsList);
|
||||
sql = Utils.replaceSchemaAlias(sql, dsMap);
|
||||
Provider provider = ProviderFactory.getProvider(dsList.getFirst());
|
||||
|
||||
// build query sql
|
||||
SQLMeta sqlMeta = new SQLMeta();
|
||||
Table2SQLObj.table2sqlobj(sqlMeta, null, "(" + sql + ")", false);
|
||||
Field2SQLObj.field2sqlObj(sqlMeta, fields, fields, false, dsMap, Utils.getParams(fields), null, pluginManage, true);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, fields, false, dsMap, Utils.getParams(fields), null, pluginManage);
|
||||
Order2SQLObj.getOrders(sqlMeta, datasetGroupInfoDTO.getSortFields(), fields, false, dsMap, Utils.getParams(fields), null, pluginManage);
|
||||
String querySQL;
|
||||
querySQL = SQLProvider.createQuerySQL(sqlMeta, false, needOrder, false);
|
||||
querySQL = provider.rebuildSQL(querySQL, sqlMeta, false, dsMap);
|
||||
table.setSql(querySQL);
|
||||
}
|
||||
|
||||
private void filterPermissions(
|
||||
List<DataSQLBotAssistantVO> vos,
|
||||
List<Map<String, Object>> list,
|
||||
Map<Long, List<DataSetColumnPermissionsDTO>> colPermissionMap,
|
||||
Map<Long, List<DataSetRowPermissionsTreeDTO>> rowPermissionMap
|
||||
) {
|
||||
if (CollectionUtils.isEmpty(vos)) {
|
||||
return vos;
|
||||
return;
|
||||
}
|
||||
vos.forEach(vo -> {
|
||||
List<SQLBotAssistanTable> tables = vo.getTables();
|
||||
tables.forEach(table -> {
|
||||
Long datasetGroupId = table.getDatasetGroupId();
|
||||
List<DataSetColumnPermissionsDTO> dataSetColumnPermissionsDTOS = colPermissionMap.get(datasetGroupId);
|
||||
|
||||
List<ColumnPermissionItem> columnPermissionItems = new ArrayList<>();
|
||||
|
||||
for (DataSetColumnPermissionsDTO dataSetColumnPermissionsDTO : dataSetColumnPermissionsDTOS) {
|
||||
ColumnPermissions columnPermissions = JsonUtil.parseObject(dataSetColumnPermissionsDTO.getPermissions(), ColumnPermissions.class);
|
||||
if (!columnPermissions.getEnable()) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.equalsAnyIgnoreCase(dataSetColumnPermissionsDTO.getAuthTargetType(), "user", "role")) {
|
||||
columnPermissionItems.addAll(columnPermissions.getColumns().stream().filter(columnPermissionItem -> columnPermissionItem.getSelected()).collect(Collectors.toList()));
|
||||
}
|
||||
List<DataSetColumnPermissionsDTO> columnPermissionsDTOS = ObjectUtils.isEmpty(colPermissionMap) ? null : colPermissionMap.get(datasetGroupId);
|
||||
List<DataSetRowPermissionsTreeDTO> rowPermissionsTreeDTOS = ObjectUtils.isEmpty(rowPermissionMap) ? null : rowPermissionMap.get(datasetGroupId);
|
||||
if (table.isNeedTransform() || ObjectUtils.isNotEmpty(columnPermissionsDTOS) || ObjectUtils.isNotEmpty(rowPermissionsTreeDTOS)) {
|
||||
rebuildTable(table, columnPermissionsDTOS, rowPermissionsTreeDTOS);
|
||||
}
|
||||
List<SQLBotAssistantField> filterFields = table.getFields().stream().filter(field -> {
|
||||
List<ColumnPermissionItem> fieldColumnPermissionItems = columnPermissionItems.stream().filter(columnPermissionItem -> columnPermissionItem.getId().equals(field.getFieldId())).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(fieldColumnPermissionItems)) {
|
||||
return true;
|
||||
}
|
||||
return fieldColumnPermissionItems.stream().map(ColumnPermissionItem::getOpt).toList().contains(ColumnPermissionConstants.Desensitization);
|
||||
}).collect(Collectors.toList());
|
||||
table.setFields(filterFields);
|
||||
});
|
||||
});
|
||||
return vos;
|
||||
}
|
||||
|
||||
private SQLBotAssistantField buildField(Map<String, Object> row) {
|
||||
SQLBotAssistantField field = new SQLBotAssistantField();
|
||||
if (ObjectUtils.isNotEmpty(row.get("field_id"))) {
|
||||
field.setFieldId(Long.parseLong(row.get("field_id").toString()));
|
||||
if (ObjectUtils.isNotEmpty(row.get("cdtf_id"))) {
|
||||
field.setFieldId(Long.parseLong(row.get("cdtf_id").toString()));
|
||||
}
|
||||
if (ObjectUtils.isNotEmpty(row.get("dataease_name"))) {
|
||||
field.setDataeaseName(row.get("dataease_name").toString());
|
||||
if (ObjectUtils.isNotEmpty(row.get("cdtf_dataease_name"))) {
|
||||
field.setDataeaseName(row.get("cdtf_dataease_name").toString());
|
||||
}
|
||||
field.setName(row.get("origin_name").toString());
|
||||
field.setType(row.get("field_type").toString());
|
||||
field.setComment(row.get("field_show_name").toString());
|
||||
field.setName(row.get("cdtf_origin_name").toString());
|
||||
field.setType(row.get("cdtf_type").toString());
|
||||
field.setComment(row.get("cdtf_name").toString());
|
||||
if (ObjectUtils.isNotEmpty(row.get("cdtf_ext_field")) && !row.get("cdtf_ext_field").equals(0)) {
|
||||
field.setNeedTransform(true);
|
||||
}
|
||||
Map<String, Object> fieldRowData = buildRowData(row, 3);
|
||||
fieldRowData.put("datasource_id", Long.parseLong(row.get("cd_id").toString()));
|
||||
fieldRowData.put("dataset_group_id", row.get("cdg_id"));
|
||||
fieldRowData.put("dataset_table_id", row.get("cdt_id"));
|
||||
field.setRowData(fieldRowData);
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
private DataSQLBotAssistantVO buildDs(Map<String, Object> row) {
|
||||
Object dsConfig = row.get("ds_config");
|
||||
Object dsConfig = row.get("cd_configuration");
|
||||
if (ObjectUtils.isEmpty(dsConfig) || StringUtils.isBlank(dsConfig.toString())) {
|
||||
return null;
|
||||
}
|
||||
@@ -280,7 +415,7 @@ public class DatasetSQLBotManage {
|
||||
if (StringUtils.isBlank(dsHost)) {
|
||||
dsHost = environment.getProperty("dataease.dataease-servers", String.class);
|
||||
}
|
||||
String dsType = row.get("ds_type").toString();
|
||||
String dsType = row.get("cd_type").toString();
|
||||
Configuration config = null;
|
||||
if (dsType.contains(DatasourceConfiguration.DatasourceType.Excel.name()) || dsType.contains(DatasourceConfiguration.DatasourceType.API.name())) {
|
||||
String config_json = EncryptUtils.aesDecrypt(deEngine.getConfiguration()).toString();
|
||||
@@ -298,18 +433,31 @@ public class DatasetSQLBotManage {
|
||||
vo.setExtraParams(config.getExtraParams());
|
||||
vo.setHost(config.getHost());
|
||||
vo.setPort(config.getPort());
|
||||
vo.setName(row.get("ds_name").toString());
|
||||
vo.setComment(ObjectUtils.isEmpty(row.get("ds_desc")) ? vo.getName() : row.get("ds_desc").toString());
|
||||
vo.setName(row.get("cd_name").toString());
|
||||
vo.setComment(ObjectUtils.isEmpty(row.get("cd_description")) ? vo.getName() : row.get("cd_description").toString());
|
||||
vo.setType(dsType);
|
||||
vo.setSchema(config.getSchema());
|
||||
vo.setUser(config.getUsername());
|
||||
vo.setPassword(config.getPassword());
|
||||
vo.setRowData(buildRowData(row, 0));
|
||||
if (encryptEnabled) {
|
||||
aesVO(vo);
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
private Map<String, Object> buildRowData(Map<String, Object> row, int level) {
|
||||
String[] levels = {"cd_", "cdg_", "cdt_", "cdtf_"};
|
||||
String alias = levels[level];
|
||||
Map<String, Object> filteredMap = new HashMap<>();
|
||||
row.forEach((key, value) -> {
|
||||
if (key.startsWith(alias)) {
|
||||
filteredMap.put(key.substring(alias.length()), value);
|
||||
}
|
||||
});
|
||||
return filteredMap;
|
||||
}
|
||||
|
||||
private void aesVO(DataSQLBotAssistantVO vo) {
|
||||
if (StringUtils.isNotBlank(vo.getHost())) {
|
||||
vo.setHost(aesEncrypt(vo.getHost()));
|
||||
@@ -330,21 +478,25 @@ public class DatasetSQLBotManage {
|
||||
|
||||
private SQLBotAssistanTable buildTable(Map<String, Object> row) {
|
||||
SQLBotAssistanTable table = new SQLBotAssistanTable();
|
||||
table.setName(row.get("table_name").toString());
|
||||
table.setComment(row.get("dataset_name").toString());
|
||||
if (ObjectUtils.isNotEmpty(row.get("dataset_group_id"))) {
|
||||
table.setDatasetGroupId(Long.parseLong(row.get("dataset_group_id").toString()));
|
||||
}
|
||||
table.setName(row.get("cdg_name").toString());
|
||||
table.setComment(row.get("cdg_name").toString());
|
||||
table.setDatasetGroupId(Long.parseLong(row.get("cdg_id").toString()));
|
||||
|
||||
Object infoObj = null;
|
||||
if (ObjectUtils.isNotEmpty(infoObj = row.get("info"))) {
|
||||
if (ObjectUtils.isNotEmpty(infoObj = row.get("cdt_info"))) {
|
||||
String info = infoObj.toString();
|
||||
DatasetTableInfoDTO tableInfoDTO = JsonUtil.parseObject(info, DatasetTableInfoDTO.class);
|
||||
if (StringUtils.isNotBlank(tableInfoDTO.getSql())) {
|
||||
String sql = new String(Base64.getDecoder().decode(tableInfoDTO.getSql()));
|
||||
table.setSql(sql);
|
||||
}
|
||||
if (StringUtils.isNotBlank(tableInfoDTO.getTable())) {
|
||||
table.setName(tableInfoDTO.getTable());
|
||||
}
|
||||
}
|
||||
Map<String, Object> tableRowData = buildRowData(row, 1);
|
||||
tableRowData.put("datasource_id", Long.parseLong(row.get("cd_id").toString()));
|
||||
table.setRowData(tableRowData);
|
||||
return table;
|
||||
}
|
||||
|
||||
|
||||
@@ -138,8 +138,10 @@ public class PermissionManage {
|
||||
// 获取当前数据集下,当前用户、角色、组织所有的行权限(非白名单,非禁用)
|
||||
List<DataSetRowPermissionsTreeDTO> records = rowPermissionsTree(datasetId, user);
|
||||
// 构建权限tree中的field,如果field不存在,置为null
|
||||
for (DataSetRowPermissionsTreeDTO record : records) {
|
||||
getField(record.getTree());
|
||||
if (ObjectUtils.isNotEmpty(datasetId)) {
|
||||
for (DataSetRowPermissionsTreeDTO record : records) {
|
||||
getField(record.getTree());
|
||||
}
|
||||
}
|
||||
return records;
|
||||
}
|
||||
@@ -154,7 +156,9 @@ public class PermissionManage {
|
||||
UserFormVO userEntity = getRowPermissionsApi().getUserById(userId);
|
||||
List<Long> roleIds = userEntity.getRoleIds().stream().map(x -> Long.valueOf(x)).collect(Collectors.toList());
|
||||
DatasetRowPermissionsTreeRequest dataSetRowPermissionsDTO = new DatasetRowPermissionsTreeRequest();
|
||||
dataSetRowPermissionsDTO.setDatasetId(datasetId);
|
||||
if (ObjectUtils.isNotEmpty(datasetId)) {
|
||||
dataSetRowPermissionsDTO.setDatasetId(datasetId);
|
||||
}
|
||||
dataSetRowPermissionsDTO.setEnable(true);
|
||||
|
||||
if (ObjectUtils.isNotEmpty(userId)) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.dataease.engine.trans;
|
||||
|
||||
import io.dataease.constant.DeTypeConstants;
|
||||
import io.dataease.engine.constant.ExtFieldConstant;
|
||||
import io.dataease.constant.SQLConstants;
|
||||
import io.dataease.engine.constant.ExtFieldConstant;
|
||||
import io.dataease.engine.func.FunctionConstant;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.extensions.datasource.api.PluginManageApi;
|
||||
@@ -17,12 +17,14 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static io.dataease.constant.SQLConstants.FIELD_DOT_FIX;
|
||||
|
||||
/**
|
||||
* @Author Junjun
|
||||
*/
|
||||
public class Field2SQLObj {
|
||||
|
||||
public static void field2sqlObj(SQLMeta meta, List<DatasetTableFieldDTO> fields, List<DatasetTableFieldDTO> originFields, boolean isCross, Map<Long, DatasourceSchemaDTO> dsMap, List<CalParam> fieldParam, List<CalParam> chartParam, PluginManageApi pluginManage) {
|
||||
public static void field2sqlObj(SQLMeta meta, List<DatasetTableFieldDTO> fields, List<DatasetTableFieldDTO> originFields, boolean isCross, Map<Long, DatasourceSchemaDTO> dsMap, List<CalParam> fieldParam, List<CalParam> chartParam, PluginManageApi pluginManage, boolean forSqlbot) {
|
||||
SQLObj tableObj = meta.getTable();
|
||||
if (ObjectUtils.isEmpty(tableObj)) {
|
||||
return;
|
||||
@@ -79,6 +81,13 @@ public class Field2SQLObj {
|
||||
}
|
||||
}
|
||||
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i);
|
||||
if (forSqlbot) {
|
||||
fieldAlias = x.getOriginName();
|
||||
if (ObjectUtils.isNotEmpty(x.getExtField()) && !x.getExtField().equals(ExtFieldConstant.EXT_NORMAL) && StringUtils.isNotBlank(x.getName())) {
|
||||
fieldAlias = x.getName();
|
||||
}
|
||||
fieldAlias = String.format(FIELD_DOT_FIX, fieldAlias);
|
||||
}
|
||||
// 处理横轴字段
|
||||
xFields.add(getXFields(x, originField, fieldAlias, isCross));
|
||||
}
|
||||
@@ -87,6 +96,10 @@ public class Field2SQLObj {
|
||||
meta.setXFieldsDialect(fieldsDialect);
|
||||
}
|
||||
|
||||
public static void field2sqlObj(SQLMeta meta, List<DatasetTableFieldDTO> fields, List<DatasetTableFieldDTO> originFields, boolean isCross, Map<Long, DatasourceSchemaDTO> dsMap, List<CalParam> fieldParam, List<CalParam> chartParam, PluginManageApi pluginManage) {
|
||||
field2sqlObj(meta, fields, originFields, isCross, dsMap, fieldParam, chartParam, pluginManage, false);
|
||||
}
|
||||
|
||||
public static SQLObj getXFields(DatasetTableFieldDTO f, String originField, String fieldAlias, boolean isCross) {
|
||||
String fieldName = "";
|
||||
if (originField != null) {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package io.dataease.api.dataset.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class DataSQLBotAssistantVO implements Serializable {
|
||||
@@ -31,4 +33,7 @@ public class DataSQLBotAssistantVO implements Serializable {
|
||||
|
||||
private List<SQLBotAssistanTable> tables = new ArrayList<>();
|
||||
|
||||
@JsonIgnore
|
||||
private Map<String, Object> rowData;
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class SQLBotAssistanTable implements Serializable {
|
||||
@@ -17,5 +18,11 @@ public class SQLBotAssistanTable implements Serializable {
|
||||
|
||||
@JsonIgnore
|
||||
private Long datasetGroupId;
|
||||
@JsonIgnore
|
||||
private boolean needTransform;
|
||||
@JsonIgnore
|
||||
private boolean needPermission;
|
||||
@JsonIgnore
|
||||
private Map<String, Object> rowData;
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class SQLBotAssistantField implements Serializable {
|
||||
@@ -15,4 +16,11 @@ public class SQLBotAssistantField implements Serializable {
|
||||
private Long fieldId;
|
||||
@JsonIgnore
|
||||
private String dataeaseName;
|
||||
|
||||
@JsonIgnore
|
||||
private boolean needTransform;
|
||||
@JsonIgnore
|
||||
private boolean needPermission;
|
||||
@JsonIgnore
|
||||
private Map<String, Object> rowData;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ package io.dataease.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BeanUtils {
|
||||
|
||||
@@ -77,4 +79,64 @@ public class BeanUtils {
|
||||
}
|
||||
return fieldNames;
|
||||
}
|
||||
|
||||
private static String underscoreToCamel(String underscore) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
String[] parts = underscore.split("_");
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
String part = parts[i];
|
||||
if (part.isEmpty()) continue;
|
||||
if (i == 0) {
|
||||
result.append(part);
|
||||
} else {
|
||||
result.append(Character.toUpperCase(part.charAt(0)))
|
||||
.append(part.substring(1).toLowerCase());
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
public static <T> T mapToBean(Map<String, Object> map, Class<T> clazz) {
|
||||
try {
|
||||
T bean = clazz.getDeclaredConstructor().newInstance();
|
||||
PropertyDescriptor[] descriptors = org.springframework.beans.BeanUtils.getPropertyDescriptors(clazz);
|
||||
|
||||
for (PropertyDescriptor descriptor : descriptors) {
|
||||
String propertyName = descriptor.getName();
|
||||
if ("class".equals(propertyName)) continue;
|
||||
|
||||
// 查找Map中对应的key(支持驼峰和下划线)
|
||||
Object value = findValueInMap(map, propertyName);
|
||||
if (value != null && descriptor.getWriteMethod() != null) {
|
||||
descriptor.getWriteMethod().invoke(bean, value);
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Map转Bean失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object findValueInMap(Map<String, Object> map, String propertyName) {
|
||||
Object value = map.get(propertyName);
|
||||
if (value != null) return value;
|
||||
|
||||
String underscore = camelToUnderscore(propertyName);
|
||||
value = map.get(underscore);
|
||||
if (value != null) return value;
|
||||
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
String camelKey = underscoreToCamel(entry.getKey());
|
||||
if (propertyName.equals(camelKey)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String camelToUnderscore(String camel) {
|
||||
return camel.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user