diff --git a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java index c75ede9ddc..6f2dcdb93a 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java +++ b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java @@ -175,7 +175,7 @@ public class ChartDataManage { FilterTreeObj fieldCustomFilter = view.getCustomFilter(); List drill = new ArrayList<>(view.getDrillFields()); - DatasetGroupInfoDTO table = datasetGroupManage.get(view.getTableId(), null); + DatasetGroupInfoDTO table = datasetGroupManage.getDatasetGroupInfoDTO(view.getTableId(), null); if (table == null) { DEException.throwException(ResultCode.DATA_IS_WRONG.code(), Translator.get("i18n_no_ds")); } diff --git a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java index 9bb1cc8812..8d6980fee9 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java +++ b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java @@ -4,8 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import io.dataease.api.chart.dto.*; -import io.dataease.api.chart.vo.ViewSelectorVO; import io.dataease.api.chart.filter.FilterTreeObj; +import io.dataease.api.chart.vo.ViewSelectorVO; import io.dataease.api.dataset.union.model.SQLObj; import io.dataease.chart.dao.auto.entity.CoreChartView; import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper; @@ -20,6 +20,7 @@ import io.dataease.engine.utils.Utils; import io.dataease.exception.DEException; import io.dataease.i18n.Translator; import io.dataease.utils.BeanUtils; +import io.dataease.utils.IDUtils; import io.dataease.utils.JsonUtil; import jakarta.annotation.Resource; import org.apache.commons.lang3.ObjectUtils; @@ -120,6 +121,7 @@ public class ChartViewManege { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("dataset_group_id", id); wrapper.eq("checked", true); + wrapper.isNull("chart_id"); List fields = coreDatasetTableFieldMapper.selectList(wrapper); List collect = fields.stream().map(ele -> { @@ -173,6 +175,36 @@ public class ChartViewManege { return map; } + public void copyField(Long id, Long chartId) { + CoreDatasetTableField coreDatasetTableField = coreDatasetTableFieldMapper.selectById(id); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("dataset_group_id", coreDatasetTableField.getDatasetGroupId()); + List coreDatasetTableFields = coreDatasetTableFieldMapper.selectList(queryWrapper); + HashMap map = new HashMap<>(); + for (CoreDatasetTableField ele : coreDatasetTableFields) { + map.put(ele.getName(), ele.getName()); + } + newName(map, coreDatasetTableField, coreDatasetTableField.getName()); + coreDatasetTableField.setChartId(chartId); + coreDatasetTableField.setExtField(2); + coreDatasetTableField.setOriginName("[" + id + "]"); + coreDatasetTableField.setId(IDUtils.snowID()); + coreDatasetTableFieldMapper.insert(coreDatasetTableField); + } + + private void newName(HashMap map, CoreDatasetTableField coreDatasetTableField, String name) { + name = name + "_copy"; + if (map.containsKey(name)) { + newName(map, coreDatasetTableField, name); + } else { + coreDatasetTableField.setName(name); + } + } + + public void deleteField(Long id) { + coreDatasetTableFieldMapper.deleteById(id); + } + public DatasetTableFieldDTO createCountField(Long id) { DatasetTableFieldDTO dto = new DatasetTableFieldDTO(); dto.setId(-1L); diff --git a/core/core-backend/src/main/java/io/dataease/chart/server/ChartDataServer.java b/core/core-backend/src/main/java/io/dataease/chart/server/ChartDataServer.java index 4e99e031e6..bc65280bcc 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/server/ChartDataServer.java +++ b/core/core-backend/src/main/java/io/dataease/chart/server/ChartDataServer.java @@ -4,6 +4,7 @@ import io.dataease.api.chart.ChartDataApi; import io.dataease.api.chart.dto.ChartViewDTO; import io.dataease.api.chart.dto.ViewDetailField; import io.dataease.api.chart.request.ChartExcelRequest; +import io.dataease.chart.constant.ChartConstants; import io.dataease.chart.manage.ChartDataManage; import io.dataease.constant.AuthConstant; import io.dataease.constant.CommonConstants; @@ -69,7 +70,12 @@ public class ChartDataServer implements ChartDataApi { try { ChartViewDTO viewDTO = request.getViewInfo(); viewDTO.setIsExcelExport(true); - viewDTO.setResultCount(limit); + if(ChartConstants.VIEW_RESULT_MODE.CUSTOM.equals(viewDTO.getResultMode())){ + Integer limitCount = viewDTO.getResultCount(); + viewDTO.setResultCount(limitCount>limit?limit:limitCount); + }else{ + viewDTO.setResultCount(limit); + } ChartViewDTO chartViewInfo = getData(viewDTO); List tableRow = (List) chartViewInfo.getData().get("sourceData"); request.setDetails(tableRow); diff --git a/core/core-backend/src/main/java/io/dataease/chart/server/ChartViewServer.java b/core/core-backend/src/main/java/io/dataease/chart/server/ChartViewServer.java index d4c3213266..5da0abd39d 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/server/ChartViewServer.java +++ b/core/core-backend/src/main/java/io/dataease/chart/server/ChartViewServer.java @@ -57,4 +57,14 @@ public class ChartViewServer implements ChartViewApi { public List viewOption(Long resourceId) { return chartViewManege.viewOption(resourceId); } + + @Override + public void copyField(Long id, Long chartId) { + chartViewManege.copyField(id, chartId); + } + + @Override + public void deleteField(Long id) { + chartViewManege.deleteField(id); + } } diff --git a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java index d70a50a101..68924c114e 100644 --- a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java +++ b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java @@ -1,7 +1,6 @@ package io.dataease.dataset.manage; import io.dataease.api.chart.dto.ChartExtFilterDTO; -import io.dataease.api.chart.dto.ChartViewDTO; import io.dataease.api.chart.dto.ColumnPermissionItem; import io.dataease.api.chart.dto.DeSortField; import io.dataease.api.chart.request.ChartExtRequest; @@ -204,7 +203,7 @@ public class DatasetDataManage { Table2SQLObj.table2sqlobj(sqlMeta, null, "(" + sql + ")", crossDs); Field2SQLObj.field2sqlObj(sqlMeta, fields, fields, crossDs, dsMap); WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, fields, crossDs, dsMap); - Order2SQLObj.getOrders(sqlMeta, fields, datasetGroupInfoDTO.getSortFields(), crossDs, dsMap); + Order2SQLObj.getOrders(sqlMeta, datasetGroupInfoDTO.getSortFields(), fields, crossDs, dsMap); String querySQL; if (start == null || count == null) { querySQL = SQLProvider.createQuerySQL(sqlMeta, false, needOrder, false); @@ -425,13 +424,9 @@ public class DatasetDataManage { } List allFields = new ArrayList<>(); // 根据图表计算字段,获取数据集 - Long datasetGroupId; - if (field.getDatasetGroupId() == null && field.getChartId() != null) { - ChartViewDTO chart = chartViewManege.getChart(field.getChartId()); - datasetGroupId = chart.getTableId(); + Long datasetGroupId = field.getDatasetGroupId(); + if (field.getChartId() != null) { allFields.addAll(datasetTableFieldManage.getChartCalcFields(field.getChartId())); - } else { - datasetGroupId = field.getDatasetGroupId(); } DatasetGroupInfoDTO datasetGroupInfoDTO = datasetGroupManage.get(datasetGroupId, null); @@ -471,9 +466,9 @@ public class DatasetDataManage { rowPermissionsTree = permissionManage.getRowPermissionsTree(datasetGroupInfoDTO.getId(), user.getUserId()); } - Field2SQLObj.field2sqlObj(sqlMeta, fields, datasetGroupInfoDTO.getAllFields(), crossDs, dsMap); - WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, fields, crossDs, dsMap); - Order2SQLObj.getOrders(sqlMeta, fields, datasetGroupInfoDTO.getSortFields(), crossDs, dsMap); + Field2SQLObj.field2sqlObj(sqlMeta, fields, allFields, crossDs, dsMap); + WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, allFields, crossDs, dsMap); + Order2SQLObj.getOrders(sqlMeta, datasetGroupInfoDTO.getSortFields(), allFields, crossDs, dsMap); String querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, true, 0, 1000); querySQL = SqlUtils.rebuildSQL(querySQL, sqlMeta, crossDs, dsMap); logger.info("calcite data enum sql: " + querySQL); @@ -539,20 +534,18 @@ public class DatasetDataManage { } } + List allFields = new ArrayList<>(); + for (Long id : ids) { DatasetTableFieldDTO field = datasetTableFieldManage.selectById(id); if (field == null) { DEException.throwException(Translator.get("i18n_no_field")); } - List allFields = new ArrayList<>(); + // 根据图表计算字段,获取数据集 - Long datasetGroupId; - if (field.getDatasetGroupId() == null && field.getChartId() != null) { - ChartViewDTO chart = chartViewManege.getChart(field.getChartId()); - datasetGroupId = chart.getTableId(); + Long datasetGroupId = field.getDatasetGroupId(); + if (field.getChartId() != null) { allFields.addAll(datasetTableFieldManage.getChartCalcFields(field.getChartId())); - } else { - datasetGroupId = field.getDatasetGroupId(); } datasetGroupInfoDTO = datasetGroupManage.get(datasetGroupId, null); @@ -687,10 +680,10 @@ public class DatasetDataManage { sortDistinct = false; } - Field2SQLObj.field2sqlObj(sqlMeta, fields, datasetGroupInfoDTO.getAllFields(), crossDs, dsMap); - ExtWhere2Str.extWhere2sqlOjb(sqlMeta, extFilterList, datasetGroupInfoDTO.getAllFields(), crossDs, dsMap); - WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, fields, crossDs, dsMap); - Order2SQLObj.getOrders(sqlMeta, fields, datasetGroupInfoDTO.getSortFields(), crossDs, dsMap); + Field2SQLObj.field2sqlObj(sqlMeta, fields, allFields, crossDs, dsMap); + ExtWhere2Str.extWhere2sqlOjb(sqlMeta, extFilterList, allFields, crossDs, dsMap); + WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, allFields, crossDs, dsMap); + Order2SQLObj.getOrders(sqlMeta, datasetGroupInfoDTO.getSortFields(), allFields, crossDs, dsMap); String querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, sortDistinct && ids.size() == 1, 0, 1000); querySQL = SqlUtils.rebuildSQL(querySQL, sqlMeta, crossDs, dsMap); logger.info("calcite data enum sql: " + querySQL); diff --git a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetGroupManage.java b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetGroupManage.java index 75a63d969e..daecbe6449 100644 --- a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetGroupManage.java +++ b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetGroupManage.java @@ -371,6 +371,10 @@ public class DatasetGroupManage { return dto; } + public DatasetGroupInfoDTO getDatasetGroupInfoDTO(Long id, String type) throws Exception { + return get(id, type); + } + public DatasetGroupInfoDTO get(Long id, String type) throws Exception { CoreDatasetGroup coreDatasetGroup = coreDatasetGroupMapper.selectById(id); if (coreDatasetGroup == null) { diff --git a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetTableFieldManage.java b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetTableFieldManage.java index 7903adf912..9ae1ba7faa 100644 --- a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetTableFieldManage.java +++ b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetTableFieldManage.java @@ -156,6 +156,7 @@ public class DatasetTableFieldManage { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("dataset_group_id", id); wrapper.eq("checked", true); + wrapper.isNull("chart_id"); return transDTO(coreDatasetTableFieldMapper.selectList(wrapper)); } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java b/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java index 980c4b75c9..947ec1c0cd 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java @@ -117,9 +117,9 @@ public class CalciteProvider { tableDesc.setDatasourceId(datasourceRequest.getDatasource().getId()); tableDesc.setType("db"); tableDesc.setTableName(resultSet.getString(1)); - if(resultSet.getMetaData().getColumnCount() > 1){ + if (resultSet.getMetaData().getColumnCount() > 1) { tableDesc.setName(resultSet.getString(2)); - }else { + } else { tableDesc.setName(resultSet.getString(1)); } return tableDesc; @@ -316,10 +316,104 @@ public class CalciteProvider { return list; } + public void hidePW(DatasourceDTO datasourceDTO) { + DatasourceConfiguration configuration = null; + DatasourceType datasourceType = DatasourceType.valueOf(datasourceDTO.getType()); + switch (datasourceType) { + case mysql: + case mongo: + case mariadb: + case TiDB: + case StarRocks: + case doris: + configuration = JsonUtil.parseObject(datasourceDTO.getConfiguration(), Mysql.class); + if (StringUtils.isNotEmpty(configuration.getUrlType()) && configuration.getUrlType().equalsIgnoreCase("jdbcUrl")) { + if (configuration.getJdbcUrl().contains("password=")) { + String[] params = configuration.getJdbcUrl().split("\\?")[1].split("&"); + String pd = ""; + for (int i = 0; i < params.length; i++) { + if (params[i].contains("password=")) { + pd = params[i]; + } + } + configuration.setJdbcUrl(configuration.getJdbcUrl().replace(pd, "password=******")); + datasourceDTO.setConfiguration(JsonUtil.toJSONString(configuration).toString()); + } + } + break; + case pg: + configuration = JsonUtil.parseObject(datasourceDTO.getConfiguration(), Pg.class); + if (StringUtils.isNotEmpty(configuration.getUrlType()) && configuration.getUrlType().equalsIgnoreCase("jdbcUrl")) { + if (configuration.getJdbcUrl().contains("password=")) { + String[] params = configuration.getJdbcUrl().split("\\?")[1].split("&"); + String pd = ""; + for (int i = 0; i < params.length; i++) { + if (params[i].contains("password=")) { + pd = params[i]; + } + } + configuration.setJdbcUrl(configuration.getJdbcUrl().replace(pd, "password=******")); + datasourceDTO.setConfiguration(JsonUtil.toJSONString(configuration).toString()); + } + } + break; + case redshift: + configuration = JsonUtil.parseObject(datasourceDTO.getConfiguration(), Redshift.class); + if (StringUtils.isNotEmpty(configuration.getUrlType()) && configuration.getUrlType().equalsIgnoreCase("jdbcUrl")) { + if (configuration.getJdbcUrl().contains("password=")) { + String[] params = configuration.getJdbcUrl().split("\\?")[1].split("&"); + String pd = ""; + for (int i = 0; i < params.length; i++) { + if (params[i].contains("password=")) { + pd = params[i]; + } + } + configuration.setJdbcUrl(configuration.getJdbcUrl().replace(pd, "password=******")); + datasourceDTO.setConfiguration(JsonUtil.toJSONString(configuration).toString()); + } + } + break; + case ck: + configuration = JsonUtil.parseObject(datasourceDTO.getConfiguration(), CK.class); + if (StringUtils.isNotEmpty(configuration.getUrlType()) && configuration.getUrlType().equalsIgnoreCase("jdbcUrl")) { + if (configuration.getJdbcUrl().contains("password=")) { + String[] params = configuration.getJdbcUrl().split("\\?")[1].split("&"); + String pd = ""; + for (int i = 0; i < params.length; i++) { + if (params[i].contains("password=")) { + pd = params[i]; + } + } + configuration.setJdbcUrl(configuration.getJdbcUrl().replace(pd, "password=******")); + datasourceDTO.setConfiguration(JsonUtil.toJSONString(configuration).toString()); + } + } + break; + case impala: + configuration = JsonUtil.parseObject(datasourceDTO.getConfiguration(), Impala.class); + if (StringUtils.isNotEmpty(configuration.getUrlType()) && configuration.getUrlType().equalsIgnoreCase("jdbcUrl")) { + if (configuration.getJdbcUrl().contains("password=")) { + String[] params = configuration.getJdbcUrl().split(";")[1].split("&"); + String pd = ""; + for (int i = 0; i < params.length; i++) { + if (params[i].contains("password=")) { + pd = params[i]; + } + } + configuration.setJdbcUrl(configuration.getJdbcUrl().replace(pd, "password=******")); + datasourceDTO.setConfiguration(JsonUtil.toJSONString(configuration).toString()); + } + } + break; + default: + break; + } + } + private String getTableFiledSql(DatasourceRequest datasourceRequest) { String sql = ""; DatasourceConfiguration configuration = null; - String database=""; + String database = ""; DatasourceType datasourceType = DatasourceType.valueOf(datasourceRequest.getDatasource().getType()); switch (datasourceType) { case mysql: @@ -440,7 +534,8 @@ public class CalciteProvider { return sql; } - private TableField getTableFieldDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws SQLException { + private TableField getTableFieldDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws + SQLException { TableField tableField = new TableField(); tableField.setOriginName(resultSet.getString(1)); tableField.setType(resultSet.getString(2).toUpperCase()); @@ -809,7 +904,7 @@ public class CalciteProvider { " AND ep.class = 1 \n" + " AND ep.name = 'MS_Description'\n" + "where sc.name ='DS_SCHEMA'" - .replace("DS_SCHEMA", configuration.getSchema())); + .replace("DS_SCHEMA", configuration.getSchema())); tableSqls.add("SELECT \n" + " t.name AS TableName, \n" + " ep.value AS TableDescription \n" + diff --git a/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java b/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java index bd37f22672..bbc252b61e 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java @@ -488,12 +488,20 @@ public class DatasourceServer implements DatasourceApi { return calciteProvider.getSchema(datasourceRequest); } + @Override + public DatasourceDTO hidePw(Long datasourceId) throws DEException { + return getDatasourceDTOById(datasourceId, true); + } @Override public DatasourceDTO get(Long datasourceId) throws DEException { + return getDatasourceDTOById(datasourceId, false); + } + + private DatasourceDTO getDatasourceDTOById(Long datasourceId, boolean hidePw) throws DEException { DatasourceDTO datasourceDTO = new DatasourceDTO(); CoreDatasource datasource = datasourceMapper.selectById(datasourceId); - if(datasource == null){ + if (datasource == null) { DEException.throwException("不存在的数据源!"); } BeanUtils.copyBean(datasourceDTO, datasource); @@ -547,15 +555,18 @@ public class DatasourceServer implements DatasourceApi { if (task != null) { datasourceDTO.setLastSyncTime(task.getStartTime()); } + } else { + if (hidePw) { + calciteProvider.hidePW(datasourceDTO); + } + } if (datasourceDTO.getType().equalsIgnoreCase(DatasourceConfiguration.DatasourceType.Excel.toString())) { datasourceDTO.setFileName(ExcelUtils.getFileName(datasource)); datasourceDTO.setSize(ExcelUtils.getSize(datasource)); } datasourceDTO.setConfiguration(new String(Base64.getEncoder().encode(datasourceDTO.getConfiguration().getBytes()))); - datasourceDTO.setCreator(coreUserManage.getUserName(Long.valueOf(datasourceDTO.getCreateBy()))); - return datasourceDTO; } @@ -750,7 +761,7 @@ public class DatasourceServer implements DatasourceApi { datasourceRequest.setDsList(Map.of(datasourceSchemaDTO.getId(), datasourceSchemaDTO)); datasourceRequest.setQuery(TableUtils.tableName2Sql(datasourceSchemaDTO, tableName) + " LIMIT 0 OFFSET 0"); datasourceRequest.setTable(tableName); - List tableFields = (List) calciteProvider.fetchTableField(datasourceRequest) ; + List tableFields = (List) calciteProvider.fetchTableField(datasourceRequest); return tableFields.stream().filter(tableField -> { return !tableField.getOriginName().equalsIgnoreCase("dataease_uuid"); }).collect(Collectors.toList()); diff --git a/core/core-backend/src/main/java/io/dataease/engine/trans/Order2SQLObj.java b/core/core-backend/src/main/java/io/dataease/engine/trans/Order2SQLObj.java index 5798d270be..54d6d4ab23 100644 --- a/core/core-backend/src/main/java/io/dataease/engine/trans/Order2SQLObj.java +++ b/core/core-backend/src/main/java/io/dataease/engine/trans/Order2SQLObj.java @@ -22,17 +22,17 @@ import java.util.Objects; */ public class Order2SQLObj { - public static void getOrders(SQLMeta meta, List fields, List sortFields, boolean isCross, Map dsMap) { + public static void getOrders(SQLMeta meta, List sortFields, List originFields, boolean isCross, Map dsMap) { SQLObj tableObj = meta.getTable(); List xOrders = meta.getXOrders() == null ? new ArrayList<>() : meta.getXOrders(); if (ObjectUtils.isEmpty(tableObj)) { return; } if (ObjectUtils.isNotEmpty(sortFields)) { - int step = fields.size(); + int step = originFields.size(); for (int i = step; i < (step + sortFields.size()); i++) { DeSortField deSortField = sortFields.get(i - step); - SQLObj order = buildSortField(deSortField, tableObj, i, fields, isCross, dsMap); + SQLObj order = buildSortField(deSortField, tableObj, i, originFields, isCross, dsMap); xOrders.add(order); } meta.setXOrders(xOrders); diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java b/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java index 744f79da9e..26a8587f20 100644 --- a/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java +++ b/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java @@ -12,6 +12,7 @@ import io.dataease.engine.constant.DeTypeConstants; import io.dataease.exception.DEException; import io.dataease.exportCenter.dao.auto.entity.CoreExportTask; import io.dataease.exportCenter.dao.auto.mapper.CoreExportTaskMapper; +import io.dataease.system.manage.SysParameterManage; import io.dataease.utils.*; import io.dataease.visualization.server.DataVisualizationServer; import io.dataease.websocket.WsMessage; @@ -50,6 +51,8 @@ public class ExportCenterManage { private CoreChartViewMapper coreChartViewMapper; @Autowired private WsService wsService; + @Resource + private SysParameterManage sysParameterManage; @Value("${export.dataset.limit:100000}") private int limit; @@ -183,12 +186,21 @@ public class ExportCenterManage { if (status.equalsIgnoreCase(exportTaskDTO.getExportStatus())) { setExportFromAbsName(exportTaskDTO); } + if (status.equalsIgnoreCase(exportTaskDTO.getExportStatus())) { + setOrgName(exportTaskDTO); + } result.add(exportTaskDTO); }); return result; } + private void setOrgName(ExportTaskDTO exportTaskDTO) { + if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) { + exportTaskDTO.setOrgName(dataVisualizationServer.getAbsPath(exportTaskDTO.getExportFrom())); + } + } + private void setExportFromAbsName(ExportTaskDTO exportTaskDTO) { if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) { exportTaskDTO.setExportFromName(dataVisualizationServer.getAbsPath(exportTaskDTO.getExportFrom())); @@ -408,6 +420,21 @@ public class ExportCenterManage { private static final String LOG_RETENTION = "30"; + public void cleanLog() { + String key = "basic.exportFileLiveTime"; + String val = sysParameterManage.singleVal(key); + if (StringUtils.isBlank(val)) { + DEException.throwException("未获取到文件保留时间"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + long expTime = Long.parseLong(val) * 24L * 3600L * 1000L; + long threshold = System.currentTimeMillis() - expTime; + queryWrapper.lt("export_time", threshold); + exportTaskMapper.selectList(queryWrapper).forEach(coreExportTask -> { + delete(coreExportTask.getId()); + }); + + } } diff --git a/core/core-backend/src/main/java/io/dataease/job/schedule/CheckDsStatusJob.java b/core/core-backend/src/main/java/io/dataease/job/schedule/CheckDsStatusJob.java index 54cbd97a2e..cf3c0e087b 100644 --- a/core/core-backend/src/main/java/io/dataease/job/schedule/CheckDsStatusJob.java +++ b/core/core-backend/src/main/java/io/dataease/job/schedule/CheckDsStatusJob.java @@ -10,9 +10,9 @@ import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.stereotype.Component; + @Component public class CheckDsStatusJob implements Job { - @Resource private DatasourceServer datasourceServer; diff --git a/core/core-backend/src/main/java/io/dataease/share/manage/XpackShareManage.java b/core/core-backend/src/main/java/io/dataease/share/manage/XpackShareManage.java index 5a0584d040..5a809c11a7 100644 --- a/core/core-backend/src/main/java/io/dataease/share/manage/XpackShareManage.java +++ b/core/core-backend/src/main/java/io/dataease/share/manage/XpackShareManage.java @@ -14,12 +14,13 @@ import io.dataease.constant.AuthConstant; import io.dataease.constant.BusiResourceEnum; import io.dataease.exception.DEException; import io.dataease.license.config.XpackInteract; -import io.dataease.share.dao.auto.mapper.XpackShareMapper; -import io.dataease.utils.*; +import io.dataease.license.utils.LicenseUtil; import io.dataease.share.dao.auto.entity.XpackShare; +import io.dataease.share.dao.auto.mapper.XpackShareMapper; import io.dataease.share.dao.ext.mapper.XpackShareExtMapper; import io.dataease.share.dao.ext.po.XpackSharePO; import io.dataease.share.util.LinkTokenUtil; +import io.dataease.utils.*; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.collections4.CollectionUtils; @@ -125,7 +126,6 @@ public class XpackShareManage { } - public IPage querySharePage(int goPage, int pageSize, VisualizationWorkbranchQueryRequest request) { Long uid = AuthUtils.getUser().getUserId(); QueryWrapper queryWrapper = new QueryWrapper<>(); @@ -174,7 +174,7 @@ public class XpackShareManage { return pos.stream().map(po -> new XpackShareGridVO( po.getShareId(), po.getResourceId(), po.getName(), po.getCreator().toString(), - po.getTime(), po.getExp(), 9,po.getExtFlag(),po.getType())).toList(); + po.getTime(), po.getExp(), 9, po.getExtFlag(), po.getType())).toList(); } private XpackShareManage proxy() { @@ -182,6 +182,10 @@ public class XpackShareManage { } public XpackShareProxyVO proxyInfo(XpackShareProxyRequest request) { + boolean inIframeError = request.isInIframe() && !LicenseUtil.licenseValid(); + if (inIframeError) { + return new XpackShareProxyVO(); + } QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("uuid", request.getUuid()); XpackShare xpackShare = xpackShareMapper.selectOne(queryWrapper); @@ -192,7 +196,7 @@ public class XpackShareManage { response.addHeader(AuthConstant.LINK_TOKEN_KEY, linkToken); Integer type = xpackShare.getType(); String typeText = (ObjectUtils.isNotEmpty(type) && type == 1) ? "dashboard" : "dataV"; - return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText); + return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText, inIframeError); } private boolean linkExp(XpackShare xpackShare) { diff --git a/core/core-backend/src/main/java/io/dataease/websocket/factory/DeWebSocketHandlerDecorator.java b/core/core-backend/src/main/java/io/dataease/websocket/factory/DeWebSocketHandlerDecorator.java index bb3f8f4f4d..68526a6256 100644 --- a/core/core-backend/src/main/java/io/dataease/websocket/factory/DeWebSocketHandlerDecorator.java +++ b/core/core-backend/src/main/java/io/dataease/websocket/factory/DeWebSocketHandlerDecorator.java @@ -20,8 +20,10 @@ public class DeWebSocketHandlerDecorator extends WebSocketHandlerDecorator { public void afterConnectionEstablished(WebSocketSession session) throws Exception { Optional.ofNullable(session.getPrincipal()).ifPresent(principal -> { String name = principal.getName(); - Long userId = Long.parseLong(name); - WsUtil.onLine(userId); + if(name != null){ + Long userId = Long.parseLong(name); + WsUtil.onLine(userId); + } }); super.afterConnectionEstablished(session); } @@ -30,8 +32,10 @@ public class DeWebSocketHandlerDecorator extends WebSocketHandlerDecorator { public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { Optional.ofNullable(session.getPrincipal()).ifPresent(principal -> { String name = principal.getName(); - Long userId = Long.parseLong(name); - WsUtil.offLine(userId); + if(name != null){ + Long userId = Long.parseLong(name); + WsUtil.offLine(userId); + } }); super.afterConnectionClosed(session, closeStatus); diff --git a/core/core-backend/src/main/resources/db/desktop/V2.7__ddl.sql b/core/core-backend/src/main/resources/db/desktop/V2.7__ddl.sql index 81f0a52efc..6de7b516c6 100644 --- a/core/core-backend/src/main/resources/db/desktop/V2.7__ddl.sql +++ b/core/core-backend/src/main/resources/db/desktop/V2.7__ddl.sql @@ -13,3 +13,24 @@ CREATE TABLE `core_sys_startup_job` BEGIN; INSERT INTO `core_sys_startup_job` VALUES ('chartFilterMerge', 'chartFilterMerge', 'ready'); COMMIT; + + +DROP TABLE IF EXISTS `core_export_task`; +CREATE TABLE `core_export_task` +( + `id` VARCHAR(255) NOT NULL, + `user_id` BIGINT(20) NOT NULL, + `file_name` VARCHAR(2048) DEFAULT NULL, + `file_size` DOUBLE DEFAULT NULL, + `file_size_unit` VARCHAR(255) DEFAULT NULL, + `export_from` VARCHAR(255) DEFAULT NULL, + `export_status` VARCHAR(255) DEFAULT NULL, + `export_from_type` VARCHAR(255) DEFAULT NULL, + `export_time` BIGINT(20) DEFAULT NULL, + `export_progress` VARCHAR(255) DEFAULT NULL, + `export_machine_name` VARCHAR(512) DEFAULT NULL, + `params` longtext NOT NULL COMMENT '过滤参数', + PRIMARY KEY (`id`) +) COMMENT='导出任务表'; + +UPDATE `QRTZ_JOB_DETAILS` SET `JOB_CLASS_NAME` = 'io.dataease.job.schedule.CheckDsStatusJob' WHERE (`SCHED_NAME` = 'deSyncJob') and (`JOB_NAME` = 'Datasource') and (`JOB_GROUP` = 'check_status'); diff --git a/core/core-backend/src/main/resources/db/migration/V2.7__ddl.sql b/core/core-backend/src/main/resources/db/migration/V2.7__ddl.sql index 6b9223fe5e..ecd9e924ff 100644 --- a/core/core-backend/src/main/resources/db/migration/V2.7__ddl.sql +++ b/core/core-backend/src/main/resources/db/migration/V2.7__ddl.sql @@ -52,3 +52,6 @@ CREATE TABLE `xpack_platform_token` PRIMARY KEY (`id`) ); + + +UPDATE `QRTZ_JOB_DETAILS` SET `JOB_CLASS_NAME` = 'io.dataease.job.schedule.CheckDsStatusJob' WHERE (`SCHED_NAME` = 'deSyncJob') and (`JOB_NAME` = 'Datasource') and (`JOB_GROUP` = 'check_status'); diff --git a/core/core-frontend/package.json b/core/core-frontend/package.json index 08d27de69c..82d27937e7 100644 --- a/core/core-frontend/package.json +++ b/core/core-frontend/package.json @@ -20,6 +20,7 @@ "@codemirror/lang-sql": "^6.4.0", "@npkg/tinymce-plugins": "^0.0.7", "@tinymce/tinymce-vue": "^5.1.0", + "@videojs-player/vue": "^1.0.0", "@vueuse/core": "^9.13.0", "ace-builds": "^1.15.3", "axios": "^1.3.3", @@ -46,6 +47,7 @@ "snowflake-id": "^1.1.0", "tinymce": "^5.8.2", "vant": "^4.8.3", + "video.js": "^7.21.6", "vue": "^3.3.4", "vue-clipboard3": "^2.0.0", "vue-codemirror": "^6.1.1", @@ -54,7 +56,6 @@ "vue-types": "^5.0.2", "vue-uuid": "^3.0.0", "vue3-ace-editor": "^2.2.2", - "vue3-video-play": "^1.3.2", "vuedraggable": "^4.1.0", "web-storage-cache": "^1.1.1", "xss": "^1.0.14" diff --git a/core/core-frontend/src/api/datasource.ts b/core/core-frontend/src/api/datasource.ts index ef14354ba6..93f8186344 100644 --- a/core/core-frontend/src/api/datasource.ts +++ b/core/core-frontend/src/api/datasource.ts @@ -147,6 +147,8 @@ export const deleteById = (id: number) => request.get({ url: '/datasource/delete export const getById = (id: number) => request.get({ url: '/datasource/get/' + id }) +export const getHidePwById = (id: number) => request.get({ url: '/datasource/hidePw/' + id }) + export const uploadFile = async (data): Promise => { return request .post({ diff --git a/core/core-frontend/src/assets/svg/bar-range-origin.svg b/core/core-frontend/src/assets/svg/bar-range-origin.svg new file mode 100644 index 0000000000..26ef1d75e9 --- /dev/null +++ b/core/core-frontend/src/assets/svg/bar-range-origin.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/core/core-frontend/src/assets/svg/bidirectional-bar-origin.svg b/core/core-frontend/src/assets/svg/bidirectional-bar-origin.svg new file mode 100644 index 0000000000..122c82ea47 --- /dev/null +++ b/core/core-frontend/src/assets/svg/bidirectional-bar-origin.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/icon_search.svg b/core/core-frontend/src/assets/svg/icon_search.svg new file mode 100644 index 0000000000..fa50c16739 --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/core/core-frontend/src/assets/svg/progress-bar-origin.svg b/core/core-frontend/src/assets/svg/progress-bar-origin.svg new file mode 100644 index 0000000000..7b6131949b --- /dev/null +++ b/core/core-frontend/src/assets/svg/progress-bar-origin.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/quadrant-origin.svg b/core/core-frontend/src/assets/svg/quadrant-origin.svg new file mode 100644 index 0000000000..b79493cba8 --- /dev/null +++ b/core/core-frontend/src/assets/svg/quadrant-origin.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/core/core-frontend/src/components/data-visualization/DvToolbar.vue b/core/core-frontend/src/components/data-visualization/DvToolbar.vue index 40dceb75cb..ee8b0a78f0 100644 --- a/core/core-frontend/src/components/data-visualization/DvToolbar.vue +++ b/core/core-frontend/src/components/data-visualization/DvToolbar.vue @@ -93,10 +93,13 @@ const saveCanvasWithCheck = () => { const saveResource = () => { wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id) if (styleChangeTimes.value > 0) { - snapshotStore.resetStyleChangeTimes() - canvasSave(() => { - ElMessage.success('保存成功') - window.history.pushState({}, '', `#/dvCanvas?dvId=${dvInfo.value.id}`) + eventBus.emit('hideArea-canvas-main') + nextTick(() => { + snapshotStore.resetStyleChangeTimes() + canvasSave(() => { + ElMessage.success('保存成功') + window.history.pushState({}, '', `#/dvCanvas?dvId=${dvInfo.value.id}`) + }) }) } } diff --git a/core/core-frontend/src/components/data-visualization/RealTimeComponentList.vue b/core/core-frontend/src/components/data-visualization/RealTimeComponentList.vue deleted file mode 100644 index 54b85c0df7..0000000000 --- a/core/core-frontend/src/components/data-visualization/RealTimeComponentList.vue +++ /dev/null @@ -1,473 +0,0 @@ - - - - - - - diff --git a/core/core-frontend/src/components/data-visualization/canvas/CanvasCore.vue b/core/core-frontend/src/components/data-visualization/canvas/CanvasCore.vue index 7d48537771..800f5a30c1 100644 --- a/core/core-frontend/src/components/data-visualization/canvas/CanvasCore.vue +++ b/core/core-frontend/src/components/data-visualization/canvas/CanvasCore.vue @@ -1380,6 +1380,11 @@ const groupAreaClickChange = async () => { groupAreaCom.style.top = areaData.value.style.top groupAreaCom.style.width = areaData.value.style.width groupAreaCom.style.height = areaData.value.style.height + dvMainStore.setClickComponentStatus(true) + dvMainStore.setCurComponent({ + component: groupAreaCom, + index: dvMainStore.componentData.length - 1 + }) } else if (groupAreaCom) { groupAreaHis.forEach(ele => { dvMainStore.deleteComponentById(ele.id) diff --git a/core/core-frontend/src/components/data-visualization/canvas/ComposeShow.vue b/core/core-frontend/src/components/data-visualization/canvas/ComposeShow.vue index 2004f9f1e1..0b1041a12e 100644 --- a/core/core-frontend/src/components/data-visualization/canvas/ComposeShow.vue +++ b/core/core-frontend/src/components/data-visualization/canvas/ComposeShow.vue @@ -37,7 +37,7 @@ const handleMouseDown = e => { return } const index = areaData.value.components.findIndex(component => component === props.element) - if (index != -1) { + if (index != -1 && props.element.component !== 'GroupArea') { areaData.value.components.splice(index, 1) e.stopPropagation() } diff --git a/core/core-frontend/src/components/data-visualization/canvas/Shape.vue b/core/core-frontend/src/components/data-visualization/canvas/Shape.vue index a8559c8291..b34d2bc013 100644 --- a/core/core-frontend/src/components/data-visualization/canvas/Shape.vue +++ b/core/core-frontend/src/components/data-visualization/canvas/Shape.vue @@ -424,7 +424,6 @@ const handleInnerMouseDownOnShape = e => { if (curComponent.value && curComponent.value.id !== element.value.id) { areaDataPush(curComponent.value) } - dvMainStore.setCurComponent({ component: null, index: null }) e.stopPropagation() return } diff --git a/core/core-frontend/src/components/plugin/src/index.vue b/core/core-frontend/src/components/plugin/src/index.vue index 6197cca108..147e71cbd5 100644 --- a/core/core-frontend/src/components/plugin/src/index.vue +++ b/core/core-frontend/src/components/plugin/src/index.vue @@ -8,7 +8,6 @@ import { i18n } from '@/plugins/vue-i18n' import * as Vue from 'vue' import axios from 'axios' import * as Pinia from 'pinia' -import * as vueI18n from 'vue-i18n' import * as vueRouter from 'vue-router' import { useEmitt } from '@/hooks/web/useEmitt' @@ -82,7 +81,11 @@ const storeCacheProxy = byteArray => { } const pluginProxy = ref(null) const invokeMethod = param => { - pluginProxy.value['invokeMethod'](param) + if (pluginProxy.value['invokeMethod']) { + pluginProxy.value['invokeMethod'](param) + } else { + pluginProxy.value[param.methodName](param.args) + } } onMounted(async () => { @@ -96,17 +99,16 @@ onMounted(async () => { distributed = wsCache.get(key) } if (distributed) { - window['Vue'] = Vue - window['Axios'] = axios - window['Pinia'] = Pinia - window['vueI18n'] = vueI18n - window['vueRouter'] = vueRouter - window['MittAll'] = useEmitt().emitter.all - window['i18n'] = i18n if (window['DEXPack']) { const xpack = await window['DEXPack'].mapping[attrs.jsname] plugin.value = xpack.default } else { + window['Vue'] = Vue + window['Axios'] = axios + window['Pinia'] = Pinia + window['vueRouter'] = vueRouter + window['MittAll'] = useEmitt().emitter.all + window['I18n'] = i18n loadDistributed().then(async res => { new Function(res.data)() const xpack = await window['DEXPack'].mapping[attrs.jsname] @@ -125,7 +127,13 @@ defineExpose({ diff --git a/core/core-frontend/src/components/visualization/LinkageSet.vue b/core/core-frontend/src/components/visualization/LinkageSet.vue index 580082b7f2..fd11819906 100644 --- a/core/core-frontend/src/components/visualization/LinkageSet.vue +++ b/core/core-frontend/src/components/visualization/LinkageSet.vue @@ -371,14 +371,9 @@ const linkageFieldAdaptor = async data => { if (state.curLinkageViewInfo.tableId === targetChartDetails.tableId) { const curCheckAllAxisStr = JSON.stringify(state.curLinkageViewInfo.xAxis) + - JSON.stringify(state.curLinkageViewInfo.xAxisExt) + - JSON.stringify(state.curLinkageViewInfo.yAxis) + - JSON.stringify(state.curLinkageViewInfo.yAxisExt) + JSON.stringify(state.curLinkageViewInfo.xAxisExt) const targetCheckAllAxisStr = - JSON.stringify(targetChartDetails.xAxis) + - JSON.stringify(targetChartDetails.xAxisExt) + - JSON.stringify(targetChartDetails.yAxis) + - JSON.stringify(targetChartDetails.yAxisExt) + JSON.stringify(targetChartDetails.xAxis) + JSON.stringify(targetChartDetails.xAxisExt) state.sourceLinkageInfo.targetViewFields.forEach(item => { if (curCheckAllAxisStr.includes(item.id) && targetCheckAllAxisStr.includes(item.id)) { addLinkageField(item.id, item.id) @@ -395,9 +390,7 @@ const sourceLinkageInfoFilter = computed(() => { if (state.sourceLinkageInfo.targetViewFields) { const curCheckAllAxisStr = JSON.stringify(state.curLinkageViewInfo.xAxis) + - JSON.stringify(state.curLinkageViewInfo.xAxisExt) + - JSON.stringify(state.curLinkageViewInfo.yAxis) + - JSON.stringify(state.curLinkageViewInfo.yAxisExt) + JSON.stringify(state.curLinkageViewInfo.xAxisExt) return state.sourceLinkageInfo.targetViewFields.filter(item => curCheckAllAxisStr.includes(item.id) ) diff --git a/core/core-frontend/src/components/visualization/UserViewEnlarge.vue b/core/core-frontend/src/components/visualization/UserViewEnlarge.vue index cd549446cd..35797c6ce6 100644 --- a/core/core-frontend/src/components/visualization/UserViewEnlarge.vue +++ b/core/core-frontend/src/components/visualization/UserViewEnlarge.vue @@ -8,7 +8,12 @@ trigger="click" >
- + 导出Excel - +
= { @@ -111,10 +116,15 @@ const DETAIL_TABLE_ATTR: DeepPartial = { tableItemBgColor: '#FFFFFF', tableFontColor: '#7C7E81', enableTableCrossBG: false + }, + tooltip: { + show: false } } } +const authShow = computed(() => editMode.value === 'edit' || dvInfo.value.weight > 3) + const customExport = computed(() => { if (downLoading.value) { const bashStyle = pixel.value.split(' * ') @@ -204,8 +214,8 @@ const downloadViewDetails = () => { exportLoading.value = true exportExcelDownload(chart, () => { openMessageLoading(exportData) - exportLoading.value = false }) + exportLoading.value = false } const exportData = () => { diff --git a/core/core-frontend/src/custom-component/component-list.ts b/core/core-frontend/src/custom-component/component-list.ts index 8b6e3a5e4d..911f774e25 100644 --- a/core/core-frontend/src/custom-component/component-list.ts +++ b/core/core-frontend/src/custom-component/component-list.ts @@ -16,8 +16,8 @@ export const STREAMMEDIALINKS = { isLive: false, cors: true, // 允许跨域 loop: true, - autoplay: false - // url: null // 网络动画视频 + autoplay: false, + url: null // 网络动画视频 } } @@ -26,21 +26,20 @@ export const VIDEO_LINKS_DE2 = { videoType: 'web', poster: null, web: { - width: '100%', //播放器宽度 - height: '100%', //播放器高度 - color: '#409eff', //主题色 - title: '', //视频名称 src: null, //视频源 - muted: false, //静音 - webFullScreen: false, - speedRate: ['0.75', '1.0', '1.25', '1.5', '2.0'], //播放倍速 - autoPlay: true, //自动播放 - loop: false, //循环播放 - mirror: false, //镜像画面 - lightOff: false, //关灯模式 - volume: 0.3, //默认音量大小 - control: true, //是否显示控制 - controlBtns: ['audioTrack', 'quality', 'volume', 'fullScreen'] //显示所有按钮, + autoplay: true, // 如果true,浏览器准备好时开始回放。 + muted: true, // 默认情况下将会消除任何音频。 + loop: true, // 导致视频一结束就重新开始。 + preload: 'auto', // 建议浏览器在