merge: 合并分支
28
.github/workflows/llm-code-review.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: LLM Code Review
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
jobs:
|
||||
llm-code-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: fit2cloud/LLM-CodeReview-Action@main
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FIT2CLOUDRD_LLM_CODE_REVIEW_TOKEN }}
|
||||
OPENAI_API_KEY: ${{ secrets.ALIYUN_LLM_API_KEY }}
|
||||
LANGUAGE: Chinese
|
||||
OPENAI_API_ENDPOINT: https://dashscope.aliyuncs.com/compatible-mode/v1
|
||||
MODEL: qwen2-1.5b-instruct
|
||||
PROMPT: "请检查下面的代码差异是否有不规范、潜在的问题或者优化建议,用中文回答。"
|
||||
top_p: 1
|
||||
temperature: 1
|
||||
# max_tokens: 10000
|
||||
MAX_PATCH_LENGTH: 10000
|
||||
IGNORE_PATTERNS: "/node_modules,*.md,/dist,/.github"
|
||||
FILE_PATTERNS: "*.java,*.go,*.py,*.vue,*.ts,*.js,*.css,*.scss,*.html"
|
||||
@ -14,18 +14,18 @@ public class MybatisPlusGenerator {
|
||||
* 第一 我嫌麻烦
|
||||
* 第二 后面配置会放到nacos读起来更麻烦了
|
||||
*/
|
||||
private static final String url = "jdbc:mysql://localhost:3306/dataease4?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false";
|
||||
private static final String url = "jdbc:mysql://localhost:3306/dataease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false";
|
||||
private static final String username = "root";
|
||||
private static final String password = "123456";
|
||||
|
||||
/**
|
||||
* 业务模块例如datasource,dataset,panel等
|
||||
*/
|
||||
private static final String busi = "visualization";
|
||||
private static final String busi = "chart";
|
||||
/**
|
||||
* 这是要生成代码的表名称
|
||||
*/
|
||||
private static final String TABLE_NAME = "visualization_link_jump_info";
|
||||
private static final String TABLE_NAME = "core_chart_view";
|
||||
|
||||
/**
|
||||
* 下面两个配置基本上不用动
|
||||
|
||||
@ -11,16 +11,20 @@ import io.dataease.engine.sql.SQLProvider;
|
||||
import io.dataease.engine.trans.Dimension2SQLObj;
|
||||
import io.dataease.engine.trans.Quota2SQLObj;
|
||||
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.DatasourceRequest;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.extensions.datasource.model.SQLMeta;
|
||||
import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.extensions.datasource.vo.DatasourceConfiguration;
|
||||
import io.dataease.extensions.datasource.vo.XpackPluginsDatasourceVO;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.extensions.view.plugin.AbstractChartPlugin;
|
||||
import io.dataease.extensions.view.util.ChartDataUtil;
|
||||
import io.dataease.extensions.view.util.FieldUtil;
|
||||
import io.dataease.license.utils.LicenseUtil;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
@ -250,14 +254,159 @@ public class DefaultChartHandler extends AbstractChartPlugin {
|
||||
return res;
|
||||
}
|
||||
|
||||
protected String assistSQL(String sql, List<ChartViewFieldDTO> assistFields) {
|
||||
protected List<ChartViewFieldDTO> getAssistFields(List<ChartSeniorAssistDTO> list, List<ChartViewFieldDTO> yAxis, List<ChartViewFieldDTO> xAxis) {
|
||||
List<ChartViewFieldDTO> res = new ArrayList<>();
|
||||
for (ChartSeniorAssistDTO dto : list) {
|
||||
DatasetTableFieldDTO curField = dto.getCurField();
|
||||
ChartViewFieldDTO field = null;
|
||||
String alias = "";
|
||||
for (int i = 0; i < yAxis.size(); i++) {
|
||||
ChartViewFieldDTO yField = yAxis.get(i);
|
||||
if (Objects.equals(yField.getId(), curField.getId())) {
|
||||
field = yField;
|
||||
alias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ObjectUtils.isEmpty(field) && CollectionUtils.isNotEmpty(xAxis)) {
|
||||
for (int i = 0; i < xAxis.size(); i++) {
|
||||
ChartViewFieldDTO xField = xAxis.get(i);
|
||||
if (StringUtils.equalsIgnoreCase(String.valueOf(xField.getId()), String.valueOf(curField.getId()))) {
|
||||
field = xField;
|
||||
alias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ObjectUtils.isEmpty(field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ChartViewFieldDTO chartViewFieldDTO = new ChartViewFieldDTO();
|
||||
BeanUtils.copyBean(chartViewFieldDTO, curField);
|
||||
chartViewFieldDTO.setSummary(dto.getSummary());
|
||||
chartViewFieldDTO.setOriginName(alias);// yAxis的字段别名,就是查找的字段名
|
||||
res.add(chartViewFieldDTO);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public List<ChartSeniorAssistDTO> getDynamicThresholdFields(ChartViewDTO view) {
|
||||
List<ChartSeniorAssistDTO> list = new ArrayList<>();
|
||||
Map<String, Object> senior = view.getSenior();
|
||||
if (ObjectUtils.isEmpty(senior)) {
|
||||
return list;
|
||||
}
|
||||
ChartSeniorThresholdCfgDTO thresholdCfg = JsonUtil.parseObject((String) JsonUtil.toJSONString(senior.get("threshold")), ChartSeniorThresholdCfgDTO.class);
|
||||
|
||||
if (null == thresholdCfg || !thresholdCfg.isEnable()) {
|
||||
return list;
|
||||
}
|
||||
List<TableThresholdDTO> tableThreshold = thresholdCfg.getTableThreshold();
|
||||
|
||||
if (ObjectUtils.isEmpty(tableThreshold)) {
|
||||
return list;
|
||||
}
|
||||
|
||||
List<ChartSeniorThresholdDTO> conditionsList = tableThreshold.stream()
|
||||
.filter(item -> !ObjectUtils.isEmpty(item))
|
||||
.map(TableThresholdDTO::getConditions)
|
||||
.flatMap(List::stream)
|
||||
.filter(condition -> StringUtils.equalsAnyIgnoreCase(condition.getType(), "dynamic"))
|
||||
.toList();
|
||||
|
||||
List<ChartSeniorAssistDTO> assistDTOs = conditionsList.stream()
|
||||
.flatMap(condition -> getConditionFields(condition).stream())
|
||||
.filter(this::solveThresholdCondition)
|
||||
.toList();
|
||||
|
||||
list.addAll(assistDTOs);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private boolean solveThresholdCondition(ChartSeniorAssistDTO fieldDTO) {
|
||||
Long fieldId = fieldDTO.getFieldId();
|
||||
String summary = fieldDTO.getValue();
|
||||
if (ObjectUtils.isEmpty(fieldId) || StringUtils.isEmpty(summary)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DatasetTableFieldDTO datasetTableFieldDTO = datasetTableFieldManage.selectById(fieldId);
|
||||
if (ObjectUtils.isEmpty(datasetTableFieldDTO)) {
|
||||
return false;
|
||||
}
|
||||
ChartViewFieldDTO datasetTableField = new ChartViewFieldDTO();
|
||||
BeanUtils.copyBean(datasetTableField, datasetTableFieldDTO);
|
||||
fieldDTO.setCurField(datasetTableField);
|
||||
fieldDTO.setSummary(summary);
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<ChartSeniorAssistDTO> getConditionFields(ChartSeniorThresholdDTO condition) {
|
||||
List<ChartSeniorAssistDTO> list = new ArrayList<>();
|
||||
if ("between".equals(condition.getTerm())) {
|
||||
if (!StringUtils.equalsIgnoreCase(condition.getDynamicMaxField().getSummary(), "value")) {
|
||||
list.add(of(condition.getDynamicMaxField()));
|
||||
}
|
||||
if (!StringUtils.equalsIgnoreCase(condition.getDynamicMinField().getSummary(), "value")) {
|
||||
list.add(of(condition.getDynamicMinField()));
|
||||
}
|
||||
} else {
|
||||
if (!StringUtils.equalsIgnoreCase(condition.getDynamicField().getSummary(), "value")) {
|
||||
list.add(of(condition.getDynamicField()));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private ChartSeniorAssistDTO of(ThresholdDynamicFieldDTO dynamicField) {
|
||||
ChartSeniorAssistDTO conditionField = new ChartSeniorAssistDTO();
|
||||
conditionField.setFieldId(Long.parseLong(dynamicField.getFieldId()));
|
||||
conditionField.setValue(dynamicField.getSummary());
|
||||
return conditionField;
|
||||
}
|
||||
|
||||
protected String assistSQL(String sql, List<ChartViewFieldDTO> assistFields, Map<Long, DatasourceSchemaDTO> dsMap) {
|
||||
// get datasource prefix and suffix
|
||||
String dsType = dsMap.entrySet().iterator().next().getValue().getType();
|
||||
String prefix = "";
|
||||
String suffix = "";
|
||||
if (Arrays.stream(DatasourceConfiguration.DatasourceType.values()).map(DatasourceConfiguration.DatasourceType::getType).toList().contains(dsType)) {
|
||||
DatasourceConfiguration.DatasourceType datasourceType = DatasourceConfiguration.DatasourceType.valueOf(dsType);
|
||||
prefix = datasourceType.getPrefix();
|
||||
suffix = datasourceType.getSuffix();
|
||||
} else {
|
||||
if (LicenseUtil.licenseValid()) {
|
||||
List<XpackPluginsDatasourceVO> xpackPluginsDatasourceVOS = pluginManage.queryPluginDs();
|
||||
List<XpackPluginsDatasourceVO> list = xpackPluginsDatasourceVOS.stream().filter(ele -> StringUtils.equals(ele.getType(), dsType)).toList();
|
||||
if (ObjectUtils.isNotEmpty(list)) {
|
||||
XpackPluginsDatasourceVO first = list.getFirst();
|
||||
prefix = first.getPrefix();
|
||||
suffix = first.getSuffix();
|
||||
} else {
|
||||
DEException.throwException("当前数据源插件不存在");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < assistFields.size(); i++) {
|
||||
ChartViewFieldDTO dto = assistFields.get(i);
|
||||
if (i == (assistFields.size() - 1)) {
|
||||
stringBuilder.append(dto.getSummary() + "(" + dto.getOriginName() + ")");
|
||||
if (crossDs) {
|
||||
if (i == (assistFields.size() - 1)) {
|
||||
stringBuilder.append(dto.getSummary() + "(" + dto.getOriginName() + ")");
|
||||
} else {
|
||||
stringBuilder.append(dto.getSummary() + "(" + dto.getOriginName() + "),");
|
||||
}
|
||||
} else {
|
||||
stringBuilder.append(dto.getSummary() + "(" + dto.getOriginName() + "),");
|
||||
if (i == (assistFields.size() - 1)) {
|
||||
stringBuilder.append(dto.getSummary() + "(" + prefix + dto.getOriginName() + suffix + ")");
|
||||
} else {
|
||||
stringBuilder.append(dto.getSummary() + "(" + prefix + dto.getOriginName() + suffix + "),");
|
||||
}
|
||||
}
|
||||
}
|
||||
return "SELECT " + stringBuilder + " FROM (" + sql + ") tmp";
|
||||
@ -464,7 +613,8 @@ public class DefaultChartHandler extends AbstractChartPlugin {
|
||||
if (StringUtils.isNotEmpty(compareCalc.getType())
|
||||
&& !StringUtils.equalsIgnoreCase(compareCalc.getType(), "none")) {
|
||||
if (Arrays.asList(ChartConstants.M_Y).contains(compareCalc.getType())) {
|
||||
if (StringUtils.equalsIgnoreCase(compareCalc.getField() + "", filterDTO.getFieldId()) && filterDTO.getFilterType() == 0) {
|
||||
if (StringUtils.equalsIgnoreCase(compareCalc.getField() + "", filterDTO.getFieldId())
|
||||
&& (filterDTO.getFilterType() == 0 || filterDTO.getFilterType() == 2)) {
|
||||
// -1 year
|
||||
try {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
|
||||
@ -120,11 +120,11 @@ public class YoyChartHandler extends DefaultChartHandler {
|
||||
expandedResult.setQuerySql(originSql);
|
||||
}
|
||||
// 同环比数据排序
|
||||
expandedResult.setOriginData(sortData(view, expandedResult.getOriginData()));
|
||||
expandedResult.setOriginData(sortData(view, expandedResult.getOriginData(),formatResult));
|
||||
return expandedResult;
|
||||
}
|
||||
|
||||
public static List<String[]> sortData(ChartViewDTO view, List<String[]> data) {
|
||||
public static List<String[]> sortData(ChartViewDTO view, List<String[]> data, AxisFormatResult formatResult) {
|
||||
// 维度排序
|
||||
List<ChartViewFieldDTO> xAxisSortList = view.getXAxis().stream().filter(x -> !StringUtils.equalsIgnoreCase("none", x.getSort())).toList();
|
||||
// 指标排序
|
||||
@ -135,11 +135,9 @@ public class YoyChartHandler extends DefaultChartHandler {
|
||||
ChartViewFieldDTO firstYAxis = yAxisSortList.getFirst();
|
||||
boolean asc = firstYAxis.getSort().equalsIgnoreCase("asc");
|
||||
// 维度指标
|
||||
List<ChartViewFieldDTO> allAxisList = Stream.of(
|
||||
view.getXAxis(),
|
||||
view.getXAxisExt(),
|
||||
view.getYAxis()
|
||||
).flatMap(List::stream).toList();
|
||||
List<ChartViewFieldDTO> allAxisList = new ArrayList<>();
|
||||
allAxisList.addAll(formatResult.getAxisMap().get(ChartAxis.xAxis));
|
||||
allAxisList.addAll(formatResult.getAxisMap().get(ChartAxis.yAxis));
|
||||
int index = findIndex(allAxisList, firstYAxis.getId());
|
||||
return sortData(data, asc, index);
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ public class BarHandler extends YoyChartHandler {
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(originSql, assistFields);
|
||||
var assistSql = assistSQL(originSql, assistFields, dsMap);
|
||||
req.setQuery(assistSql);
|
||||
logger.debug("calcite assistSql sql: " + assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
|
||||
@ -52,10 +52,10 @@ public class StackBarHandler extends BarHandler {
|
||||
if (ObjectUtils.isNotEmpty(extStack) &&
|
||||
Objects.equals(drillFields.get(0).getId(), extStack.get(0).getId())) {
|
||||
fieldsToFilter.addAll(view.getXAxis());
|
||||
groupStackDrill(noDrillFieldAxis, noDrillFilterList, fieldsToFilter, drillFields, drillRequestList);
|
||||
formatResult.getAxisMap().put(ChartAxis.xAxis, noDrillFieldAxis);
|
||||
result.setFilterList(noDrillFilterList);
|
||||
}
|
||||
groupStackDrill(noDrillFieldAxis, noDrillFilterList, fieldsToFilter, drillFields, drillRequestList);
|
||||
formatResult.getAxisMap().put(ChartAxis.xAxis, noDrillFieldAxis);
|
||||
result.setFilterList(noDrillFilterList);
|
||||
}
|
||||
return (T) result;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ public class LineHandler extends YoyChartHandler {
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(originSql, assistFields);
|
||||
var assistSql = assistSQL(originSql, assistFields, dsMap);
|
||||
req.setQuery(assistSql);
|
||||
logger.debug("calcite assistSql sql: " + assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
|
||||
@ -100,7 +100,7 @@ public class StackAreaHandler extends YoyChartHandler {
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(originSql, assistFields);
|
||||
var assistSql = assistSQL(originSql, assistFields, dsMap);
|
||||
req.setQuery(assistSql);
|
||||
logger.debug("calcite assist sql: " + assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
|
||||
@ -47,8 +47,7 @@ public class SymbolicMapHandler extends GroupChartHandler {
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var extBubble = formatResult.getAxisMap().get(ChartAxis.extBubble);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
Map<String, Object> result = ChartDataBuild.transSymbolicMapNormalWithDetail(xAxis, yAxis, extBubble, data, detailFields, detailData);
|
||||
return result;
|
||||
return ChartDataBuild.transSymbolicMapNormalWithDetail(view, xAxis, yAxis, extBubble, data, detailFields, detailData);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -92,7 +92,7 @@ public class MixHandler extends YoyChartHandler {
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(originSql, assistFields);
|
||||
var assistSql = assistSQL(originSql, assistFields, dsMap);
|
||||
req.setQuery(assistSql);
|
||||
logger.debug("calcite assistSql sql: " + assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
@ -144,7 +144,7 @@ public class MixHandler extends YoyChartHandler {
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(originSql, assistFields);
|
||||
var assistSql = assistSQL(originSql, assistFields, dsMap);
|
||||
req.setQuery(assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
rightResult.setAssistData(assistData);
|
||||
|
||||
@ -12,8 +12,9 @@ import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.extensions.view.util.ChartDataUtil;
|
||||
import io.dataease.extensions.view.util.FieldUtil;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -21,6 +22,8 @@ import org.springframework.stereotype.Component;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class TableInfoHandler extends DefaultChartHandler {
|
||||
@ -86,7 +89,7 @@ public class TableInfoHandler extends DefaultChartHandler {
|
||||
pageInfo.setPageSize(chartExtRequest.getPageSize());
|
||||
}
|
||||
Dimension2SQLObj.dimension2sqlObj(sqlMeta, xAxis, FieldUtil.transFields(allFields), crossDs, dsMap, Utils.getParams(FieldUtil.transFields(allFields)), view.getCalParams(), pluginManage);
|
||||
if(view.getIsExcelExport()){
|
||||
if (view.getIsExcelExport()) {
|
||||
for (int i = 0; i < xAxis.size(); i++) {
|
||||
ChartViewFieldDTO fieldDTO = null;
|
||||
for (ChartViewFieldDTO allField : allFields) {
|
||||
@ -101,7 +104,7 @@ public class TableInfoHandler extends DefaultChartHandler {
|
||||
}
|
||||
}
|
||||
|
||||
String originSql = SQLProvider.createQuerySQL(sqlMeta, false, true, view);// 明细表强制加排序
|
||||
String originSql = SQLProvider.createQuerySQL(sqlMeta, false, !StringUtils.equalsIgnoreCase(dsMap.entrySet().iterator().next().getValue().getType(), "es"), view);// 明细表强制加排序
|
||||
String limit = ((pageInfo.getGoPage() != null && pageInfo.getPageSize() != null) ? " LIMIT " + pageInfo.getPageSize() + " OFFSET " + (pageInfo.getGoPage() - 1) * chartExtRequest.getPageSize() : "");
|
||||
var querySql = originSql + limit;
|
||||
|
||||
@ -135,6 +138,32 @@ public class TableInfoHandler extends DefaultChartHandler {
|
||||
calcResult.setContext(filterResult.getContext());
|
||||
calcResult.setQuerySql(querySql);
|
||||
calcResult.setOriginData(data);
|
||||
try {
|
||||
var dynamicAssistFields = getDynamicThresholdFields(view);
|
||||
Set<Long> fieldIds = xAxis.stream().map(ChartViewFieldDTO::getId).collect(Collectors.toSet());
|
||||
List<ChartViewFieldDTO> finalXAxis = xAxis;
|
||||
dynamicAssistFields.forEach(i -> {
|
||||
if (!fieldIds.contains(i.getFieldId())) {
|
||||
ChartViewFieldDTO fieldDTO = new ChartViewFieldDTO();
|
||||
BeanUtils.copyBean(fieldDTO, i.getCurField());
|
||||
finalXAxis.add(fieldDTO);
|
||||
}
|
||||
});
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var assistFields = getAssistFields(dynamicAssistFields, yAxis, xAxis);
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(querySql, assistFields, dsMap);
|
||||
req.setQuery(assistSql);
|
||||
logger.debug("calcite assistSql sql: " + assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
calcResult.setAssistData(assistData);
|
||||
calcResult.setDynamicAssistFields(dynamicAssistFields);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return calcResult;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,18 @@
|
||||
package io.dataease.chart.charts.impl.table;
|
||||
|
||||
import io.dataease.chart.charts.impl.YoyChartHandler;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceRequest;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.extensions.datasource.model.SQLMeta;
|
||||
import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author jianneng
|
||||
* @date 2024/9/11 11:37
|
||||
@ -12,4 +21,29 @@ import org.springframework.stereotype.Component;
|
||||
public class TableNormalHandler extends YoyChartHandler {
|
||||
@Getter
|
||||
private String type = "table-normal";
|
||||
|
||||
@Override
|
||||
public <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, Provider provider) {
|
||||
var dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
var result = (T) super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider);
|
||||
try {
|
||||
var originSql = result.getQuerySql();
|
||||
var dynamicAssistFields = getDynamicThresholdFields(view);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var assistFields = getAssistFields(dynamicAssistFields, yAxis);
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(originSql, assistFields, dsMap);
|
||||
req.setQuery(assistSql);
|
||||
logger.debug("calcite assistSql sql: " + assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
result.setAssistData(assistData);
|
||||
result.setDynamicAssistFields(dynamicAssistFields);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.IDUtils;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import reactor.util.function.Tuple2;
|
||||
@ -32,9 +33,28 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
|
||||
@Override
|
||||
public <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, Provider provider) {
|
||||
T result = super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider);
|
||||
T result = super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider);
|
||||
Map<String, Object> customCalc = calcCustomExpr(view, filterResult, sqlMap, sqlMeta, provider);
|
||||
result.getData().put("customCalc", customCalc);
|
||||
try {
|
||||
var dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
var originSql = result.getQuerySql();
|
||||
var dynamicAssistFields = getDynamicThresholdFields(view);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var assistFields = getAssistFields(dynamicAssistFields, yAxis);
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(originSql, assistFields, dsMap);
|
||||
req.setQuery(assistSql);
|
||||
logger.debug("calcite assistSql sql: " + assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
result.setAssistData(assistData);
|
||||
result.setDynamicAssistFields(dynamicAssistFields);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -54,7 +74,9 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
var rowAxis = view.getXAxis();
|
||||
var colAxis = view.getXAxisExt();
|
||||
var dataMap = new HashMap<String, Object>();
|
||||
var quotaIds = view.getYAxis().stream().map(ChartViewFieldDTO::getDataeaseName).collect(Collectors.toSet());
|
||||
if (CollectionUtils.isEmpty(rowAxis)) {
|
||||
return dataMap;
|
||||
}
|
||||
// 行总计,列维度聚合加上自定义字段
|
||||
var row = tableTotal.getRow();
|
||||
if (row.isShowGrandTotals()) {
|
||||
@ -76,7 +98,7 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
var tmpData = new ArrayList<Map<String, Object>>();
|
||||
dataMap.put("rowSubTotal", tmpData);
|
||||
for (int i = 0; i < rowAxis.size(); i++) {
|
||||
if ( i == rowAxis.size() - 1) {
|
||||
if (i == rowAxis.size() - 1) {
|
||||
break;
|
||||
}
|
||||
var xAxis = new ArrayList<>(colAxis);
|
||||
@ -96,7 +118,7 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
}
|
||||
// 列总计,行维度聚合加上自定义字段
|
||||
var col = tableTotal.getCol();
|
||||
if (col.isShowGrandTotals()) {
|
||||
if (col.isShowGrandTotals() && CollectionUtils.isNotEmpty(colAxis)) {
|
||||
var yAxis = getCustomFields(view, col.getCalcTotals().getCfg());
|
||||
if (!yAxis.isEmpty()) {
|
||||
var result = getData(sqlMeta, rowAxis, yAxis, allFields, crossDs, dsMap, view, provider, needOrder);
|
||||
@ -109,13 +131,13 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
}
|
||||
}
|
||||
// 列小计,行维度聚合,自定义指标数 * (列维度的数量 - 1)
|
||||
if (col.isShowSubTotals()) {
|
||||
if (col.isShowSubTotals() && colAxis.size() >= 2) {
|
||||
var yAxis = getCustomFields(view, col.getCalcSubTotals().getCfg());
|
||||
if (!yAxis.isEmpty()) {
|
||||
var tmpData = new ArrayList<Map<String, Object>>();
|
||||
dataMap.put("colSubTotal", tmpData);
|
||||
for (int i = 0; i < colAxis.size(); i++) {
|
||||
if ( i == colAxis.size() - 1) {
|
||||
if (i == colAxis.size() - 1) {
|
||||
break;
|
||||
}
|
||||
var xAxis = new ArrayList<>(rowAxis);
|
||||
@ -153,13 +175,13 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
}
|
||||
}
|
||||
// 行总计里面的列小计
|
||||
if (row.isShowGrandTotals() && col.isShowSubTotals()) {
|
||||
if (row.isShowGrandTotals() && col.isShowSubTotals() && colAxis.size() >= 2) {
|
||||
var yAxis = getCustomFields(view, col.getCalcTotals().getCfg());
|
||||
if (!yAxis.isEmpty()) {
|
||||
var tmpData = new ArrayList<Map<String, Object>>();
|
||||
dataMap.put("colSubInRowTotal", tmpData);
|
||||
for (int i = 0; i < colAxis.size(); i++) {
|
||||
if ( i == colAxis.size() - 1) {
|
||||
if (i == colAxis.size() - 1) {
|
||||
break;
|
||||
}
|
||||
var xAxis = colAxis.subList(0, i + 1);
|
||||
@ -174,13 +196,13 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
}
|
||||
}
|
||||
// 列总计里面的行小计
|
||||
if (col.isShowGrandTotals() && row.isShowGrandTotals()) {
|
||||
if (col.isShowGrandTotals() && row.isShowGrandTotals() && rowAxis.size() >= 2) {
|
||||
var yAxis = getCustomFields(view, row.getCalcTotals().getCfg());
|
||||
if (!yAxis.isEmpty()) {
|
||||
var tmpData = new ArrayList<Map<String, Object>>();
|
||||
dataMap.put("rowSubInColTotal", tmpData);
|
||||
for (int i = 0; i < rowAxis.size(); i++) {
|
||||
if ( i == rowAxis.size() - 1) {
|
||||
if (i == rowAxis.size() - 1) {
|
||||
break;
|
||||
}
|
||||
var xAxis = rowAxis.subList(0, i + 1);
|
||||
@ -195,13 +217,13 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
}
|
||||
}
|
||||
// 行小计和列小计相交部分
|
||||
if (row.isShowSubTotals() && col.isShowSubTotals()) {
|
||||
if (row.isShowSubTotals() && col.isShowSubTotals() && colAxis.size() >= 2 && rowAxis.size() >= 2) {
|
||||
var yAxis = getCustomFields(view, col.getCalcTotals().getCfg());
|
||||
if (!yAxis.isEmpty()) {
|
||||
var tmpData = new ArrayList<List<Map<String, Object>>>();
|
||||
dataMap.put("rowSubInColSub", tmpData);
|
||||
for (int i = 0; i < rowAxis.size(); i++) {
|
||||
if ( i == rowAxis.size() - 1) {
|
||||
if (i == rowAxis.size() - 1) {
|
||||
break;
|
||||
}
|
||||
var tmpList = new ArrayList<Map<String, Object>>();
|
||||
@ -209,7 +231,7 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
var subRow = rowAxis.subList(0, i + 1);
|
||||
var xAxis = new ArrayList<>(subRow);
|
||||
for (int j = 0; j < colAxis.size(); j++) {
|
||||
if ( j == colAxis.size() - 1) {
|
||||
if (j == colAxis.size() - 1) {
|
||||
break;
|
||||
}
|
||||
var subCol = colAxis.subList(0, j + 1);
|
||||
@ -230,6 +252,14 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
|
||||
private Map<String, Object> buildCustomCalcResult(List<String[]> data, List<ChartViewFieldDTO> dimAxis, List<ChartViewFieldDTO> quotaAxis) {
|
||||
var rootResult = new HashMap<String, Object>();
|
||||
if (CollectionUtils.isEmpty(dimAxis)) {
|
||||
var rowData = data.getFirst();
|
||||
for (int i = 0; i < rowData.length; i++) {
|
||||
var qAxis = quotaAxis.get(i);
|
||||
rootResult.put(qAxis.getDataeaseName(), rowData[i]);
|
||||
}
|
||||
return rootResult;
|
||||
}
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
var rowData = data.get(i);
|
||||
Map<String, Object> curSubMap = rootResult;
|
||||
@ -254,8 +284,8 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
}
|
||||
|
||||
private Tuple2<String, List<String[]>> getData(SQLMeta sqlMeta, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis,
|
||||
List<ChartViewFieldDTO> allFields, boolean crossDs, Map<Long, DatasourceSchemaDTO> dsMap,
|
||||
ChartViewDTO view, Provider provider, boolean needOrder) {
|
||||
List<ChartViewFieldDTO> allFields, boolean crossDs, Map<Long, DatasourceSchemaDTO> dsMap,
|
||||
ChartViewDTO view, Provider provider, boolean needOrder) {
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setDsList(dsMap);
|
||||
Dimension2SQLObj.dimension2sqlObj(sqlMeta, xAxis, FieldUtil.transFields(allFields), crossDs, dsMap, Utils.getParams(FieldUtil.transFields(allFields)), view.getCalParams(), pluginManage);
|
||||
@ -268,6 +298,7 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
nullToBlank(data);
|
||||
return Tuples.of(querySql, data);
|
||||
}
|
||||
|
||||
private void nullToBlank(List<String[]> data) {
|
||||
data.forEach(r -> {
|
||||
for (int i = 0; i < r.length; i++) {
|
||||
@ -285,7 +316,7 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
if (!quotaIds.contains(totalCfg.getDataeaseName())) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(totalCfg.getAggregation(), "CUSTOM")){
|
||||
if (StringUtils.equalsIgnoreCase(totalCfg.getAggregation(), "CUSTOM")) {
|
||||
var field = new ChartViewFieldDTO();
|
||||
field.setDeType(DeTypeConstants.DE_FLOAT);
|
||||
BeanUtils.copyBean(field, totalCfg);
|
||||
|
||||
@ -9,7 +9,7 @@ import java.io.Serializable;
|
||||
* </p>
|
||||
*
|
||||
* @author fit2cloud
|
||||
* @since 2024-05-07
|
||||
* @since 2024-10-23
|
||||
*/
|
||||
@TableName("core_chart_view")
|
||||
public class CoreChartView implements Serializable {
|
||||
@ -101,11 +101,21 @@ public class CoreChartView implements Serializable {
|
||||
*/
|
||||
private String customAttr;
|
||||
|
||||
/**
|
||||
* 图形属性_移动端
|
||||
*/
|
||||
private String customAttrMobile;
|
||||
|
||||
/**
|
||||
* 组件样式
|
||||
*/
|
||||
private String customStyle;
|
||||
|
||||
/**
|
||||
* 组件样式_移动端
|
||||
*/
|
||||
private String customStyleMobile;
|
||||
|
||||
/**
|
||||
* 结果过滤
|
||||
*/
|
||||
@ -137,7 +147,7 @@ public class CoreChartView implements Serializable {
|
||||
private Long updateTime;
|
||||
|
||||
/**
|
||||
* 缩略图
|
||||
* 缩略图
|
||||
*/
|
||||
private String snapshot;
|
||||
|
||||
@ -206,8 +216,14 @@ public class CoreChartView implements Serializable {
|
||||
*/
|
||||
private Boolean aggregate;
|
||||
|
||||
/**
|
||||
* 流向地图起点名称field
|
||||
*/
|
||||
private String flowMapStartName;
|
||||
|
||||
/**
|
||||
* 流向地图终点名称field
|
||||
*/
|
||||
private String flowMapEndName;
|
||||
|
||||
/**
|
||||
@ -215,7 +231,6 @@ public class CoreChartView implements Serializable {
|
||||
*/
|
||||
private String extColor;
|
||||
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@ -352,6 +367,14 @@ public class CoreChartView implements Serializable {
|
||||
this.customAttr = customAttr;
|
||||
}
|
||||
|
||||
public String getCustomAttrMobile() {
|
||||
return customAttrMobile;
|
||||
}
|
||||
|
||||
public void setCustomAttrMobile(String customAttrMobile) {
|
||||
this.customAttrMobile = customAttrMobile;
|
||||
}
|
||||
|
||||
public String getCustomStyle() {
|
||||
return customStyle;
|
||||
}
|
||||
@ -360,6 +383,14 @@ public class CoreChartView implements Serializable {
|
||||
this.customStyle = customStyle;
|
||||
}
|
||||
|
||||
public String getCustomStyleMobile() {
|
||||
return customStyleMobile;
|
||||
}
|
||||
|
||||
public void setCustomStyleMobile(String customStyleMobile) {
|
||||
this.customStyleMobile = customStyleMobile;
|
||||
}
|
||||
|
||||
public String getCustomFilter() {
|
||||
return customFilter;
|
||||
}
|
||||
@ -564,7 +595,9 @@ public class CoreChartView implements Serializable {
|
||||
", extLabel = " + extLabel +
|
||||
", extTooltip = " + extTooltip +
|
||||
", customAttr = " + customAttr +
|
||||
", customAttrMobile = " + customAttrMobile +
|
||||
", customStyle = " + customStyle +
|
||||
", customStyleMobile = " + customStyleMobile +
|
||||
", customFilter = " + customFilter +
|
||||
", drillFields = " + drillFields +
|
||||
", senior = " + senior +
|
||||
@ -585,9 +618,9 @@ public class CoreChartView implements Serializable {
|
||||
", copyFrom = " + copyFrom +
|
||||
", copyId = " + copyId +
|
||||
", aggregate = " + aggregate +
|
||||
", flowMapStartName=" + flowMapStartName +
|
||||
", flowMapEndName=" + flowMapEndName +
|
||||
", extColor=" + extColor +
|
||||
", flowMapStartName = " + flowMapStartName +
|
||||
", flowMapEndName = " + flowMapEndName +
|
||||
", extColor = " + extColor +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
* </p>
|
||||
*
|
||||
* @author fit2cloud
|
||||
* @since 2024-05-07
|
||||
* @since 2024-10-23
|
||||
*/
|
||||
@Mapper
|
||||
public interface CoreChartViewMapper extends BaseMapper<CoreChartView> {
|
||||
|
||||
@ -110,7 +110,6 @@ public class ChartDataManage {
|
||||
}
|
||||
|
||||
var dillAxis = new ArrayList<ChartViewFieldDTO>();
|
||||
|
||||
DatasetGroupInfoDTO table = datasetGroupManage.getDatasetGroupInfoDTO(view.getTableId(), null);
|
||||
if (table == null) {
|
||||
DEException.throwException(ResultCode.DATA_IS_WRONG.code(), Translator.get("i18n_no_ds"));
|
||||
@ -313,11 +312,15 @@ public class ChartDataManage {
|
||||
ChartViewFieldDTO nextDrillField = drill.get(i + 1);
|
||||
if (!fields.contains(nextDrillField.getId())) {
|
||||
nextDrillField.setSource(FieldSource.DRILL);
|
||||
nextDrillField.setSort(getDrillSort(xAxis, drill.get(0)));
|
||||
xAxis.add(nextDrillField);
|
||||
dillAxis.add(nextDrillField);
|
||||
fields.add(nextDrillField.getId());
|
||||
} else {
|
||||
Optional<ChartViewFieldDTO> axis = xAxis.stream().filter(x -> Objects.equals(x.getId(), nextDrillField.getId())).findFirst();
|
||||
axis.ifPresent(field -> {
|
||||
field.setSort(nextDrillField.getSort());
|
||||
field.setCustomSort(nextDrillField.getCustomSort());
|
||||
});
|
||||
dillAxis.add(nextDrillField);
|
||||
}
|
||||
}
|
||||
@ -371,10 +374,7 @@ public class ChartDataManage {
|
||||
provider = ProviderFactory.getProvider(dsMap.entrySet().iterator().next().getValue().getType());
|
||||
}
|
||||
|
||||
if (ObjectUtils.isEmpty(view.getCalParams())) {
|
||||
view.setCalParams(Utils.getParams(transFields(allFields)));
|
||||
}
|
||||
|
||||
view.setCalParams(Utils.getParams(transFields(allFields)));
|
||||
SQLMeta sqlMeta = new SQLMeta();
|
||||
Table2SQLObj.table2sqlobj(sqlMeta, null, "(" + sql + ")", crossDs);
|
||||
CustomWhere2Str.customWhere2sqlObj(sqlMeta, fieldCustomFilter, transFields(allFields), crossDs, dsMap, Utils.getParams(transFields(allFields)), view.getCalParams(), pluginManage);
|
||||
@ -625,7 +625,9 @@ public class ChartDataManage {
|
||||
|| StringUtils.containsIgnoreCase(view.getType(), "group")
|
||||
|| ("antv".equalsIgnoreCase(view.getRender()) && "line".equalsIgnoreCase(view.getType()))
|
||||
|| StringUtils.equalsIgnoreCase(view.getType(), "flow-map")
|
||||
|| StringUtils.equalsIgnoreCase(view.getType(), "t-heatmap")) {
|
||||
|| StringUtils.equalsIgnoreCase(view.getType(), "t-heatmap")
|
||||
|| StringUtils.equalsIgnoreCase(view.getType(), "sankey")
|
||||
) {
|
||||
xAxis.addAll(xAxisExt);
|
||||
}
|
||||
List<ChartViewFieldDTO> yAxis = new ArrayList<>(view.getYAxis());
|
||||
@ -793,4 +795,24 @@ public class ChartDataManage {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getDrillFieldData(ChartViewDTO view, Long fieldId) throws Exception {
|
||||
List<ChartViewFieldDTO> drillField = view.getDrillFields();
|
||||
ChartViewFieldDTO targetField = null;
|
||||
for (int i = 0; i < drillField.size(); i++) {
|
||||
ChartViewFieldDTO tmp = drillField.get(i);
|
||||
if (tmp.getId().equals(fieldId)) {
|
||||
targetField = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (targetField == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
view.setXAxis(Collections.singletonList(targetField));
|
||||
|
||||
List<String[]> sqlData = sqlData(view, view.getChartExtRequest(), fieldId);
|
||||
List<String[]> result = customSort(Optional.ofNullable(targetField.getCustomSort()).orElse(new ArrayList<>()), sqlData, 0);
|
||||
return result.stream().map(i -> i[0]).distinct().collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,7 +335,13 @@ public class ChartViewManege {
|
||||
record.setExtLabel(objectMapper.writeValueAsString(dto.getExtLabel()));
|
||||
record.setExtTooltip(objectMapper.writeValueAsString(dto.getExtTooltip()));
|
||||
record.setCustomAttr(objectMapper.writeValueAsString(dto.getCustomAttr()));
|
||||
if(dto.getCustomAttrMobile() != null){
|
||||
record.setCustomAttrMobile(objectMapper.writeValueAsString(dto.getCustomAttrMobile()));
|
||||
}
|
||||
record.setCustomStyle(objectMapper.writeValueAsString(dto.getCustomStyle()));
|
||||
if(dto.getCustomAttrMobile() != null) {
|
||||
record.setCustomStyleMobile(objectMapper.writeValueAsString(dto.getCustomStyleMobile()));
|
||||
}
|
||||
record.setSenior(objectMapper.writeValueAsString(dto.getSenior()));
|
||||
record.setDrillFields(objectMapper.writeValueAsString(dto.getDrillFields()));
|
||||
record.setCustomFilter(objectMapper.writeValueAsString(dto.getCustomFilter()));
|
||||
@ -363,7 +369,13 @@ public class ChartViewManege {
|
||||
dto.setExtLabel(JsonUtil.parseList(record.getExtLabel(), tokenType));
|
||||
dto.setExtTooltip(JsonUtil.parseList(record.getExtTooltip(), tokenType));
|
||||
dto.setCustomAttr(JsonUtil.parse(record.getCustomAttr(), Map.class));
|
||||
if(record.getCustomAttrMobile() != null){
|
||||
dto.setCustomAttrMobile(JsonUtil.parse(record.getCustomAttrMobile(), Map.class));
|
||||
}
|
||||
dto.setCustomStyle(JsonUtil.parse(record.getCustomStyle(), Map.class));
|
||||
if(record.getCustomStyleMobile() != null) {
|
||||
dto.setCustomStyleMobile(JsonUtil.parse(record.getCustomStyleMobile(), Map.class));
|
||||
}
|
||||
dto.setSenior(JsonUtil.parse(record.getSenior(), Map.class));
|
||||
dto.setDrillFields(JsonUtil.parseList(record.getDrillFields(), tokenType));
|
||||
dto.setCustomFilter(JsonUtil.parseObject(record.getCustomFilter(), FilterTreeObj.class));
|
||||
|
||||
@ -3,6 +3,7 @@ package io.dataease.chart.manage;
|
||||
import io.dataease.api.chart.request.ThresholdCheckRequest;
|
||||
import io.dataease.api.chart.vo.ThresholdCheckVO;
|
||||
import io.dataease.engine.constant.DeTypeConstants;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import io.dataease.extensions.view.dto.ChartViewFieldDTO;
|
||||
@ -18,6 +19,8 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -126,12 +129,13 @@ public class ChartViewThresholdManage {
|
||||
String enumValueText = String.join(",", enumValue);
|
||||
return fieldName + " 属于 " + "( " + enumValueText + " )";
|
||||
} else {
|
||||
Integer deType = map.getDeType();
|
||||
String valueType = item.getValueType();
|
||||
return fieldName + " " + translateTerm(item.getTerm()) + " " + formatFieldValue(item.getValue(), valueType);
|
||||
return fieldName + " " + translateTerm(item.getTerm()) + " " + formatFieldValue(item.getValue(), valueType, deType);
|
||||
}
|
||||
}
|
||||
|
||||
private String formatFieldValue(String value, String valueType) {
|
||||
private String formatFieldValue(String value, String valueType, Integer deType) {
|
||||
if (StringUtils.isBlank(valueType)) {
|
||||
valueType = "fixed";
|
||||
}
|
||||
@ -144,11 +148,72 @@ public class ChartViewThresholdManage {
|
||||
return "最小值";
|
||||
} else if (StringUtils.equals("average", value)) {
|
||||
return "平均值";
|
||||
} else if (deType == 1) {
|
||||
return formatDynamicTimeLabel(value);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private String formatDynamicTimeLabel(String value) {
|
||||
if (StringUtils.isBlank(value)) {
|
||||
return value;
|
||||
}
|
||||
try {
|
||||
Map map = JsonUtil.parseObject(value, Map.class);
|
||||
String format = map.get("format").toString();
|
||||
int timeFlag = Integer.parseInt(map.get("timeFlag").toString());
|
||||
|
||||
if (timeFlag == 9) {
|
||||
int count = Integer.parseInt(map.get("count").toString());
|
||||
int unit = Integer.parseInt(map.get("unit").toString());
|
||||
int suffix = Integer.parseInt(map.get("suffix").toString());
|
||||
String time = map.get("time").toString();
|
||||
|
||||
List<String> unitLabels = null;
|
||||
if (StringUtils.equalsIgnoreCase("YYYY", format)) {
|
||||
unitLabels = List.of("年");
|
||||
} else if (StringUtils.equalsIgnoreCase("YYYY-MM", format)) {
|
||||
unitLabels = List.of("年", "月");
|
||||
} else if (StringUtils.equalsIgnoreCase("YYYY-MM-DD", format)) {
|
||||
unitLabels = List.of("年", "月", "日");
|
||||
} else if (StringUtils.equalsIgnoreCase("HH:mm:ss", format)) {
|
||||
DEException.throwException("纯时间格式不支持动态格式");
|
||||
} else {
|
||||
unitLabels = List.of("年", "月", "日");
|
||||
}
|
||||
String unitText = unitLabels.get(unit - 1);
|
||||
String suffixText = "前";
|
||||
if (suffix == 2) {
|
||||
suffixText = "后";
|
||||
}
|
||||
String timeText = "";
|
||||
if (StringUtils.containsIgnoreCase(format, "HH")) {
|
||||
timeText = " " + time;
|
||||
}
|
||||
return count + " " + unitText + suffixText + timeText;
|
||||
} else {
|
||||
List<String> shortLabels = null;
|
||||
if (StringUtils.equalsIgnoreCase("YYYY", format)) {
|
||||
shortLabels = List.of("当年", "去年", "明年");
|
||||
} else if (StringUtils.equalsIgnoreCase("YYYY-MM", format)) {
|
||||
shortLabels = List.of("当月", "上个月", "下个月", "年初", "年末");
|
||||
} else if (StringUtils.equalsIgnoreCase("YYYY-MM-DD", format)) {
|
||||
shortLabels = List.of("今天", "昨天", "明天", "月初", "月末");
|
||||
} else if (StringUtils.equalsIgnoreCase("HH:mm:ss", format)) {
|
||||
shortLabels = List.of("当前", "1小时前", "1小时后");
|
||||
} else {
|
||||
shortLabels = List.of("今天", "昨天", "明天", "月初", "月末");
|
||||
}
|
||||
return shortLabels.get(timeFlag - 1);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("动态时间配置错误,请重新配置!");
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private String translateTerm(String term) {
|
||||
return switch (term) {
|
||||
case "eq" -> "等于";
|
||||
@ -250,11 +315,100 @@ public class ChartViewThresholdManage {
|
||||
if ((Objects.equals(fieldDTO.getDeType(), DeTypeConstants.DE_INT) || Objects.equals(fieldDTO.getDeType(), DeTypeConstants.DE_FLOAT)) && StringUtils.equals("dynamic", item.getValueType())) {
|
||||
item.setField(fieldDTO);
|
||||
item.setValue(formatValue(rows, item));
|
||||
} else if (Objects.equals(fieldDTO.getDeType(), DeTypeConstants.DE_TIME) && StringUtils.equals("dynamic", item.getValueType())) {
|
||||
item.setField(fieldDTO);
|
||||
item.setValue(dynamicFormatValue(item));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String dynamicFormatValue(FilterTreeItem item) {
|
||||
String value = item.getValue();
|
||||
|
||||
if (StringUtils.isBlank(value)) {
|
||||
return value;
|
||||
}
|
||||
try {
|
||||
Map map = JsonUtil.parseObject(value, Map.class);
|
||||
String format = map.get("format").toString();
|
||||
int timeFlag = Integer.parseInt(map.get("timeFlag").toString());
|
||||
if (timeFlag == 9) {
|
||||
int count = Integer.parseInt(map.get("count").toString());
|
||||
int unit = Integer.parseInt(map.get("unit").toString());
|
||||
int suffix = Integer.parseInt(map.get("suffix").toString());
|
||||
String time = map.get("time").toString();
|
||||
String timeValue = getCustomTimeValue(format, unit, suffix, count, false);
|
||||
if (StringUtils.containsIgnoreCase(format, "yyyy-MM-dd HH") && StringUtils.isNotBlank(time)) {
|
||||
return timeValue + " " + time;
|
||||
}
|
||||
return timeValue;
|
||||
} else {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
String fullFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
int length = format.length();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(fullFormat.substring(0, length));
|
||||
int count = timeFlag == 1 ? 0 : 1;
|
||||
int suffix = timeFlag - 1;
|
||||
if (StringUtils.equalsIgnoreCase("YYYY", format)) {
|
||||
return getCustomTimeValue(format, 1, suffix, count, true);
|
||||
} else if (StringUtils.equalsIgnoreCase("YYYY-MM", format)) {
|
||||
if (timeFlag == 4) {
|
||||
return now.withMonth(1).withDayOfMonth(1).format(formatter);
|
||||
} else if (timeFlag == 5) {
|
||||
return now.withMonth(12).withDayOfMonth(31).format(formatter);
|
||||
} else {
|
||||
return getCustomTimeValue(format, 2, suffix, count, true);
|
||||
}
|
||||
} else {
|
||||
if (timeFlag == 4) {
|
||||
return now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).format(formatter);
|
||||
} else if (timeFlag == 5) {
|
||||
return now.plusMonths(1).withDayOfMonth(1).minusDays(1).withHour(0).withMinute(0).withSecond(0).format(formatter);
|
||||
} else {
|
||||
return getCustomTimeValue(format, 3, suffix, count, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("动态时间配置错误,请重新配置!" + e.getMessage());
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private String getCustomTimeValue(String format, int unit, int suffix, int count, boolean hasTime) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
String fullFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
int len = format.length();
|
||||
if (hasTime) {
|
||||
now = now.withHour(0).withMinute(0).withSecond(0);
|
||||
} else {
|
||||
len = Math.min(len, 10);
|
||||
}
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(fullFormat.substring(0, len));
|
||||
if (count == 0) {
|
||||
return now.format(formatter);
|
||||
}
|
||||
if (unit == 1) {
|
||||
if (suffix == 1) {
|
||||
return now.minusYears(count).format(formatter);
|
||||
}
|
||||
return now.plusYears(count).format(formatter);
|
||||
} else if (unit == 2) {
|
||||
if (suffix == 1) {
|
||||
return now.minusMonths(count).format(formatter);
|
||||
}
|
||||
return now.plusMonths(count).format(formatter);
|
||||
} else {
|
||||
if (suffix == 1) {
|
||||
return now.minusDays(count).format(formatter);
|
||||
}
|
||||
return now.plusDays(count).format(formatter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String formatValue(List<Map<String, Object>> rows, FilterTreeItem item) {
|
||||
DatasetTableFieldDTO field = item.getField();
|
||||
String dataeaseName = field.getDataeaseName();
|
||||
|
||||
@ -5,6 +5,7 @@ import io.dataease.api.chart.ChartDataApi;
|
||||
import io.dataease.api.chart.dto.ViewDetailField;
|
||||
import io.dataease.api.chart.request.ChartExcelRequest;
|
||||
import io.dataease.api.chart.request.ChartExcelRequestInner;
|
||||
import io.dataease.auth.DeLinkPermit;
|
||||
import io.dataease.chart.constant.ChartConstants;
|
||||
import io.dataease.chart.manage.ChartDataManage;
|
||||
import io.dataease.constant.AuthConstant;
|
||||
@ -17,6 +18,7 @@ import io.dataease.exportCenter.manage.ExportCenterManage;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import io.dataease.extensions.view.dto.ChartViewFieldDTO;
|
||||
import io.dataease.extensions.view.dto.FormatterCfgDTO;
|
||||
import io.dataease.license.manage.F2CLicLimitedManage;
|
||||
import io.dataease.result.ResultCode;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
@ -38,6 +40,10 @@ import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@ -71,6 +77,7 @@ public class ChartDataServer implements ChartDataApi {
|
||||
return Math.toIntExact(Math.min(f2CLicLimitedManage.checkDatasetLimit(), limit));
|
||||
}
|
||||
|
||||
@DeLinkPermit("#p0.sceneId")
|
||||
@Override
|
||||
public ChartViewDTO getData(ChartViewDTO chartViewDTO) throws Exception {
|
||||
try {
|
||||
@ -111,7 +118,7 @@ public class ChartDataServer implements ChartDataApi {
|
||||
Integer curLimit = getExportLimit();
|
||||
if (ChartConstants.VIEW_RESULT_MODE.CUSTOM.equals(viewDTO.getResultMode())) {
|
||||
Integer limitCount = viewDTO.getResultCount();
|
||||
viewDTO.setResultCount(Math.min(curLimit,limitCount));
|
||||
viewDTO.setResultCount(Math.min(curLimit, limitCount));
|
||||
} else {
|
||||
viewDTO.setResultCount(curLimit);
|
||||
}
|
||||
@ -121,6 +128,16 @@ public class ChartDataServer implements ChartDataApi {
|
||||
request.setHeader(dsHeader);
|
||||
request.setExcelTypes(dsTypes);
|
||||
}
|
||||
for (Object[] objects : tableRow) {
|
||||
for (int i = 0; i < viewDTO.getXAxis().size(); i++) {
|
||||
if (viewDTO.getXAxis().get(i).getDeType().equals(DeTypeConstants.DE_INT) || viewDTO.getXAxis().get(i).getDeType().equals(DeTypeConstants.DE_FLOAT)) {
|
||||
try {
|
||||
objects[i] = valueFormatter(BigDecimal.valueOf(Double.valueOf(objects[i].toString())), viewDTO.getXAxis().get(i).getFormatterCfg());
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
request.setDetails(tableRow);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@ -128,6 +145,85 @@ public class ChartDataServer implements ChartDataApi {
|
||||
|
||||
}
|
||||
|
||||
public static String valueFormatter(BigDecimal value, FormatterCfgDTO formatter) {
|
||||
if (value == null || formatter == null) {
|
||||
return null;
|
||||
}
|
||||
String result;
|
||||
if (formatter.getType().equals("auto")) {
|
||||
result = transSeparatorAndSuffix(String.valueOf(transUnit(value, formatter)), formatter);
|
||||
} else if (formatter.getType().equals("value")) {
|
||||
result = transSeparatorAndSuffix(transDecimal(transUnit(value, formatter), formatter), formatter);
|
||||
} else if (formatter.getType().equals("percent")) {
|
||||
value = value.multiply(BigDecimal.valueOf(100));
|
||||
result = transSeparatorAndSuffix(transDecimal(value, formatter), formatter);
|
||||
} else {
|
||||
result = value.toString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static BigDecimal transUnit(BigDecimal value, FormatterCfgDTO formatter) {
|
||||
return value.divide(BigDecimal.valueOf(formatter.getUnit()));
|
||||
}
|
||||
|
||||
private static String transDecimal(BigDecimal value, FormatterCfgDTO formatter) {
|
||||
DecimalFormat df = new DecimalFormat("0." + new String(new char[formatter.getDecimalCount()]).replace('\0', '0'));
|
||||
return df.format(value);
|
||||
}
|
||||
|
||||
private static String transSeparatorAndSuffix(String value, FormatterCfgDTO formatter) {
|
||||
StringBuilder sb = new StringBuilder(value);
|
||||
|
||||
if (formatter.getThousandSeparator()) {
|
||||
String[] parts = value.split("\\.");
|
||||
parts[0] = addThousandSeparators(parts[0]);
|
||||
sb = new StringBuilder(String.join(".", parts));
|
||||
}
|
||||
if (formatter.getType().equals("percent")) {
|
||||
sb.append('%');
|
||||
} else {
|
||||
switch (formatter.getUnit()) {
|
||||
case 1000:
|
||||
sb.append("千");
|
||||
break;
|
||||
case 10000:
|
||||
sb.append("万");
|
||||
break;
|
||||
case 1000000:
|
||||
sb.append("百万");
|
||||
break;
|
||||
case 100000000:
|
||||
sb.append('亿');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
String suffix = formatter.getSuffix().trim();
|
||||
if (!suffix.isEmpty()) {
|
||||
sb.append(suffix);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String addThousandSeparators(String number) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int len = number.length();
|
||||
int count = 0;
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
sb.append(number.charAt(i));
|
||||
count++;
|
||||
if (count == 3 && i != 0) {
|
||||
sb.append(',');
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.reverse().toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void innerExportDetails(ChartExcelRequest request, HttpServletResponse response) throws Exception {
|
||||
HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
@ -184,7 +280,7 @@ public class ChartDataServer implements ChartDataApi {
|
||||
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
//文件名称
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + request.getViewName() + ".xlsx");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(request.getViewName(), StandardCharsets.UTF_8) + ".xlsx");
|
||||
wb.write(outputStream);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
@ -301,4 +397,9 @@ public class ChartDataServer implements ChartDataApi {
|
||||
public List<String> getFieldData(ChartViewDTO view, Long fieldId, String fieldType) throws Exception {
|
||||
return chartDataManage.getFieldData(view, fieldId, fieldType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDrillFieldData(ChartViewDTO view, Long fieldId) throws Exception {
|
||||
return chartDataManage.getDrillFieldData(view, fieldId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1766,7 +1766,7 @@ public class ChartDataBuild {
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Object> transSymbolicMapNormalWithDetail(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartViewFieldDTO> extBubble, List<String[]> data, List<ChartViewFieldDTO> detailFields, List<String[]> detailData) {
|
||||
public static Map<String, Object> transSymbolicMapNormalWithDetail(ChartViewDTO view, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartViewFieldDTO> extBubble, List<String[]> data, List<ChartViewFieldDTO> detailFields, List<String[]> detailData) {
|
||||
int detailIndex = xAxis.size();
|
||||
|
||||
List<ChartViewFieldDTO> realDetailFields = detailFields.subList(detailIndex, detailFields.size());
|
||||
@ -1778,7 +1778,7 @@ public class ChartDataBuild {
|
||||
fields.addAll(extBubble);
|
||||
if (ObjectUtils.isNotEmpty(yAxis))
|
||||
fields.addAll(yAxis);
|
||||
Map<String, Object> map = transTableNormal(fields, null, data, new HashMap<>());
|
||||
Map<String, Object> map = transTableNormal(fields, view, data, new HashMap<>());
|
||||
List<Map<String, Object>> tableRow = (List<Map<String, Object>>) map.get("tableRow");
|
||||
final int xEndIndex = detailIndex;
|
||||
Map<String, List<String[]>> groupDataList = detailData.stream().collect(Collectors.groupingBy(item -> "(" + StringUtils.join(ArrayUtils.subarray(item, 0, xEndIndex), ")-de-(") + ")"));
|
||||
|
||||
@ -536,7 +536,7 @@ public class SqlparserUtils {
|
||||
}
|
||||
}
|
||||
if (filterParameter != null) {
|
||||
sql = sql.replace(matcher.group(), transFilter(filterParameter));
|
||||
sql = sql.replace(matcher.group(), transFilter(filterParameter, dsMap));
|
||||
} else {
|
||||
if (defaultsSqlVariableDetail != null && StringUtils.isNotEmpty(defaultsSqlVariableDetail.getDefaultValue())) {
|
||||
if (!isEdit && isFromDataSet && defaultsSqlVariableDetail.getDefaultValueScope().equals(SqlVariableDetails.DefaultValueScope.ALLSCOPE)) {
|
||||
@ -594,15 +594,28 @@ public class SqlparserUtils {
|
||||
}
|
||||
|
||||
|
||||
private static String transFilter(SqlVariableDetails sqlVariableDetails) {
|
||||
private static String transFilter(SqlVariableDetails sqlVariableDetails, Map<Long, DatasourceSchemaDTO> dsMap) {
|
||||
if (sqlVariableDetails.getOperator().equals("in")) {
|
||||
return "'" + String.join("','", sqlVariableDetails.getValue()) + "'";
|
||||
} else if (sqlVariableDetails.getOperator().equals("between")) {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(sqlVariableDetails.getType().size() > 1 ? (String) sqlVariableDetails.getType().get(1).replace("DD", "dd").replace("YYYY", "yyyy") : "yyyy");
|
||||
if (StringUtils.endsWith(sqlVariableDetails.getId(), START_END_SEPARATOR)) {
|
||||
return simpleDateFormat.format(new Date(Long.parseLong((String) sqlVariableDetails.getValue().get(1))));
|
||||
if (StringUtils.equalsIgnoreCase(dsMap.entrySet().iterator().next().getValue().getType(), DatasourceConfiguration.DatasourceType.sqlServer.getType())
|
||||
&& sqlVariableDetails.getDeType() == 0) {
|
||||
return "N'" + String.join("', N'", sqlVariableDetails.getValue()) + "'";
|
||||
} else {
|
||||
return simpleDateFormat.format(new Date(Long.parseLong((String) sqlVariableDetails.getValue().get(0))));
|
||||
return "'" + String.join("','", sqlVariableDetails.getValue()) + "'";
|
||||
}
|
||||
} else if (sqlVariableDetails.getOperator().equals("between")) {
|
||||
if (sqlVariableDetails.getDeType() == 1) {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(sqlVariableDetails.getType().size() > 1 ? (String) sqlVariableDetails.getType().get(1).replace("DD", "dd").replace("YYYY", "yyyy") : "yyyy");
|
||||
if (StringUtils.endsWith(sqlVariableDetails.getId(), START_END_SEPARATOR)) {
|
||||
return simpleDateFormat.format(new Date(Long.parseLong((String) sqlVariableDetails.getValue().get(1))));
|
||||
} else {
|
||||
return simpleDateFormat.format(new Date(Long.parseLong((String) sqlVariableDetails.getValue().get(0))));
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.endsWith(sqlVariableDetails.getId(), START_END_SEPARATOR)) {
|
||||
return sqlVariableDetails.getValue().get(1);
|
||||
} else {
|
||||
return sqlVariableDetails.getValue().get(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return (String) sqlVariableDetails.getValue().get(0);
|
||||
|
||||
@ -14,7 +14,7 @@ public class CommonConfig {
|
||||
@Bean(destroyMethod = "shutdown")
|
||||
public CommonThreadPool resourcePoolThreadPool() {
|
||||
CommonThreadPool commonThreadPool = new CommonThreadPool();
|
||||
commonThreadPool.setCorePoolSize(20);
|
||||
commonThreadPool.setCorePoolSize(50);
|
||||
commonThreadPool.setMaxQueueSize(100);
|
||||
commonThreadPool.setKeepAliveSeconds(3600);
|
||||
return commonThreadPool;
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
package io.dataease.config;
|
||||
|
||||
import io.dataease.constant.AuthConstant;
|
||||
import io.dataease.share.interceptor.LinkInterceptor;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@ -11,6 +14,8 @@ import static io.dataease.utils.StaticResourceUtils.ensureSuffix;
|
||||
@Configuration
|
||||
public class DeMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
@Resource
|
||||
private LinkInterceptor linkInterceptor;
|
||||
|
||||
/**
|
||||
* Configuring static resource path
|
||||
@ -33,4 +38,9 @@ public class DeMvcConfig implements WebMvcConfigurer {
|
||||
registry.addResourceHandler(geoUrlPattern).addResourceLocations(geoDir);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(linkInterceptor).addPathPatterns("/**");
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ public class CopilotManage {
|
||||
Map<Long, DatasourceSchemaDTO> dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
if (crossDs) {
|
||||
DEException.throwException("跨源数据集不支持该功能");
|
||||
DEException.throwException(Translator.get("i18n_copilot_cross_ds_error"));
|
||||
}
|
||||
|
||||
// 调用copilot service 获取SQL和chart struct,将返回SQL中表名替换成数据集SQL
|
||||
@ -302,7 +302,7 @@ public class CopilotManage {
|
||||
if (StringUtils.equalsIgnoreCase(receiveDTO.getChart().getType(), "pie")) {
|
||||
AxisFieldDTO column = receiveDTO.getChart().getColumn();
|
||||
if (fields.size() != 2 || column == null) {
|
||||
DEException.throwException("当前字段不足以构建饼图: " + JsonUtil.toJSONString(receiveDTO));
|
||||
DEException.throwException("build pie error: " + JsonUtil.toJSONString(receiveDTO));
|
||||
}
|
||||
AxisDTO axisDTO = new AxisDTO();
|
||||
AxisFieldDTO x = new AxisFieldDTO();
|
||||
@ -318,7 +318,7 @@ public class CopilotManage {
|
||||
y.setName(column.getName());
|
||||
y.setValue(column.getValue());
|
||||
} else {
|
||||
DEException.throwException("当前字段不足以构建饼图: " + JsonUtil.toJSONString(receiveDTO));
|
||||
DEException.throwException("build pie error: " + JsonUtil.toJSONString(receiveDTO));
|
||||
}
|
||||
axisDTO.setX(x);
|
||||
axisDTO.setY(y);
|
||||
|
||||
@ -6,4 +6,5 @@ package io.dataease.dataset.constant;
|
||||
public class DatasetTableType {
|
||||
public static String DB = "db";
|
||||
public static String SQL = "sql";
|
||||
public static String Es = "es";
|
||||
}
|
||||
|
||||
@ -50,6 +50,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -129,6 +130,15 @@ public class DatasetDataManage {
|
||||
datasourceRequest.setTable(tableInfoDTO.getTable());
|
||||
}
|
||||
|
||||
tableFields = provider.fetchTableField(datasourceRequest);
|
||||
} else if (StringUtils.equalsIgnoreCase(type, DatasetTableType.Es)) {
|
||||
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(datasetTableDTO.getDatasourceId());
|
||||
Provider provider = ProviderFactory.getProvider(type);
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
|
||||
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
|
||||
datasourceRequest.setDatasource(datasourceSchemaDTO);
|
||||
datasourceRequest.setTable(datasetTableDTO.getTableName());
|
||||
tableFields = provider.fetchTableField(datasourceRequest);
|
||||
} else {
|
||||
// excel,api
|
||||
@ -185,9 +195,7 @@ public class DatasetDataManage {
|
||||
DEException.throwException(Translator.get("i18n_no_column_permission"));
|
||||
}
|
||||
}
|
||||
|
||||
buildFieldName(sqlMap, fields);
|
||||
|
||||
Map<Long, DatasourceSchemaDTO> dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
DatasourceUtils.checkDsStatus(dsMap);
|
||||
List<String> dsList = new ArrayList<>();
|
||||
@ -202,13 +210,11 @@ public class DatasetDataManage {
|
||||
}
|
||||
sql = Utils.replaceSchemaAlias(sql, dsMap);
|
||||
}
|
||||
|
||||
List<DataSetRowPermissionsTreeDTO> rowPermissionsTree = new ArrayList<>();
|
||||
TokenUserBO user = AuthUtils.getUser();
|
||||
if (user != null && checkPermission) {
|
||||
rowPermissionsTree = permissionManage.getRowPermissionsTree(datasetGroupInfoDTO.getId(), user.getUserId());
|
||||
}
|
||||
|
||||
Provider provider;
|
||||
if (crossDs) {
|
||||
provider = ProviderFactory.getDefaultProvider();
|
||||
@ -236,7 +242,6 @@ public class DatasetDataManage {
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setQuery(querySQL);
|
||||
datasourceRequest.setDsList(dsMap);
|
||||
|
||||
Map<String, Object> data = provider.fetchResultField(datasourceRequest);
|
||||
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
@ -448,11 +453,17 @@ public class DatasetDataManage {
|
||||
LinkedHashMap<String, Object> obj = new LinkedHashMap<>();
|
||||
if (row.length > 0) {
|
||||
for (int j = 0; j < fields.size(); j++) {
|
||||
String res = row[j];
|
||||
// 如果字段类型是数值类型的小数,则去除科学计数
|
||||
if (fields.get(j).getDeType() == 3 && StringUtils.containsIgnoreCase(res, "E")) {
|
||||
BigDecimal bigDecimal = new BigDecimal(res);
|
||||
res = String.format("%.8f", bigDecimal);
|
||||
}
|
||||
if (desensitizationList.keySet().contains(fields.get(j).getDataeaseName())) {
|
||||
obj.put(fields.get(j).getDataeaseName(), ChartDataBuild.desensitizationValue(desensitizationList.get(fields.get(j).getDataeaseName()), String.valueOf(row[j])));
|
||||
obj.put(fields.get(j).getDataeaseName(), ChartDataBuild.desensitizationValue(desensitizationList.get(fields.get(j).getDataeaseName()), String.valueOf(res)));
|
||||
} else {
|
||||
obj.put(ObjectUtils.isNotEmpty(fields.get(j).getDataeaseName()) ?
|
||||
fields.get(j).getDataeaseName() : fields.get(j).getOriginName(), row[j]);
|
||||
fields.get(j).getDataeaseName() : fields.get(j).getOriginName(), res);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -561,14 +572,20 @@ public class DatasetDataManage {
|
||||
provider = ProviderFactory.getProvider(dsList.getFirst());
|
||||
}
|
||||
|
||||
String dsType = null;
|
||||
if (dsMap != null && dsMap.entrySet().iterator().hasNext()) {
|
||||
Map.Entry<Long, DatasourceSchemaDTO> next = dsMap.entrySet().iterator().next();
|
||||
dsType = next.getValue().getType();
|
||||
}
|
||||
|
||||
Field2SQLObj.field2sqlObj(sqlMeta, fields, allFields, crossDs, dsMap, Utils.getParams(allFields), null, pluginManage);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, allFields, crossDs, dsMap, Utils.getParams(allFields), null, pluginManage);
|
||||
Order2SQLObj.getOrders(sqlMeta, datasetGroupInfoDTO.getSortFields(), allFields, crossDs, dsMap, Utils.getParams(allFields), null, pluginManage);
|
||||
String querySQL;
|
||||
if (multFieldValuesRequest.getResultMode() == 0) {
|
||||
querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, true, 0, 1000);
|
||||
querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, !StringUtils.equalsIgnoreCase(dsType, "es"), 0, 1000);
|
||||
} else {
|
||||
querySQL = SQLProvider.createQuerySQL(sqlMeta, false, needOrder, true);
|
||||
querySQL = SQLProvider.createQuerySQL(sqlMeta, false, needOrder, !StringUtils.equalsIgnoreCase(dsType, "es"));
|
||||
}
|
||||
querySQL = provider.rebuildSQL(querySQL, sqlMeta, crossDs, dsMap);
|
||||
logger.debug("calcite data enum sql: " + querySQL);
|
||||
@ -808,15 +825,21 @@ public class DatasetDataManage {
|
||||
provider = ProviderFactory.getProvider(dsList.getFirst());
|
||||
}
|
||||
|
||||
String dsType = null;
|
||||
if (dsMap != null && dsMap.entrySet().iterator().hasNext()) {
|
||||
Map.Entry<Long, DatasourceSchemaDTO> next = dsMap.entrySet().iterator().next();
|
||||
dsType = next.getValue().getType();
|
||||
}
|
||||
|
||||
Field2SQLObj.field2sqlObj(sqlMeta, fields, allFields, crossDs, dsMap, Utils.getParams(allFields), null, pluginManage);
|
||||
ExtWhere2Str.extWhere2sqlOjb(sqlMeta, extFilterList, allFields, crossDs, dsMap, Utils.getParams(allFields), null, pluginManage);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, allFields, crossDs, dsMap, Utils.getParams(allFields), null, pluginManage);
|
||||
Order2SQLObj.getOrders(sqlMeta, datasetGroupInfoDTO.getSortFields(), allFields, crossDs, dsMap, Utils.getParams(allFields), null, pluginManage);
|
||||
String querySQL;
|
||||
if (request.getResultMode() == 0) {
|
||||
querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, sortDistinct && ids.size() == 1, 0, 1000);
|
||||
querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, sortDistinct && ids.size() == 1 && !StringUtils.equalsIgnoreCase(dsType, "es"), 0, 1000);
|
||||
} else {
|
||||
querySQL = SQLProvider.createQuerySQL(sqlMeta, false, needOrder, sortDistinct && ids.size() == 1);
|
||||
querySQL = SQLProvider.createQuerySQL(sqlMeta, false, needOrder, sortDistinct && ids.size() == 1 && !StringUtils.equalsIgnoreCase(dsType, "es"));
|
||||
}
|
||||
querySQL = provider.rebuildSQL(querySQL, sqlMeta, crossDs, dsMap);
|
||||
logger.debug("calcite data enum sql: " + querySQL);
|
||||
|
||||
@ -262,6 +262,9 @@ public class DatasetGroupManage {
|
||||
List<CoreDatasetTable> coreDatasetTables = coreDatasetTableMapper.selectList(wrapper);
|
||||
Set<Long> ids = new LinkedHashSet();
|
||||
coreDatasetTables.forEach(ele -> ids.add(ele.getDatasourceId()));
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
DEException.throwException("数据集因异常导致无法使用,请重新创建");
|
||||
}
|
||||
|
||||
QueryWrapper<CoreDatasource> datasourceQueryWrapper = new QueryWrapper<>();
|
||||
datasourceQueryWrapper.in("id", ids);
|
||||
@ -559,6 +562,9 @@ public class DatasetGroupManage {
|
||||
return;
|
||||
}
|
||||
fullName.add(parent.getName());
|
||||
if (parent.getId().equals(parent.getPid())) {
|
||||
return;
|
||||
}
|
||||
if (parent.getPid() != null && parent.getPid() != 0) {
|
||||
geFullName(parent.getPid(), fullName);
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ public class DatasetSQLManage {
|
||||
if (CollectionUtils.isEmpty(filterDTO.getValue())) {
|
||||
continue;
|
||||
}
|
||||
filterParametersAdaptor(parameters,filterDTO,datasetTableId);
|
||||
filterParametersAdaptor(parameters, filterDTO, datasetTableId);
|
||||
}
|
||||
}
|
||||
if (chartExtRequest != null && ObjectUtils.isNotEmpty(chartExtRequest.getFilter())) {
|
||||
@ -79,13 +79,13 @@ public class DatasetSQLManage {
|
||||
if (CollectionUtils.isEmpty(filterDTO.getValue())) {
|
||||
continue;
|
||||
}
|
||||
filterParametersAdaptor(parameters,filterDTO,datasetTableId);
|
||||
filterParametersAdaptor(parameters, filterDTO, datasetTableId);
|
||||
}
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
private void filterParametersAdaptor(List<SqlVariableDetails> parameters,ChartExtFilterDTO filterDTO,Long datasetTableId){
|
||||
private void filterParametersAdaptor(List<SqlVariableDetails> parameters, ChartExtFilterDTO filterDTO, Long datasetTableId) {
|
||||
if (ObjectUtils.isNotEmpty(filterDTO.getParameters())) {
|
||||
for (SqlVariableDetails parameter : filterDTO.getParameters()) {
|
||||
if (parameter.getDatasetTableId().equals(datasetTableId)) {
|
||||
@ -152,17 +152,22 @@ public class DatasetSQLManage {
|
||||
f.setDatasetTableId(datasetTable.getId());
|
||||
String prefix = "";
|
||||
String suffix = "";
|
||||
|
||||
DsTypeDTO datasourceType = getDatasourceType(dsMap, datasetTable.getDatasourceId());
|
||||
if (Objects.equals(f.getExtField(), ExtFieldConstant.EXT_NORMAL)) {
|
||||
if (isCross) {
|
||||
prefix = "`";
|
||||
suffix = "`";
|
||||
} else {
|
||||
DsTypeDTO datasourceType = getDatasourceType(dsMap, datasetTable.getDatasourceId());
|
||||
prefix = datasourceType.getPrefix();
|
||||
suffix = datasourceType.getSuffix();
|
||||
}
|
||||
}
|
||||
return table.getTableAlias() + "." + prefix + f.getOriginName() + suffix + " AS " + prefix + alias + suffix;
|
||||
if (StringUtils.equalsIgnoreCase(datasourceType.getType(), "es")) {
|
||||
return table.getTableAlias() + "." + prefix + f.getOriginName() + suffix;
|
||||
} else {
|
||||
return table.getTableAlias() + "." + prefix + f.getOriginName() + suffix + " AS " + prefix + alias + suffix;
|
||||
}
|
||||
})
|
||||
.toArray(String[]::new);
|
||||
checkedInfo.put(table.getTableAlias(), array);
|
||||
@ -488,6 +493,15 @@ public class DatasetSQLManage {
|
||||
schemaAlias = String.format(SQLConstants.SCHEMA, coreDatasource.getId());
|
||||
}
|
||||
|
||||
if (!dsMap.containsKey(coreDatasource.getId())) {
|
||||
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
|
||||
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
|
||||
datasourceSchemaDTO.setSchemaAlias(schemaAlias);
|
||||
dsMap.put(coreDatasource.getId(), datasourceSchemaDTO);
|
||||
}
|
||||
} else if (StringUtils.equalsIgnoreCase(ds.getType(), DatasetTableType.Es)) {
|
||||
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(ds.getDatasourceId());
|
||||
schemaAlias = String.format(SQLConstants.SCHEMA, coreDatasource.getId());
|
||||
if (!dsMap.containsKey(coreDatasource.getId())) {
|
||||
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
|
||||
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
package io.dataease.datasource.dto.es;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class EsResponse {
|
||||
private List<Column> columns = new ArrayList<>();
|
||||
private List<String[]> rows = new ArrayList<>();
|
||||
private String cursor;
|
||||
private Integer status;
|
||||
private Error error;
|
||||
private String version;
|
||||
|
||||
@Data
|
||||
public class Error {
|
||||
private String type;
|
||||
private String reason;
|
||||
}
|
||||
|
||||
@Data
|
||||
public class Column {
|
||||
private String name;
|
||||
private String type;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package io.dataease.datasource.dto.es;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Request {
|
||||
private String query;
|
||||
private Integer fetch_size = 10000;
|
||||
private boolean field_multi_value_leniency = true;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package io.dataease.datasource.dto.es;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RequestWithCursor extends Request {
|
||||
private String cursor;
|
||||
}
|
||||
@ -269,7 +269,7 @@ public class CalciteProvider extends Provider {
|
||||
try (Connection con = getConnectionFromPool(datasourceRequest.getDatasource().getId()); Statement statement = getStatement(con, 30)) {
|
||||
datasourceRequest.setDsVersion(con.getMetaData().getDatabaseMajorVersion());
|
||||
if (datasourceRequest.getDatasource().getType().equalsIgnoreCase("mongo") || isDorisCatalog(datasourceRequest)) {
|
||||
resultSet = statement.executeQuery("select * from " + table + " limit 0 offset 0 ");
|
||||
resultSet = statement.executeQuery("select * from " + String.format(" `%s`", table) + " limit 0 offset 0 ");
|
||||
return fetchResultField(resultSet);
|
||||
}
|
||||
resultSet = statement.executeQuery(getTableFiledSql(datasourceRequest));
|
||||
@ -777,135 +777,176 @@ public class CalciteProvider extends Provider {
|
||||
case StarRocks:
|
||||
case doris:
|
||||
configuration = JsonUtil.parseObject(ds.getConfiguration(), Mysql.class);
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
}
|
||||
dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout()));
|
||||
dataSource.setInitialSize(configuration.getInitialPoolSize());
|
||||
dataSource.setMaxTotal(configuration.getMaxPoolSize());
|
||||
dataSource.setMinIdle(configuration.getMinPoolSize());
|
||||
startSshSession(configuration, null, ds.getId());
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getDataBase());
|
||||
rootSchema.add(ds.getSchemaAlias(), schema);
|
||||
break;
|
||||
case impala:
|
||||
configuration = JsonUtil.parseObject(ds.getConfiguration(), Impala.class);
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
}
|
||||
dataSource.setInitialSize(configuration.getInitialPoolSize());
|
||||
dataSource.setMaxTotal(configuration.getMaxPoolSize());
|
||||
dataSource.setMinIdle(configuration.getMinPoolSize());
|
||||
dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout()));
|
||||
startSshSession(configuration, null, ds.getId());
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getDataBase());
|
||||
rootSchema.add(ds.getSchemaAlias(), schema);
|
||||
break;
|
||||
case sqlServer:
|
||||
configuration = JsonUtil.parseObject(ds.getConfiguration(), Sqlserver.class);
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
}
|
||||
dataSource.setInitialSize(configuration.getInitialPoolSize());
|
||||
dataSource.setMaxTotal(configuration.getMaxPoolSize());
|
||||
dataSource.setMinIdle(configuration.getMinPoolSize());
|
||||
dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout()));
|
||||
startSshSession(configuration, null, ds.getId());
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getSchema());
|
||||
rootSchema.add(ds.getSchemaAlias(), schema);
|
||||
break;
|
||||
case oracle:
|
||||
configuration = JsonUtil.parseObject(ds.getConfiguration(), Oracle.class);
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
}
|
||||
dataSource.setInitialSize(configuration.getInitialPoolSize());
|
||||
dataSource.setMaxTotal(configuration.getMaxPoolSize());
|
||||
dataSource.setMinIdle(configuration.getMinPoolSize());
|
||||
dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout()));
|
||||
startSshSession(configuration, null, ds.getId());
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getSchema());
|
||||
rootSchema.add(ds.getSchemaAlias(), schema);
|
||||
break;
|
||||
case db2:
|
||||
configuration = JsonUtil.parseObject(ds.getConfiguration(), Db2.class);
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
}
|
||||
dataSource.setInitialSize(configuration.getInitialPoolSize());
|
||||
dataSource.setMaxTotal(configuration.getMaxPoolSize());
|
||||
dataSource.setMinIdle(configuration.getMinPoolSize());
|
||||
dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout()));
|
||||
startSshSession(configuration, null, ds.getId());
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getSchema());
|
||||
rootSchema.add(ds.getSchemaAlias(), schema);
|
||||
break;
|
||||
case ck:
|
||||
configuration = JsonUtil.parseObject(ds.getConfiguration(), CK.class);
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
}
|
||||
dataSource.setInitialSize(configuration.getInitialPoolSize());
|
||||
dataSource.setMaxTotal(configuration.getMaxPoolSize());
|
||||
dataSource.setMinIdle(configuration.getMinPoolSize());
|
||||
dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout()));
|
||||
startSshSession(configuration, null, ds.getId());
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getDataBase());
|
||||
rootSchema.add(ds.getSchemaAlias(), schema);
|
||||
break;
|
||||
case pg:
|
||||
configuration = JsonUtil.parseObject(ds.getConfiguration(), Pg.class);
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
}
|
||||
dataSource.setInitialSize(configuration.getInitialPoolSize());
|
||||
dataSource.setMaxTotal(configuration.getMaxPoolSize());
|
||||
dataSource.setMinIdle(configuration.getMinPoolSize());
|
||||
dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout()));
|
||||
startSshSession(configuration, null, ds.getId());
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getSchema());
|
||||
rootSchema.add(ds.getSchemaAlias(), schema);
|
||||
break;
|
||||
case redshift:
|
||||
configuration = JsonUtil.parseObject(ds.getConfiguration(), Redshift.class);
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
}
|
||||
dataSource.setInitialSize(configuration.getInitialPoolSize());
|
||||
dataSource.setMaxTotal(configuration.getMaxPoolSize());
|
||||
dataSource.setMinIdle(configuration.getMinPoolSize());
|
||||
dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout()));
|
||||
startSshSession(configuration, null, ds.getId());
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getSchema());
|
||||
rootSchema.add(ds.getSchemaAlias(), schema);
|
||||
break;
|
||||
case h2:
|
||||
configuration = JsonUtil.parseObject(ds.getConfiguration(), H2.class);
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
}
|
||||
dataSource.setInitialSize(configuration.getInitialPoolSize());
|
||||
dataSource.setMaxTotal(configuration.getMaxPoolSize());
|
||||
dataSource.setMinIdle(configuration.getMinPoolSize());
|
||||
dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout()));
|
||||
startSshSession(configuration, null, ds.getId());
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getDataBase());
|
||||
rootSchema.add(ds.getSchemaAlias(), schema);
|
||||
break;
|
||||
default:
|
||||
configuration = JsonUtil.parseObject(ds.getConfiguration(), Mysql.class);
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||
dataSource.setUsername(configuration.getUsername());
|
||||
}
|
||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||
dataSource.setPassword(configuration.getPassword());
|
||||
}
|
||||
dataSource.setInitialSize(configuration.getInitialPoolSize());
|
||||
dataSource.setMaxTotal(configuration.getMaxPoolSize());
|
||||
dataSource.setMinIdle(configuration.getMinPoolSize());
|
||||
dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout()));
|
||||
startSshSession(configuration, null, ds.getId());
|
||||
dataSource.setUrl(configuration.getJdbc());
|
||||
schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getDataBase());
|
||||
rootSchema.add(ds.getSchemaAlias(), schema);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("Fail to create connection: " + ds.getName(), e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
@ -1345,13 +1386,21 @@ public class CalciteProvider extends Provider {
|
||||
return connection;
|
||||
}
|
||||
|
||||
private Connection getConnectionFromPool(Long dsId) throws SQLException {
|
||||
Connection connection = take();
|
||||
CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
|
||||
SchemaPlus rootSchema = calciteConnection.getRootSchema();
|
||||
JdbcSchema jdbcSchema = rootSchema.getSubSchema(String.format(SQLConstants.SCHEMA, dsId)).unwrap(JdbcSchema.class);
|
||||
BasicDataSource basicDataSource = (BasicDataSource) jdbcSchema.getDataSource();
|
||||
return basicDataSource.getConnection();
|
||||
private Connection getConnectionFromPool(Long dsId) {
|
||||
try {
|
||||
Connection connection = take();
|
||||
CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
|
||||
SchemaPlus rootSchema = calciteConnection.getRootSchema();
|
||||
if (rootSchema.getSubSchema(String.format(SQLConstants.SCHEMA, dsId)) == null) {
|
||||
DEException.throwException("请检查数据源的有效性!");
|
||||
}
|
||||
JdbcSchema jdbcSchema = rootSchema.getSubSchema(String.format(SQLConstants.SCHEMA, dsId)).unwrap(JdbcSchema.class);
|
||||
BasicDataSource basicDataSource = (BasicDataSource) jdbcSchema.getDataSource();
|
||||
return basicDataSource.getConnection();
|
||||
} catch (Exception e) {
|
||||
DEException.throwException("连接无效, " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void exec(EngineRequest engineRequest) throws Exception {
|
||||
|
||||
@ -0,0 +1,217 @@
|
||||
package io.dataease.datasource.provider;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import io.dataease.dataset.utils.FieldUtils;
|
||||
import io.dataease.datasource.dto.es.EsResponse;
|
||||
import io.dataease.datasource.dto.es.Request;
|
||||
import io.dataease.datasource.type.Es;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.extensions.datasource.dto.*;
|
||||
import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.i18n.Translator;
|
||||
|
||||
import io.dataease.utils.HttpClientConfig;
|
||||
import io.dataease.utils.HttpClientUtil;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service("esProvider")
|
||||
public class EsProvider extends Provider {
|
||||
|
||||
@Override
|
||||
public List<String> getSchema(DatasourceRequest datasourceRequest) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasetTableDTO> getTables(DatasourceRequest datasourceRequest) {
|
||||
List<DatasetTableDTO> tables = new ArrayList<>();
|
||||
try {
|
||||
String response = execQuery(datasourceRequest, "show tables", "?format=json");
|
||||
tables = fetchTables(response);
|
||||
tables = tables.stream().filter(table -> StringUtils.isNotEmpty(table.getTableName()) && !table.getTableName().startsWith(".")).collect(Collectors.toList());
|
||||
tables.forEach(table -> {
|
||||
table.setDatasourceId(datasourceRequest.getDatasource().getId());
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.getMessage();
|
||||
DEException.throwException(e);
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionObj getConnection(DatasourceDTO coreDatasource) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String checkStatus(DatasourceRequest datasourceRequest) throws Exception {
|
||||
Es es = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), Es.class);
|
||||
String response = execGetQuery(datasourceRequest);
|
||||
if (JsonParser.parseString(response).getAsJsonObject().getAsJsonObject("error") != null) {
|
||||
throw new Exception(JsonParser.parseString(response).getAsJsonObject().getAsJsonObject("error").get("reason").getAsString());
|
||||
}
|
||||
String version = JsonParser.parseString(response).getAsJsonObject().getAsJsonObject("version").get("number").getAsString();
|
||||
String[] versionList = version.split("\\.");
|
||||
if (Integer.valueOf(versionList[0]) < 7 && Integer.valueOf(versionList[1]) < 3) {
|
||||
throw new Exception(Translator.get("i18n_es_limit"));
|
||||
}
|
||||
if (Integer.valueOf(versionList[0]) == 6) {
|
||||
es.setUri("_xpack/sql");
|
||||
}
|
||||
if (Integer.valueOf(versionList[0]) > 6) {
|
||||
es.setUri("_sql");
|
||||
}
|
||||
datasourceRequest.getDatasource().setConfiguration(JsonUtil.toJSONString(es).toString());
|
||||
getTables(datasourceRequest);
|
||||
return "Success";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> fetchResultField(DatasourceRequest datasourceRequest) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
String response = execQuery(datasourceRequest, datasourceRequest.getQuery(), "?format=json");
|
||||
result.put("data", fetchResultData(response));
|
||||
result.put("fields", fetchResultField4Sql(response));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
DEException.throwException(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TableField> fetchTableField(DatasourceRequest datasourceRequest) {
|
||||
List<TableField> tableFields = new ArrayList<>();
|
||||
try {
|
||||
String sql;
|
||||
if (datasourceRequest.getTable() != null) {
|
||||
sql = "select * from " + datasourceRequest.getTable() + " limit 0";
|
||||
} else {
|
||||
sql = datasourceRequest.getQuery();
|
||||
}
|
||||
String response = execQuery(datasourceRequest, sql, "?format=json");
|
||||
tableFields = fetchResultField4Sql(response);
|
||||
} catch (Exception e) {
|
||||
DEException.throwException(e);
|
||||
}
|
||||
return tableFields;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void hidePW(DatasourceDTO datasourceDTO) {
|
||||
}
|
||||
|
||||
|
||||
private List<String[]> fetchResultData(String response) throws Exception {
|
||||
EsResponse esResponse = new Gson().fromJson(response, EsResponse.class);
|
||||
return fetchResultData(esResponse);
|
||||
}
|
||||
|
||||
private List<String[]> fetchResultData(EsResponse esResponse) throws Exception {
|
||||
List<String[]> list = new LinkedList<>();
|
||||
if (esResponse.getError() != null) {
|
||||
throw new Exception(esResponse.getError().getReason());
|
||||
}
|
||||
list.addAll(esResponse.getRows());
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<TableField> fetchResultField4Sql(String response) throws Exception {
|
||||
List<TableField> fieldList = new ArrayList<>();
|
||||
EsResponse esResponse = new Gson().fromJson(response, EsResponse.class);
|
||||
if (esResponse.getError() != null) {
|
||||
throw new Exception(esResponse.getError().getReason());
|
||||
}
|
||||
|
||||
for (EsResponse.Column column : esResponse.getColumns()) {
|
||||
TableField field = new TableField();
|
||||
field.setOriginName(column.getName());
|
||||
field.setOriginName(column.getName());
|
||||
field.setFieldType(column.getType());
|
||||
field.setType(column.getType().toUpperCase());
|
||||
field.setFieldType(field.getType());
|
||||
int deType = FieldUtils.transType2DeType(field.getType());
|
||||
field.setDeExtractType(deType);
|
||||
field.setDeType(deType);
|
||||
fieldList.add(field);
|
||||
}
|
||||
return fieldList;
|
||||
}
|
||||
|
||||
private List<DatasetTableDTO> fetchTables(String response) throws Exception {
|
||||
List<DatasetTableDTO> tables = new ArrayList<>();
|
||||
EsResponse esResponse = new Gson().fromJson(response, EsResponse.class);
|
||||
if (esResponse.getError() != null) {
|
||||
throw new Exception(esResponse.getError().getReason());
|
||||
}
|
||||
|
||||
for (String[] row : esResponse.getRows()) {
|
||||
|
||||
DatasetTableDTO tableDesc = new DatasetTableDTO();
|
||||
if (row.length == 3 && row[1].contains("TABLE") && row[2].equalsIgnoreCase("INDEX")) {
|
||||
tableDesc.setTableName(row[0]);
|
||||
}
|
||||
if (row.length == 2 && row[1].contains("TABLE")) {
|
||||
tableDesc.setTableName(row[0]);
|
||||
}
|
||||
if (row.length == 4 && row[2].contains("TABLE") && row[3].equalsIgnoreCase("INDEX")) {
|
||||
tableDesc.setTableName(row[1]);
|
||||
}
|
||||
tableDesc.setType("es");
|
||||
tables.add(tableDesc);
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
|
||||
|
||||
private String execQuery(DatasourceRequest datasourceRequest, String sql, String uri) {
|
||||
Es es = null;
|
||||
if (datasourceRequest.getDatasource() == null) {
|
||||
Collection<DatasourceSchemaDTO> datasourceSchemaDTOS = datasourceRequest.getDsList().values();
|
||||
es = JsonUtil.parseObject(datasourceSchemaDTOS.stream().findFirst().get().getConfiguration(), Es.class);
|
||||
} else {
|
||||
es = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), Es.class);
|
||||
}
|
||||
|
||||
uri = es.getUri() + uri;
|
||||
HttpClientConfig httpClientConfig = new HttpClientConfig();
|
||||
if (StringUtils.isNotEmpty(es.getUsername()) && StringUtils.isNotEmpty(es.getPassword())) {
|
||||
String auth = es.getUsername() + ":" + es.getPassword();
|
||||
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8));
|
||||
httpClientConfig.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + new String(encodedAuth));
|
||||
}
|
||||
Request request = new Request();
|
||||
request.setQuery(sql);
|
||||
request.setFetch_size(datasourceRequest.getFetchSize());
|
||||
String url = es.getUrl().endsWith("/") ? es.getUrl() + uri : es.getUrl() + "/" + uri;
|
||||
return HttpClientUtil.post(url, new Gson().toJson(request), httpClientConfig);
|
||||
|
||||
}
|
||||
|
||||
private String execGetQuery(DatasourceRequest datasourceRequest) {
|
||||
Es es = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), Es.class);
|
||||
HttpClientConfig httpClientConfig = new HttpClientConfig();
|
||||
if (StringUtils.isNotEmpty(es.getUsername()) && StringUtils.isNotEmpty(es.getPassword())) {
|
||||
String auth = es.getUsername() + ":" + es.getPassword();
|
||||
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8));
|
||||
httpClientConfig.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + new String(encodedAuth));
|
||||
}
|
||||
return HttpClientUtil.get(es.getUrl(), httpClientConfig);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -15,6 +15,7 @@ import io.dataease.api.ds.vo.ExcelSheetData;
|
||||
import io.dataease.datasource.dao.auto.entity.CoreDatasource;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableDTO;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceDTO;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceRequest;
|
||||
import io.dataease.extensions.datasource.dto.TableField;
|
||||
import io.dataease.utils.AuthUtils;
|
||||
@ -40,6 +41,21 @@ public class ExcelUtils {
|
||||
private static TypeReference<List<TableField>> TableFieldListTypeReference = new TypeReference<List<TableField>>() {
|
||||
};
|
||||
|
||||
private static TypeReference<List<ExcelSheetData>> sheets = new TypeReference<List<ExcelSheetData>>() {
|
||||
};
|
||||
|
||||
public static void mergeSheets(CoreDatasource requestDatasource, DatasourceDTO sourceData) {
|
||||
List<ExcelSheetData> newSheets = JsonUtil.parseList(requestDatasource.getConfiguration(), sheets);
|
||||
List<String> tableNames = newSheets.stream().map(ExcelSheetData::getDeTableName).collect(Collectors.toList());
|
||||
List<ExcelSheetData> oldSheets = JsonUtil.parseList(sourceData.getConfiguration(), sheets);
|
||||
for (ExcelSheetData oldSheet : oldSheets) {
|
||||
if (!tableNames.contains(oldSheet.getDeTableName())) {
|
||||
newSheets.add(oldSheet);
|
||||
}
|
||||
}
|
||||
requestDatasource.setConfiguration(JsonUtil.toJSONString(newSheets).toString());
|
||||
}
|
||||
|
||||
public static List<DatasetTableDTO> getTables(DatasourceRequest datasourceRequest) throws DEException {
|
||||
List<DatasetTableDTO> tableDescs = new ArrayList<>();
|
||||
try {
|
||||
@ -311,7 +327,7 @@ public class ExcelUtils {
|
||||
if (StringUtils.isEmpty(value) || value.length() > 19) {
|
||||
return "TEXT";
|
||||
}
|
||||
String regex = "^\\d+(\\.\\d+)?$";
|
||||
String regex = "^-?\\d+(\\.\\d+)?$";
|
||||
if (!value.matches(regex)) {
|
||||
return "TEXT";
|
||||
}
|
||||
|
||||
@ -84,15 +84,10 @@ public class H2EngineProvider extends EngineProvider {
|
||||
int size = tableField.getPrecision() * 4;
|
||||
switch (tableField.getDeType()) {
|
||||
case 0:
|
||||
Column_Fields.append("longtext").append(",`");
|
||||
Column_Fields.append("varchar(2048)").append(",`");
|
||||
break;
|
||||
case 1:
|
||||
size = size < 50 ? 50 : size;
|
||||
if (size < 65533) {
|
||||
Column_Fields.append("varchar(length)".replace("length", String.valueOf(tableField.getPrecision()))).append(",`");
|
||||
} else {
|
||||
Column_Fields.append("longtext").append(",`");
|
||||
}
|
||||
Column_Fields.append("varchar(2048)").append(",`");
|
||||
break;
|
||||
case 2:
|
||||
Column_Fields.append("bigint(20)").append(",`");
|
||||
@ -104,11 +99,7 @@ public class H2EngineProvider extends EngineProvider {
|
||||
Column_Fields.append("TINYINT(length)".replace("length", String.valueOf(tableField.getPrecision()))).append(",`");
|
||||
break;
|
||||
default:
|
||||
if (size < 65533) {
|
||||
Column_Fields.append("varchar(length)".replace("length", String.valueOf(tableField.getPrecision()))).append(",`");
|
||||
} else {
|
||||
Column_Fields.append("longtext").append(",`");
|
||||
}
|
||||
Column_Fields.append("varchar(2048)").append(",`");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ public class MysqlEngineProvider extends EngineProvider {
|
||||
int size = tableField.getPrecision() * 4;
|
||||
switch (tableField.getDeExtractType()) {
|
||||
case 0:
|
||||
Column_Fields.append("longtext").append(",`");
|
||||
Column_Fields.append("varchar(1024)").append(",`");
|
||||
break;
|
||||
case 1:
|
||||
Column_Fields.append("datetime").append(",`");
|
||||
@ -104,7 +104,7 @@ public class MysqlEngineProvider extends EngineProvider {
|
||||
Column_Fields.append("TINYINT(length)".replace("length", String.valueOf(tableField.getPrecision()))).append(",`");
|
||||
break;
|
||||
default:
|
||||
Column_Fields.append("longtext").append(",`");
|
||||
Column_Fields.append("varchar(1024)").append(",`");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ public class DatasourceServer implements DatasourceApi {
|
||||
}
|
||||
|
||||
public boolean checkRepeat(@RequestBody BusiDsRequest dataSourceDTO) {
|
||||
if (Arrays.asList("API", "Excel", "folder").contains(dataSourceDTO.getType())) {
|
||||
if (Arrays.asList("API", "Excel", "folder", "es").contains(dataSourceDTO.getType())) {
|
||||
return false;
|
||||
}
|
||||
BusiNodeRequest request = new BusiNodeRequest();
|
||||
@ -267,7 +267,11 @@ public class DatasourceServer implements DatasourceApi {
|
||||
try {
|
||||
datasourceSyncManage.createEngineTable(datasourceRequest.getTable(), tableFields);
|
||||
} catch (Exception e) {
|
||||
DEException.throwException("Failed to create table " + datasourceRequest.getTable() + ", " + e.getMessage());
|
||||
if (e.getMessage().toLowerCase().contains("Row size too large".toLowerCase())) {
|
||||
DEException.throwException("文本内容超出最大支持范围: " + datasourceRequest.getTable() + ", " + e.getMessage());
|
||||
} else {
|
||||
DEException.throwException("Failed to create table " + datasourceRequest.getTable() + ", " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
commonThreadPool.addTask(() -> {
|
||||
@ -404,7 +408,7 @@ public class DatasourceServer implements DatasourceApi {
|
||||
List<String> tables = ExcelUtils.getTables(datasourceRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList());
|
||||
if (dataSourceDTO.getEditType() == 0) {
|
||||
toCreateTables = tables;
|
||||
toDeleteTables = sourceTables;
|
||||
toDeleteTables = sourceTables.stream().filter(s -> tables.contains(s)).collect(Collectors.toList());
|
||||
for (String deleteTable : toDeleteTables) {
|
||||
try {
|
||||
datasourceSyncManage.dropEngineTable(deleteTable);
|
||||
@ -422,6 +426,7 @@ public class DatasourceServer implements DatasourceApi {
|
||||
}
|
||||
datasourceSyncManage.extractExcelData(requestDatasource, "all_scope");
|
||||
dataSourceManage.checkName(dataSourceDTO);
|
||||
ExcelUtils.mergeSheets(requestDatasource, sourceData);
|
||||
dataSourceManage.innerEdit(requestDatasource);
|
||||
} else {
|
||||
datasourceSyncManage.extractExcelData(requestDatasource, "add_scope");
|
||||
@ -488,6 +493,15 @@ public class DatasourceServer implements DatasourceApi {
|
||||
return getDatasourceDTOById(datasourceId, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(Long datasourceId) throws DEException {
|
||||
CoreDatasource datasource = datasourceMapper.selectById(datasourceId);
|
||||
if (datasource == null) {
|
||||
DEException.throwException("不存在的数据源!");
|
||||
}
|
||||
return datasource.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasourceDTO> innerList(List<Long> ids, List<String> types) throws DEException {
|
||||
List<DatasourceDTO> list = new ArrayList<>();
|
||||
@ -726,11 +740,15 @@ public class DatasourceServer implements DatasourceApi {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Integer replace = 0;
|
||||
private static final Integer append = 1;
|
||||
|
||||
public ExcelFileData excelUpload(@RequestParam("file") MultipartFile file, @RequestParam("id") long datasourceId, @RequestParam("editType") Integer editType) throws DEException {
|
||||
CoreDatasource coreDatasource = datasourceMapper.selectById(datasourceId);
|
||||
|
||||
ExcelUtils excelUtils = new ExcelUtils();
|
||||
ExcelFileData excelFileData = excelUtils.excelSaveAndParse(file);
|
||||
if (editType == 1 || editType == 0) { //按照excel sheet 名称匹配
|
||||
CoreDatasource coreDatasource = datasourceMapper.selectById(datasourceId);
|
||||
if (Objects.equals(editType, append)) { //按照excel sheet 名称匹配,替换:0;追加:1
|
||||
if (coreDatasource != null) {
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setDatasource(transDTO(coreDatasource));
|
||||
@ -748,7 +766,6 @@ public class DatasourceServer implements DatasourceApi {
|
||||
oldTableFields.sort((o1, o2) -> {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
});
|
||||
|
||||
if (isEqual(newTableFields, oldTableFields)) {
|
||||
sheet.setDeTableName(datasetTableDTO.getTableName());
|
||||
excelSheetDataList.add(sheet);
|
||||
@ -761,8 +778,21 @@ public class DatasourceServer implements DatasourceApi {
|
||||
}
|
||||
excelFileData.setSheets(excelSheetDataList);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (coreDatasource != null) {
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setDatasource(transDTO(coreDatasource));
|
||||
List<DatasetTableDTO> datasetTableDTOS = ExcelUtils.getTables(datasourceRequest);
|
||||
for (ExcelSheetData sheet : excelFileData.getSheets()) {
|
||||
for (DatasetTableDTO datasetTableDTO : datasetTableDTOS) {
|
||||
if (excelDataTableName(datasetTableDTO.getTableName()).equals(sheet.getTableName()) || isCsv(file.getOriginalFilename())) {
|
||||
sheet.setDeTableName(datasetTableDTO.getTableName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
for (ExcelSheetData sheet : excelFileData.getSheets()) {
|
||||
for (int i = 0; i < sheet.getFields().size() - 1; i++) {
|
||||
for (int j = i + 1; j < sheet.getFields().size(); j++) {
|
||||
@ -1146,8 +1176,11 @@ public class DatasourceServer implements DatasourceApi {
|
||||
if (!Arrays.asList("API", "Excel", "folder").contains(coreDatasource.getType())) {
|
||||
calciteProvider.updateDsPoolAfterCheckStatus(datasourceDTO);
|
||||
}
|
||||
} catch (DEException e) {
|
||||
datasourceDTO.setStatus("Error");
|
||||
DEException.throwException(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
coreDatasource.setStatus("Error");
|
||||
datasourceDTO.setStatus("Error");
|
||||
DEException.throwException(e.getMessage());
|
||||
} finally {
|
||||
coreDatasource.setStatus(datasourceDTO.getStatus());
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package io.dataease.datasource.type;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
public class Es {
|
||||
private String url;
|
||||
private String username;
|
||||
private String password;
|
||||
private String version;
|
||||
private String uri;
|
||||
|
||||
}
|
||||
@ -71,6 +71,8 @@ public class SQLConstants {
|
||||
|
||||
public static final String WHERE_VALUE_VALUE = "'%s'";
|
||||
|
||||
public static final String WHERE_VALUE_VALUE_CH = "'-DENS-%s'";
|
||||
|
||||
public static final String WHERE_NUMBER_VALUE = "%s";
|
||||
|
||||
public static final String AGG_COUNT = "COUNT(*)";
|
||||
@ -96,4 +98,6 @@ public class SQLConstants {
|
||||
public static final String EMPTY_SIGN = "_empty_$";
|
||||
|
||||
public static final String CONCAT = "CONCAT(%s, %s)";
|
||||
|
||||
public static final String MSSQL_N_PREFIX = "-DENS-";
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author Junjun
|
||||
@ -77,6 +78,13 @@ public class CustomWhere2Str {
|
||||
if (ObjectUtils.isEmpty(field)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String dsType = null;
|
||||
if (dsMap != null && dsMap.entrySet().iterator().hasNext()) {
|
||||
Map.Entry<Long, DatasourceSchemaDTO> next = dsMap.entrySet().iterator().next();
|
||||
dsType = next.getValue().getType();
|
||||
}
|
||||
|
||||
Map<String, String> paramMap = Utils.mergeParam(fieldParam, chartParam);
|
||||
String whereName = "";
|
||||
String originName;
|
||||
@ -90,9 +98,17 @@ public class CustomWhere2Str {
|
||||
originName = calcFieldExp;
|
||||
}
|
||||
} else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getOriginName());
|
||||
} else {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
}
|
||||
} else {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getOriginName());
|
||||
} else {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
}
|
||||
}
|
||||
if (field.getDeType() == 1) {
|
||||
if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) {
|
||||
@ -114,7 +130,14 @@ public class CustomWhere2Str {
|
||||
}
|
||||
}
|
||||
// 此处获取标准格式的日期
|
||||
whereName = originName;
|
||||
if (StringUtils.equalsIgnoreCase(field.getType(), "date")
|
||||
|| (StringUtils.equalsIgnoreCase(dsMap.entrySet().iterator().next().getValue().getType(), "oracle") && StringUtils.equalsIgnoreCase(field.getType(), "timestamp"))) {
|
||||
whereName = String.format(SQLConstants.DE_CAST_DATE_FORMAT, originName,
|
||||
SQLConstants.DEFAULT_DATE_FORMAT,
|
||||
SQLConstants.DEFAULT_DATE_FORMAT);
|
||||
} else {
|
||||
whereName = originName;
|
||||
}
|
||||
}
|
||||
} else if (field.getDeType() == 2 || field.getDeType() == 3) {
|
||||
if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) {
|
||||
@ -135,7 +158,12 @@ public class CustomWhere2Str {
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(item.getFilterType(), "enum")) {
|
||||
if (ObjectUtils.isNotEmpty(item.getEnumValue())) {
|
||||
res = "(" + whereName + " IN ('" + String.join("','", item.getEnumValue()) + "'))";
|
||||
if (StringUtils.containsIgnoreCase(field.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(field.getType(), "NCHAR")) {
|
||||
res = "(" + whereName + " IN (" + item.getEnumValue().stream().map(str -> "'" + SQLConstants.MSSQL_N_PREFIX + str + "'").collect(Collectors.joining(",")) + "))";
|
||||
} else {
|
||||
res = "(" + whereName + " IN ('" + String.join("','", item.getEnumValue()) + "'))";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (field.getDeType() == 1 && isCross) {
|
||||
@ -156,9 +184,19 @@ public class CustomWhere2Str {
|
||||
} else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_empty")) {
|
||||
whereValue = "''";
|
||||
} else if (StringUtils.containsIgnoreCase(item.getTerm(), "in") || StringUtils.containsIgnoreCase(item.getTerm(), "not in")) {
|
||||
whereValue = "('" + String.join("','", value.split(",")) + "')";
|
||||
if (StringUtils.containsIgnoreCase(field.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(field.getType(), "NCHAR")) {
|
||||
whereValue = "(" + Arrays.stream(value.split(",")).map(str -> "'" + SQLConstants.MSSQL_N_PREFIX + str + "'").collect(Collectors.joining(",")) + ")";
|
||||
} else {
|
||||
whereValue = "('" + String.join("','", value.split(",")) + "')";
|
||||
}
|
||||
} else if (StringUtils.containsIgnoreCase(item.getTerm(), "like")) {
|
||||
whereValue = "'%" + value + "%'";
|
||||
if (StringUtils.containsIgnoreCase(field.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(field.getType(), "NCHAR")) {
|
||||
whereValue = "'" + SQLConstants.MSSQL_N_PREFIX + "%" + value + "%'";
|
||||
} else {
|
||||
whereValue = "'%" + value + "%'";
|
||||
}
|
||||
} else {
|
||||
// 如果是时间字段过滤,当条件是等于和不等于的时候转换成between和not between
|
||||
if (field.getDeType() == 1) {
|
||||
@ -199,7 +237,12 @@ public class CustomWhere2Str {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, value);
|
||||
}
|
||||
} else {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, value);
|
||||
if (StringUtils.containsIgnoreCase(field.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(field.getType(), "NCHAR")) {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE_CH, value);
|
||||
} else {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
SQLObj build = SQLObj.builder()
|
||||
|
||||
@ -33,13 +33,20 @@ public class Dimension2SQLObj {
|
||||
List<SQLObj> xFields = new ArrayList<>();
|
||||
List<SQLObj> xOrders = new ArrayList<>();
|
||||
Map<String, String> fieldsDialect = new HashMap<>();
|
||||
|
||||
String dsType = null;
|
||||
if (dsMap != null && dsMap.entrySet().iterator().hasNext()) {
|
||||
Map.Entry<Long, DatasourceSchemaDTO> next = dsMap.entrySet().iterator().next();
|
||||
dsType = next.getValue().getType();
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(fields)) {
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
ChartViewFieldDTO x = fields.get(i);
|
||||
String originField;
|
||||
if (ObjectUtils.isNotEmpty(x.getExtField()) && Objects.equals(x.getExtField(), ExtFieldConstant.EXT_CALC)) {
|
||||
// 解析origin name中有关联的字段生成sql表达式
|
||||
String calcFieldExp = Utils.calcFieldRegex(x.getOriginName(), tableObj, originFields, isCross, dsMap, paramMap,pluginManage);
|
||||
String calcFieldExp = Utils.calcFieldRegex(x.getOriginName(), tableObj, originFields, isCross, dsMap, paramMap, pluginManage);
|
||||
// 给计算字段处加一个占位符,后续SQL方言转换后再替换
|
||||
originField = String.format(SqlPlaceholderConstants.CALC_FIELD_PLACEHOLDER, x.getId());
|
||||
fieldsDialect.put(originField, calcFieldExp);
|
||||
@ -47,9 +54,17 @@ public class Dimension2SQLObj {
|
||||
originField = calcFieldExp;
|
||||
}
|
||||
} else if (ObjectUtils.isNotEmpty(x.getExtField()) && Objects.equals(x.getExtField(), ExtFieldConstant.EXT_COPY)) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getOriginName());
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
}
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getOriginName());
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
}
|
||||
}
|
||||
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i);
|
||||
// 处理横轴字段
|
||||
|
||||
@ -17,6 +17,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author Junjun
|
||||
@ -31,6 +32,13 @@ public class ExtWhere2Str {
|
||||
Map<String, String> paramMap = Utils.mergeParam(fieldParam, chartParam);
|
||||
List<SQLObj> list = new ArrayList<>();
|
||||
Map<String, String> fieldsDialect = new HashMap<>();
|
||||
|
||||
String dsType = null;
|
||||
if (dsMap != null && dsMap.entrySet().iterator().hasNext()) {
|
||||
Map.Entry<Long, DatasourceSchemaDTO> next = dsMap.entrySet().iterator().next();
|
||||
dsType = next.getValue().getType();
|
||||
}
|
||||
|
||||
if (ObjectUtils.isNotEmpty(fields)) {
|
||||
for (ChartExtFilterDTO request : fields) {
|
||||
List<String> value = request.getValue();
|
||||
@ -60,9 +68,17 @@ public class ExtWhere2Str {
|
||||
originName = calcFieldExp;
|
||||
}
|
||||
} else if (ObjectUtils.isNotEmpty(field.getExtField()) && field.getExtField() == 1) {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getOriginName());
|
||||
} else {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
}
|
||||
} else {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getOriginName());
|
||||
} else {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
}
|
||||
}
|
||||
|
||||
if (field.getDeType() == 1) {
|
||||
@ -87,8 +103,10 @@ public class ExtWhere2Str {
|
||||
originName = String.format(SQLConstants.DE_STR_TO_DATE, String.format(SQLConstants.CONCAT, "'1970-01-01 '", originName), SQLConstants.DEFAULT_DATE_FORMAT);
|
||||
}
|
||||
}
|
||||
// 此处获取标准格式的日期
|
||||
whereName = originName;
|
||||
// 此处获取标准格式的日期,同时此处是仪表板过滤,仪表板中图表的日期均已经格式化,所以要强制加上日期转换
|
||||
whereName = String.format(SQLConstants.DE_CAST_DATE_FORMAT, originName,
|
||||
SQLConstants.DEFAULT_DATE_FORMAT,
|
||||
SQLConstants.DEFAULT_DATE_FORMAT);
|
||||
}
|
||||
} else if (field.getDeType() == 2 || field.getDeType() == 3) {
|
||||
if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) {
|
||||
@ -129,10 +147,56 @@ public class ExtWhere2Str {
|
||||
if (value.contains(SQLConstants.EMPTY_SIGN)) {
|
||||
whereValue = "('" + StringUtils.join(value, "','") + "', '')" + " or " + whereName + " is null ";
|
||||
} else {
|
||||
whereValue = "('" + StringUtils.join(value, "','") + "')";
|
||||
// tree的情况需额外处理
|
||||
if (request.getIsTree()) {
|
||||
List<DatasetTableFieldDTO> datasetTableFieldList = request.getDatasetTableFieldList();
|
||||
boolean hasN = false;
|
||||
for (DatasetTableFieldDTO dto : datasetTableFieldList) {
|
||||
if (StringUtils.containsIgnoreCase(dto.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(dto.getType(), "NCHAR")) {
|
||||
hasN = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasN) {
|
||||
whereValue = "(" + value.stream().map(str -> "'" + SQLConstants.MSSQL_N_PREFIX + str + "'").collect(Collectors.joining(",")) + ")";
|
||||
} else {
|
||||
whereValue = "('" + StringUtils.join(value, "','") + "')";
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.containsIgnoreCase(request.getDatasetTableField().getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(request.getDatasetTableField().getType(), "NCHAR")) {
|
||||
whereValue = "(" + value.stream().map(str -> "'" + SQLConstants.MSSQL_N_PREFIX + str + "'").collect(Collectors.joining(",")) + ")";
|
||||
} else {
|
||||
whereValue = "('" + StringUtils.join(value, "','") + "')";
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) {
|
||||
whereValue = "'%" + value.get(0) + "%'";
|
||||
// tree的情况需额外处理
|
||||
if (request.getIsTree()) {
|
||||
List<DatasetTableFieldDTO> datasetTableFieldList = request.getDatasetTableFieldList();
|
||||
boolean hasN = false;
|
||||
for (DatasetTableFieldDTO dto : datasetTableFieldList) {
|
||||
if (StringUtils.containsIgnoreCase(dto.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(dto.getType(), "NCHAR")) {
|
||||
hasN = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasN) {
|
||||
whereValue = "'" + SQLConstants.MSSQL_N_PREFIX + "%" + value.get(0) + "%'";
|
||||
} else {
|
||||
whereValue = "'%" + value.get(0) + "%'";
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.containsIgnoreCase(request.getDatasetTableField().getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(request.getDatasetTableField().getType(), "NCHAR")) {
|
||||
whereValue = "'" + SQLConstants.MSSQL_N_PREFIX + "%" + value.get(0) + "%'";
|
||||
} else {
|
||||
whereValue = "'%" + value.get(0) + "%'";
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) {
|
||||
if (request.getDatasetTableField().getDeType() == 1) {
|
||||
if (request.getDatasetTableField().getDeExtractType() == 2
|
||||
@ -151,6 +215,10 @@ public class ExtWhere2Str {
|
||||
whereValue = String.format(SQLConstants.WHERE_BETWEEN, Utils.transLong2Str(Long.parseLong(value.get(0))), Utils.transLong2Str(Long.parseLong(value.get(1))));
|
||||
}
|
||||
}
|
||||
} else if (request.getDatasetTableField().getDeType() == 2
|
||||
|| request.getDatasetTableField().getDeType() == 3
|
||||
|| request.getDatasetTableField().getDeType() == 4) {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_BETWEEN, value.get(0), value.get(1));
|
||||
} else {
|
||||
whereValue = String.format(SQLConstants.WHERE_BETWEEN, value.get(0), value.get(1));
|
||||
}
|
||||
@ -159,7 +227,30 @@ public class ExtWhere2Str {
|
||||
if (StringUtils.equals(value.get(0), SQLConstants.EMPTY_SIGN)) {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, "") + " or " + whereName + " is null ";
|
||||
} else {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, value.get(0));
|
||||
// tree的情况需额外处理
|
||||
if (request.getIsTree()) {
|
||||
List<DatasetTableFieldDTO> datasetTableFieldList = request.getDatasetTableFieldList();
|
||||
boolean hasN = false;
|
||||
for (DatasetTableFieldDTO dto : datasetTableFieldList) {
|
||||
if (StringUtils.containsIgnoreCase(dto.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(dto.getType(), "NCHAR")) {
|
||||
hasN = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasN) {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE_CH, value.get(0));
|
||||
} else {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, value.get(0));
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.containsIgnoreCase(request.getDatasetTableField().getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(request.getDatasetTableField().getType(), "NCHAR")) {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE_CH, value.get(0));
|
||||
} else {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, value.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
list.add(SQLObj.builder()
|
||||
|
||||
@ -30,13 +30,20 @@ public class Field2SQLObj {
|
||||
Map<String, String> paramMap = Utils.mergeParam(fieldParam, chartParam);
|
||||
List<SQLObj> xFields = new ArrayList<>();
|
||||
Map<String, String> fieldsDialect = new HashMap<>();
|
||||
|
||||
String dsType = null;
|
||||
if (dsMap != null && dsMap.entrySet().iterator().hasNext()) {
|
||||
Map.Entry<Long, DatasourceSchemaDTO> next = dsMap.entrySet().iterator().next();
|
||||
dsType = next.getValue().getType();
|
||||
}
|
||||
|
||||
if (ObjectUtils.isNotEmpty(fields)) {
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
DatasetTableFieldDTO x = fields.get(i);
|
||||
String originField;
|
||||
if (ObjectUtils.isNotEmpty(x.getExtField()) && Objects.equals(x.getExtField(), ExtFieldConstant.EXT_CALC)) {
|
||||
// 解析origin name中有关联的字段生成sql表达式
|
||||
String calcFieldExp = Utils.calcFieldRegex(x.getOriginName(), tableObj, originFields, isCross, dsMap, paramMap,pluginManage);
|
||||
String calcFieldExp = Utils.calcFieldRegex(x.getOriginName(), tableObj, originFields, isCross, dsMap, paramMap, pluginManage);
|
||||
// 给计算字段处加一个占位符,后续SQL方言转换后再替换
|
||||
originField = String.format(SqlPlaceholderConstants.CALC_FIELD_PLACEHOLDER, x.getId());
|
||||
fieldsDialect.put(originField, calcFieldExp);
|
||||
@ -51,9 +58,17 @@ public class Field2SQLObj {
|
||||
}
|
||||
}
|
||||
} else if (ObjectUtils.isNotEmpty(x.getExtField()) && Objects.equals(x.getExtField(), ExtFieldConstant.EXT_COPY)) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getOriginName());
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
}
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getOriginName());
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), x.getDataeaseName());
|
||||
}
|
||||
}
|
||||
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i);
|
||||
// 处理横轴字段
|
||||
|
||||
@ -44,13 +44,28 @@ public class Order2SQLObj {
|
||||
private static SQLObj buildSortField(DeSortField f, SQLObj tableObj, int i, List<DatasetTableFieldDTO> originFields, boolean isCross, Map<Long, DatasourceSchemaDTO> dsMap, List<CalParam> fieldParam, List<CalParam> chartParam, PluginManageApi pluginManage) {
|
||||
Map<String, String> paramMap = Utils.mergeParam(fieldParam, chartParam);
|
||||
String originField;
|
||||
|
||||
String dsType = null;
|
||||
if (dsMap != null && dsMap.entrySet().iterator().hasNext()) {
|
||||
Map.Entry<Long, DatasourceSchemaDTO> next = dsMap.entrySet().iterator().next();
|
||||
dsType = next.getValue().getType();
|
||||
}
|
||||
|
||||
if (ObjectUtils.isNotEmpty(f.getExtField()) && Objects.equals(f.getExtField(), ExtFieldConstant.EXT_CALC)) {
|
||||
// 解析origin name中有关联的字段生成sql表达式
|
||||
originField = Utils.calcFieldRegex(f.getOriginName(), tableObj, originFields, isCross, dsMap, paramMap, pluginManage);
|
||||
} else if (ObjectUtils.isNotEmpty(f.getExtField()) && Objects.equals(f.getExtField(), ExtFieldConstant.EXT_COPY)) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), f.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), f.getOriginName());
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), f.getDataeaseName());
|
||||
}
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), f.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), f.getOriginName());
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), f.getDataeaseName());
|
||||
}
|
||||
}
|
||||
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i);
|
||||
String fieldName = "";
|
||||
|
||||
@ -33,6 +33,13 @@ public class Quota2SQLObj {
|
||||
List<String> yWheres = new ArrayList<>();
|
||||
List<SQLObj> yOrders = new ArrayList<>();
|
||||
Map<String, String> fieldsDialect = new HashMap<>();
|
||||
|
||||
String dsType = null;
|
||||
if (dsMap != null && dsMap.entrySet().iterator().hasNext()) {
|
||||
Map.Entry<Long, DatasourceSchemaDTO> next = dsMap.entrySet().iterator().next();
|
||||
dsType = next.getValue().getType();
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(fields)) {
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
ChartViewFieldDTO y = fields.get(i);
|
||||
@ -47,9 +54,17 @@ public class Quota2SQLObj {
|
||||
originField = calcFieldExp;
|
||||
}
|
||||
} else if (ObjectUtils.isNotEmpty(y.getExtField()) && Objects.equals(y.getExtField(), ExtFieldConstant.EXT_COPY)) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), y.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), y.getOriginName());
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), y.getDataeaseName());
|
||||
}
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), y.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), y.getOriginName());
|
||||
} else {
|
||||
originField = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), y.getDataeaseName());
|
||||
}
|
||||
}
|
||||
String fieldAlias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i);
|
||||
// 处理纵轴字段
|
||||
@ -100,7 +115,7 @@ public class Quota2SQLObj {
|
||||
String cast = String.format(SQLConstants.CAST, originField, Objects.equals(y.getDeType(), DeTypeConstants.DE_INT) ? SQLConstants.DEFAULT_INT_FORMAT : SQLConstants.DEFAULT_FLOAT_FORMAT);
|
||||
if (StringUtils.equalsIgnoreCase(y.getSummary(), "count_distinct")) {
|
||||
fieldName = String.format(SQLConstants.AGG_FIELD, "COUNT", "DISTINCT " + cast);
|
||||
} else if (y.getSummary() == null){
|
||||
} else if (y.getSummary() == null) {
|
||||
// 透视表自定义汇总不用聚合
|
||||
fieldName = cast;
|
||||
} else {
|
||||
|
||||
@ -18,6 +18,7 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author Junjun
|
||||
@ -96,6 +97,13 @@ public class WhereTree2Str {
|
||||
Map<String, String> paramMap = Utils.mergeParam(fieldParam, chartParam);
|
||||
String whereName = "";
|
||||
String originName;
|
||||
|
||||
String dsType = null;
|
||||
if (dsMap != null && dsMap.entrySet().iterator().hasNext()) {
|
||||
Map.Entry<Long, DatasourceSchemaDTO> next = dsMap.entrySet().iterator().next();
|
||||
dsType = next.getValue().getType();
|
||||
}
|
||||
|
||||
if (ObjectUtils.isNotEmpty(field.getExtField()) && Objects.equals(field.getExtField(), ExtFieldConstant.EXT_CALC)) {
|
||||
// 解析origin name中有关联的字段生成sql表达式
|
||||
String calcFieldExp = Utils.calcFieldRegex(field.getOriginName(), tableObj, originFields, isCross, dsMap, paramMap, pluginManage);
|
||||
@ -106,9 +114,17 @@ public class WhereTree2Str {
|
||||
originName = calcFieldExp;
|
||||
}
|
||||
} else if (ObjectUtils.isNotEmpty(field.getExtField()) && Objects.equals(field.getExtField(), ExtFieldConstant.EXT_COPY)) {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getOriginName());
|
||||
} else {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
}
|
||||
} else {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
if (StringUtils.equalsIgnoreCase(dsType, "es")) {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getOriginName());
|
||||
} else {
|
||||
originName = String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), field.getDataeaseName());
|
||||
}
|
||||
}
|
||||
if (field.getDeType() == 1) {
|
||||
if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) {
|
||||
@ -127,7 +143,14 @@ public class WhereTree2Str {
|
||||
originName = String.format(SQLConstants.DE_STR_TO_DATE, String.format(SQLConstants.CONCAT, "'1970-01-01 '", originName), SQLConstants.DEFAULT_DATE_FORMAT);
|
||||
}
|
||||
}
|
||||
whereName = originName;
|
||||
if (StringUtils.equalsIgnoreCase(field.getType(), "date")
|
||||
|| (StringUtils.equalsIgnoreCase(dsMap.entrySet().iterator().next().getValue().getType(), "oracle") && StringUtils.equalsIgnoreCase(field.getType(), "timestamp"))) {
|
||||
whereName = String.format(SQLConstants.DE_CAST_DATE_FORMAT, originName,
|
||||
SQLConstants.DEFAULT_DATE_FORMAT,
|
||||
SQLConstants.DEFAULT_DATE_FORMAT);
|
||||
} else {
|
||||
whereName = originName;
|
||||
}
|
||||
}
|
||||
} else if (field.getDeType() == 2 || field.getDeType() == 3) {
|
||||
if (field.getDeExtractType() == 0 || field.getDeExtractType() == 5) {
|
||||
@ -148,7 +171,12 @@ public class WhereTree2Str {
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(item.getFilterType(), "enum")) {
|
||||
if (CollectionUtils.isNotEmpty(item.getEnumValue())) {
|
||||
res = "(" + whereName + " IN ('" + String.join("','", item.getEnumValue()) + "'))";
|
||||
if (StringUtils.containsIgnoreCase(field.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(field.getType(), "NCHAR")) {
|
||||
res = "(" + whereName + " IN (" + item.getEnumValue().stream().map(str -> "'" + SQLConstants.MSSQL_N_PREFIX + str + "'").collect(Collectors.joining(",")) + "))";
|
||||
} else {
|
||||
res = "(" + whereName + " IN ('" + String.join("','", item.getEnumValue()) + "'))";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String value = item.getValue();
|
||||
@ -168,9 +196,19 @@ public class WhereTree2Str {
|
||||
} else if (StringUtils.equalsIgnoreCase(item.getTerm(), "not_empty")) {
|
||||
whereValue = "''";
|
||||
} else if (StringUtils.containsIgnoreCase(item.getTerm(), "in") || StringUtils.containsIgnoreCase(item.getTerm(), "not in")) {
|
||||
whereValue = "('" + String.join("','", value.split(",")) + "')";
|
||||
if (StringUtils.containsIgnoreCase(field.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(field.getType(), "NCHAR")) {
|
||||
whereValue = "(" + Arrays.stream(value.split(",")).map(str -> "'" + SQLConstants.MSSQL_N_PREFIX + str + "'").collect(Collectors.joining(",")) + ")";
|
||||
} else {
|
||||
whereValue = "('" + String.join("','", value.split(",")) + "')";
|
||||
}
|
||||
} else if (StringUtils.containsIgnoreCase(item.getTerm(), "like")) {
|
||||
whereValue = "'%" + value + "%'";
|
||||
if (StringUtils.containsIgnoreCase(field.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(field.getType(), "NCHAR")) {
|
||||
whereValue = "'" + SQLConstants.MSSQL_N_PREFIX + "%" + value + "%'";
|
||||
} else {
|
||||
whereValue = "'%" + value + "%'";
|
||||
}
|
||||
} else {
|
||||
// 如果是时间字段过滤,当条件是等于和不等于的时候转换成between和not between
|
||||
if (field.getDeType() == 1) {
|
||||
@ -209,7 +247,12 @@ public class WhereTree2Str {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, value);
|
||||
}
|
||||
} else {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, value);
|
||||
if (StringUtils.containsIgnoreCase(field.getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(field.getType(), "NCHAR")) {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE_CH, value);
|
||||
} else {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
SQLObj build = SQLObj.builder().whereField(whereName).whereTermAndValue(whereTerm + whereValue).build();
|
||||
|
||||
@ -42,6 +42,7 @@ import io.dataease.extensions.view.dto.DatasetRowPermissionsTreeObj;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.license.config.XpackInteract;
|
||||
import io.dataease.license.manage.F2CLicLimitedManage;
|
||||
import io.dataease.license.utils.LicenseUtil;
|
||||
import io.dataease.model.ExportTaskDTO;
|
||||
import io.dataease.system.manage.CoreUserManage;
|
||||
import io.dataease.system.manage.SysParameterManage;
|
||||
@ -65,6 +66,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Future;
|
||||
@ -97,7 +100,7 @@ public class ExportCenterManage implements BaseExportApi {
|
||||
private int max;
|
||||
|
||||
@Value("${dataease.export.dataset.limit:100000}")
|
||||
private int limit;
|
||||
private Long limit;
|
||||
private final static String DATA_URL_TITLE = "data:image/jpeg;base64,";
|
||||
private static final String exportData_path = "/opt/dataease2.0/data/exportData/";
|
||||
@Value("${dataease.export.page.size:50000}")
|
||||
@ -169,8 +172,14 @@ public class ExportCenterManage implements BaseExportApi {
|
||||
CoreExportTask exportTask = exportTaskMapper.selectById(id);
|
||||
OutputStream outputStream = response.getOutputStream();
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + exportTask.getFileName());
|
||||
InputStream fileInputStream = new FileInputStream(exportData_path + id + "/" + exportTask.getFileName());
|
||||
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(exportTask.getFileName(), StandardCharsets.UTF_8));
|
||||
InputStream fileInputStream;
|
||||
if (exportTask.getExportTime() < 1730277243491L) {
|
||||
fileInputStream = new FileInputStream(exportData_path + id + "/" + exportTask.getFileName());
|
||||
} else {
|
||||
fileInputStream = new FileInputStream(exportData_path + id + "/" + id + ".xlsx");
|
||||
}
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
|
||||
@ -392,7 +401,7 @@ public class ExportCenterManage implements BaseExportApi {
|
||||
exportTask.setExportStatus("IN_PROGRESS");
|
||||
exportTaskMapper.updateById(exportTask);
|
||||
|
||||
getDataFillingApi().writeExcel(dataPath + "/" + exportTask.getFileName(),
|
||||
getDataFillingApi().writeExcel(dataPath + "/" + exportTask.getId() + ".xlsx",
|
||||
new DataFillFormTableDataRequest()
|
||||
.setId(Long.parseLong(exportTask.getExportFrom()))
|
||||
.setWithoutLogs(true)
|
||||
@ -402,7 +411,7 @@ public class ExportCenterManage implements BaseExportApi {
|
||||
exportTask.setExportProgress("100");
|
||||
exportTask.setExportStatus("SUCCESS");
|
||||
|
||||
setFileSize(dataPath + "/" + exportTask.getFileName(), exportTask);
|
||||
setFileSize(dataPath + "/" + exportTask.getId() + ".xlsx", exportTask);
|
||||
} catch (Exception e) {
|
||||
exportTask.setMsg(e.getMessage());
|
||||
LogUtil.error("Failed to export data", e);
|
||||
@ -422,6 +431,7 @@ public class ExportCenterManage implements BaseExportApi {
|
||||
|
||||
TokenUserBO tokenUserBO = AuthUtils.getUser();
|
||||
Future future = scheduledThreadPoolExecutor.submit(() -> {
|
||||
LicenseUtil.validate();
|
||||
AuthUtils.setUser(tokenUserBO);
|
||||
try {
|
||||
exportTask.setExportStatus("IN_PROGRESS");
|
||||
@ -496,97 +506,105 @@ public class ExportCenterManage implements BaseExportApi {
|
||||
Field2SQLObj.field2sqlObj(sqlMeta, allFields, allFields, crossDs, dsMap, Utils.getParams(allFields), null, pluginManage);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, allFields, crossDs, dsMap, Utils.getParams(allFields), null, pluginManage);
|
||||
Order2SQLObj.getOrders(sqlMeta, dto.getSortFields(), allFields, crossDs, dsMap, Utils.getParams(allFields), null, pluginManage);
|
||||
|
||||
String replaceSql = provider.rebuildSQL(SQLProvider.createQuerySQL(sqlMeta, false, false, false), sqlMeta, crossDs, dsMap);
|
||||
Long totalCount = datasetDataManage.getDatasetTotal(dto, replaceSql, null);
|
||||
Long curLimit = getExportLimit();
|
||||
totalCount = totalCount > curLimit ? curLimit : totalCount;
|
||||
Long totalPage = (totalCount / extractPageSize) + (totalCount % extractPageSize > 0 ? 1 : 0);
|
||||
|
||||
Long sheetLimit = 1000000L;
|
||||
Long sheetCount = (totalCount / sheetLimit) + (totalCount % sheetLimit > 0 ? 1 : 0);
|
||||
Workbook wb = new SXSSFWorkbook();
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(dataPath + "/" + request.getFilename() + ".xlsx");
|
||||
Sheet detailsSheet = wb.createSheet("数据");
|
||||
List<List<String>> details = new ArrayList<>();
|
||||
|
||||
for (Integer p = 0; p < totalPage; p++) {
|
||||
String querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, false, p * extractPageSize + extractPageSize, extractPageSize);
|
||||
if (totalPage == 1) {
|
||||
querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, false, 0, totalCount.intValue());
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(dataPath + "/" + exportTask.getId() + ".xlsx");
|
||||
for (Long s = 1L; s < sheetCount + 1; s++) {
|
||||
Long sheetSize;
|
||||
if (s.equals(sheetCount)) {
|
||||
sheetSize = totalCount - (s - 1) * sheetLimit;
|
||||
} else {
|
||||
sheetSize = sheetLimit;
|
||||
}
|
||||
querySQL = provider.rebuildSQL(querySQL, sqlMeta, crossDs, dsMap);
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setQuery(querySQL);
|
||||
datasourceRequest.setDsList(dsMap);
|
||||
Map<String, Object> previewData = datasetDataManage.buildPreviewData(provider.fetchResultField(datasourceRequest), allFields, desensitizationList);
|
||||
List<Map<String, Object>> data = (List<Map<String, Object>>) previewData.get("data");
|
||||
if (p == 0L) {
|
||||
CellStyle cellStyle = wb.createCellStyle();
|
||||
Font font = wb.createFont();
|
||||
font.setFontHeightInPoints((short) 12);
|
||||
font.setBold(true);
|
||||
cellStyle.setFont(font);
|
||||
cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
|
||||
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
List<String> header = new ArrayList<>();
|
||||
for (DatasetTableFieldDTO field : allFields) {
|
||||
header.add(field.getName());
|
||||
Long pageSize = (sheetSize / extractPageSize) + (sheetSize % extractPageSize > 0 ? 1 : 0);
|
||||
Sheet detailsSheet = null;
|
||||
List<List<String>> details = new ArrayList<>();
|
||||
for (Long p = 0L; p < pageSize; p++) {
|
||||
String querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, false, p.intValue() * extractPageSize, extractPageSize);
|
||||
if (pageSize == 1) {
|
||||
querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, false, 0, sheetSize.intValue());
|
||||
}
|
||||
|
||||
details.add(header);
|
||||
for (Map<String, Object> obj : data) {
|
||||
List<String> row = new ArrayList<>();
|
||||
querySQL = provider.rebuildSQL(querySQL, sqlMeta, crossDs, dsMap);
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setQuery(querySQL);
|
||||
datasourceRequest.setDsList(dsMap);
|
||||
Map<String, Object> previewData = datasetDataManage.buildPreviewData(provider.fetchResultField(datasourceRequest), allFields, desensitizationList);
|
||||
List<Map<String, Object>> data = (List<Map<String, Object>>) previewData.get("data");
|
||||
if (p.equals(0L)) {
|
||||
detailsSheet = wb.createSheet("数据-" + s);
|
||||
CellStyle cellStyle = wb.createCellStyle();
|
||||
Font font = wb.createFont();
|
||||
font.setFontHeightInPoints((short) 12);
|
||||
font.setBold(true);
|
||||
cellStyle.setFont(font);
|
||||
cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
|
||||
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
List<String> header = new ArrayList<>();
|
||||
for (DatasetTableFieldDTO field : allFields) {
|
||||
String string = (String) obj.get(field.getDataeaseName());
|
||||
row.add(string);
|
||||
header.add(field.getName());
|
||||
}
|
||||
details.add(row);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(details)) {
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
Row row = detailsSheet.createRow(i);
|
||||
List<String> rowData = details.get(i);
|
||||
if (rowData != null) {
|
||||
for (int j = 0; j < rowData.size(); j++) {
|
||||
Cell cell = row.createCell(j);
|
||||
if (i == 0) {
|
||||
cell.setCellValue(rowData.get(j));
|
||||
cell.setCellStyle(cellStyle);
|
||||
detailsSheet.setColumnWidth(j, 255 * 20);
|
||||
} else {
|
||||
cell.setCellValue(rowData.get(j));
|
||||
details.add(header);
|
||||
for (Map<String, Object> obj : data) {
|
||||
List<String> row = new ArrayList<>();
|
||||
for (DatasetTableFieldDTO field : allFields) {
|
||||
String string = (String) obj.get(field.getDataeaseName());
|
||||
row.add(string);
|
||||
}
|
||||
details.add(row);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(details)) {
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
Row row = detailsSheet.createRow(i);
|
||||
List<String> rowData = details.get(i);
|
||||
if (rowData != null) {
|
||||
for (int j = 0; j < rowData.size(); j++) {
|
||||
Cell cell = row.createCell(j);
|
||||
if (i == 0) {
|
||||
cell.setCellValue(rowData.get(j));
|
||||
cell.setCellStyle(cellStyle);
|
||||
detailsSheet.setColumnWidth(j, 255 * 20);
|
||||
} else {
|
||||
cell.setCellValue(rowData.get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
details.clear();
|
||||
for (Map<String, Object> obj : data) {
|
||||
List<String> row = new ArrayList<>();
|
||||
for (DatasetTableFieldDTO field : allFields) {
|
||||
String string = (String) obj.get(field.getDataeaseName());
|
||||
row.add(string);
|
||||
} else {
|
||||
details.clear();
|
||||
for (Map<String, Object> obj : data) {
|
||||
List<String> row = new ArrayList<>();
|
||||
for (DatasetTableFieldDTO field : allFields) {
|
||||
String string = (String) obj.get(field.getDataeaseName());
|
||||
row.add(string);
|
||||
}
|
||||
details.add(row);
|
||||
}
|
||||
details.add(row);
|
||||
}
|
||||
int lastNum = detailsSheet.getLastRowNum();
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
Row row = detailsSheet.createRow(i + lastNum + 1);
|
||||
List<String> rowData = details.get(i);
|
||||
if (rowData != null) {
|
||||
for (int j = 0; j < rowData.size(); j++) {
|
||||
Cell cell = row.createCell(j);
|
||||
cell.setCellValue(rowData.get(j));
|
||||
int lastNum = detailsSheet.getLastRowNum();
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
Row row = detailsSheet.createRow(i + lastNum + 1);
|
||||
List<String> rowData = details.get(i);
|
||||
if (rowData != null) {
|
||||
for (int j = 0; j < rowData.size(); j++) {
|
||||
Cell cell = row.createCell(j);
|
||||
cell.setCellValue(rowData.get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exportTask.setExportStatus("IN_PROGRESS");
|
||||
double exportRogress2 = (double) ((double) s - 1) / ((double) sheetCount);
|
||||
double exportRogress = (double) ((double) (p + 1) / (double) pageSize) * ((double) 1 / sheetCount);
|
||||
DecimalFormat df = new DecimalFormat("#.##");
|
||||
String formattedResult = df.format((exportRogress + exportRogress2) * 100);
|
||||
exportTask.setExportProgress(formattedResult);
|
||||
exportTaskMapper.updateById(exportTask);
|
||||
}
|
||||
exportTask.setExportStatus("IN_PROGRESS");
|
||||
double exportRogress = (double) ((double) p / (double) totalPage);
|
||||
DecimalFormat df = new DecimalFormat("#.##");
|
||||
String formattedResult = df.format(exportRogress * 100);
|
||||
exportTask.setExportProgress(formattedResult);
|
||||
exportTaskMapper.updateById(exportTask);
|
||||
}
|
||||
wb.write(fileOutputStream);
|
||||
fileOutputStream.flush();
|
||||
@ -594,7 +612,7 @@ public class ExportCenterManage implements BaseExportApi {
|
||||
wb.close();
|
||||
exportTask.setExportProgress("100");
|
||||
exportTask.setExportStatus("SUCCESS");
|
||||
setFileSize(dataPath + "/" + request.getFilename() + ".xlsx", exportTask);
|
||||
setFileSize(dataPath + "/" + exportTask.getId() + ".xlsx", exportTask);
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("Failed to export data", e);
|
||||
@ -613,6 +631,7 @@ public class ExportCenterManage implements BaseExportApi {
|
||||
boolean isCreated = directory.mkdir();
|
||||
TokenUserBO tokenUserBO = AuthUtils.getUser();
|
||||
Future future = scheduledThreadPoolExecutor.submit(() -> {
|
||||
LicenseUtil.validate();
|
||||
AuthUtils.setUser(tokenUserBO);
|
||||
try {
|
||||
exportTask.setExportStatus("IN_PROGRESS");
|
||||
@ -663,14 +682,14 @@ public class ExportCenterManage implements BaseExportApi {
|
||||
ChartDataServer.setExcelData(detailsSheet, cellStyle, header, details, detailFields, excelTypes);
|
||||
}
|
||||
}
|
||||
try (FileOutputStream outputStream = new FileOutputStream(dataPath + "/" + request.getViewName() + ".xlsx")) {
|
||||
try (FileOutputStream outputStream = new FileOutputStream(dataPath + "/" + exportTask.getId() + ".xlsx")) {
|
||||
wb.write(outputStream);
|
||||
outputStream.flush();
|
||||
}
|
||||
wb.close();
|
||||
exportTask.setExportProgress("100");
|
||||
exportTask.setExportStatus("SUCCESS");
|
||||
setFileSize(dataPath + "/" + request.getViewName() + ".xlsx", exportTask);
|
||||
setFileSize(dataPath + "/" + exportTask.getId() + ".xlsx", exportTask);
|
||||
} catch (Exception e) {
|
||||
exportTask.setMsg(e.getMessage());
|
||||
LogUtil.error("Failed to export data", e);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package io.dataease.home;
|
||||
|
||||
import io.dataease.license.utils.LicenseUtil;
|
||||
import io.dataease.home.manage.DeIndexManage;
|
||||
import io.dataease.utils.ModelUtils;
|
||||
import io.dataease.utils.RsaUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@ -13,8 +13,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RequestMapping
|
||||
public class RestIndexController {
|
||||
|
||||
@Value("${dataease.xpack-front-distributed:false}")
|
||||
private boolean xpackFrontDistributed;
|
||||
|
||||
@Resource
|
||||
private DeIndexManage deIndexManage;
|
||||
|
||||
@GetMapping("/dekey")
|
||||
@ResponseBody
|
||||
@ -31,8 +32,8 @@ public class RestIndexController {
|
||||
|
||||
@GetMapping("/xpackModel")
|
||||
@ResponseBody
|
||||
public boolean xpackModel() {
|
||||
return xpackFrontDistributed && LicenseUtil.licenseValid();
|
||||
public Boolean xpackModel() {
|
||||
return deIndexManage.xpackModel();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
package io.dataease.home.manage;
|
||||
|
||||
import io.dataease.license.config.XpackInteract;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class DeIndexManage {
|
||||
|
||||
@XpackInteract(value = "deIndexManage", replace = true)
|
||||
public Boolean xpackModel() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -18,9 +18,9 @@ public class DeDataFillingTaskExecutor {
|
||||
protected static final String IS_TEMP_TASK = "isTempTask";
|
||||
protected static final String IS_RETRY_TASK = "isRetryTask";
|
||||
|
||||
private static final String JOB_GROUP = "REPORT_TASK";
|
||||
private static final String RETRY_JOB_GROUP = "RETRY_REPORT_TASK";
|
||||
private static final String TEMP_JOB_GROUP = "TEMP_REPORT_TASK";
|
||||
private static final String JOB_GROUP = "DATA_FILLING_TASK";
|
||||
private static final String RETRY_JOB_GROUP = "RETRY_DATA_FILLING_TASK";
|
||||
private static final String TEMP_JOB_GROUP = "TEMP_DATA_FILLING_TASK";
|
||||
|
||||
@Resource
|
||||
private ScheduleManager scheduleManager;
|
||||
|
||||
@ -2,6 +2,7 @@ package io.dataease.job.schedule;
|
||||
|
||||
import io.dataease.license.utils.LicenseUtil;
|
||||
import io.dataease.utils.CommonBeanFactory;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import org.quartz.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -18,10 +19,14 @@ public class DeXpackDataFillingScheduleJob implements Job {
|
||||
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
|
||||
DeDataFillingTaskExecutor deTaskExecutor = CommonBeanFactory.getBean(DeDataFillingTaskExecutor.class);
|
||||
assert deTaskExecutor != null;
|
||||
LicenseUtil.validate();
|
||||
boolean taskLoaded = deTaskExecutor.execute(jobDataMap);
|
||||
if (!taskLoaded) {
|
||||
Objects.requireNonNull(CommonBeanFactory.getBean(ScheduleManager.class)).removeJob(jobKey, trigger.getKey());
|
||||
try {
|
||||
LicenseUtil.validate();
|
||||
boolean taskLoaded = deTaskExecutor.execute(jobDataMap);
|
||||
if (!taskLoaded) {
|
||||
Objects.requireNonNull(CommonBeanFactory.getBean(ScheduleManager.class)).removeJob(jobKey, trigger.getKey());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e.getCause());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ public interface ResourceMonitorMapper {
|
||||
@Select("select count(id) from core_dataset_group")
|
||||
int datasetCount();
|
||||
|
||||
@Select("select count(id) from data_visualization_info where delete_flag = 0")
|
||||
@Select("select count(id) from data_visualization_info where delete_flag = 0 and pid != -1")
|
||||
int vCount();
|
||||
|
||||
@Select("select id, name, pid, type, status from core_datasource")
|
||||
@ -27,7 +27,7 @@ public interface ResourceMonitorMapper {
|
||||
@Select("select id, name, pid, node_type from core_dataset_group")
|
||||
List<DatasetFreeResource> queryFreeDataset();
|
||||
|
||||
@Select("select id, name, pid, node_type, type from data_visualization_info where delete_flag = 0")
|
||||
@Select("select id, name, pid, node_type, type from data_visualization_info where delete_flag = 0 and pid != -1")
|
||||
List<VisualFreeResource> queryFreeVusial();
|
||||
|
||||
@Delete("delete from core_datasource")
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
package io.dataease.share.interceptor;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.auth0.jwt.interfaces.Verification;
|
||||
import io.dataease.auth.DeLinkPermit;
|
||||
import io.dataease.constant.AuthConstant;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.share.manage.XpackShareManage;
|
||||
import io.dataease.share.util.LinkTokenUtil;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import io.dataease.utils.ServletUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class DeLinkAop {
|
||||
|
||||
private static final String PARAM_VARIABLE_PREFIX = "p";
|
||||
private static final String SPRING_EL_FLAG = "#";
|
||||
|
||||
private final ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
@Resource
|
||||
private XpackShareManage xpackShareManage;
|
||||
|
||||
@Around(value = "@annotation(io.dataease.auth.DeLinkPermit)")
|
||||
public Object logAround(ProceedingJoinPoint point) throws Throwable {
|
||||
Object[] params = point.getArgs();
|
||||
String linkToken = ServletUtils.getHead(AuthConstant.LINK_TOKEN_KEY);
|
||||
if (StringUtils.isNotBlank(linkToken)) {
|
||||
MethodSignature ms = (MethodSignature) point.getSignature();
|
||||
Method method = ms.getMethod();
|
||||
DeLinkPermit deLinkPermit = method.getAnnotation(DeLinkPermit.class);
|
||||
String value = deLinkPermit.value();
|
||||
if (StringUtils.isBlank(value)) {
|
||||
value = SPRING_EL_FLAG + PARAM_VARIABLE_PREFIX + "0";
|
||||
}
|
||||
Long id = getExpression(params, value);
|
||||
DecodedJWT jwt = JWT.decode(linkToken);
|
||||
Long resourceId = jwt.getClaim("resourceId").asLong();
|
||||
if (!id.equals(resourceId)) {
|
||||
DEException.throwException("link token invalid");
|
||||
return false;
|
||||
}
|
||||
|
||||
Long uid = jwt.getClaim("uid").asLong();
|
||||
String secret = xpackShareManage.queryPwd(resourceId, uid);
|
||||
if (StringUtils.isBlank(secret)) {
|
||||
secret = LinkTokenUtil.defaultPwd;
|
||||
}
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
Verification verification = JWT.require(algorithm);
|
||||
JWTVerifier verifier = verification.build();
|
||||
DecodedJWT decode = JWT.decode(linkToken);
|
||||
algorithm.verify(decode);
|
||||
verifier.verify(linkToken);
|
||||
}
|
||||
try {
|
||||
return point.proceed(params);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public Long getExpression(Object[] params, String expression) {
|
||||
StandardEvaluationContext context = buildContext(params);
|
||||
Object o = resolveValue(expression, context);
|
||||
if (ObjectUtils.isNotEmpty(o)) return Long.parseLong(o.toString());
|
||||
return null;
|
||||
}
|
||||
|
||||
private StandardEvaluationContext buildContext(Object[] params) {
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
if (params != null && params.length == 1) {
|
||||
context.setRootObject(params[0]);
|
||||
}
|
||||
for (int i = 0; i < Objects.requireNonNull(params).length; i++) {
|
||||
Object paramValue = params[i];
|
||||
context.setVariable(PARAM_VARIABLE_PREFIX + i, paramValue);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
private Object resolveValue(String exp, EvaluationContext context) {
|
||||
if (StringUtils.contains(exp, SPRING_EL_FLAG)) {
|
||||
Expression expression = parser.parseExpression(exp);
|
||||
return expression.getValue(context);
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package io.dataease.share.interceptor;
|
||||
|
||||
import io.dataease.auth.DeLinkPermit;
|
||||
import io.dataease.constant.AuthConstant;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.utils.ServletUtils;
|
||||
import io.dataease.utils.WhitelistUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Component
|
||||
public class LinkInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final static String whiteListText = "/user/ipInfo, /apisix/check";
|
||||
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
String linkToken = ServletUtils.getHead(AuthConstant.LINK_TOKEN_KEY);
|
||||
if (linkToken == null) {
|
||||
return true;
|
||||
}
|
||||
if (handler instanceof HandlerMethod handlerMethod) {
|
||||
DeLinkPermit deLinkPermit = handlerMethod.getMethodAnnotation(DeLinkPermit.class);
|
||||
if (deLinkPermit == null) {
|
||||
|
||||
List<String> whiteList = Arrays.stream(StringUtils.split(whiteListText, ",")).map(String::trim).toList();
|
||||
String requestURI = ServletUtils.request().getRequestURI();
|
||||
if (StringUtils.startsWith(requestURI, WhitelistUtils.getContextPath())) {
|
||||
requestURI = requestURI.replaceFirst(WhitelistUtils.getContextPath(), "");
|
||||
}
|
||||
if (StringUtils.startsWith(requestURI, AuthConstant.DE_API_PREFIX)) {
|
||||
requestURI = requestURI.replaceFirst(AuthConstant.DE_API_PREFIX, "");
|
||||
}
|
||||
boolean valid = whiteList.contains(requestURI);
|
||||
if (!valid) {
|
||||
DEException.throwException("分享链接Token不支持访问当前url[" + requestURI + "]");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -3,6 +3,7 @@ package io.dataease.share.manage;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.dataease.api.system.vo.ShareBaseVO;
|
||||
import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackShareProxyRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackSharePwdValidator;
|
||||
@ -21,6 +22,7 @@ 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.system.manage.SysParameterManage;
|
||||
import io.dataease.utils.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
@ -51,6 +53,9 @@ public class XpackShareManage {
|
||||
@Resource
|
||||
private ShareTicketManage shareTicketManage;
|
||||
|
||||
@Resource
|
||||
private SysParameterManage sysParameterManage;
|
||||
|
||||
public XpackShare queryByResource(Long resourceId) {
|
||||
Long userId = AuthUtils.getUser().getUserId();
|
||||
QueryWrapper<XpackShare> queryWrapper = new QueryWrapper<>();
|
||||
@ -59,6 +64,15 @@ public class XpackShareManage {
|
||||
return xpackShareMapper.selectOne(queryWrapper);
|
||||
}
|
||||
|
||||
public String queryPwd(Long resourceId, Long userId) {
|
||||
QueryWrapper<XpackShare> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("creator", userId);
|
||||
queryWrapper.eq("resource_id", resourceId);
|
||||
XpackShare xpackShare = xpackShareMapper.selectOne(queryWrapper);
|
||||
if (ObjectUtils.isEmpty(xpackShare)) return null;
|
||||
return xpackShare.getPwd();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void switcher(Long resourceId) {
|
||||
XpackShare originData = queryByResource(resourceId);
|
||||
@ -190,7 +204,20 @@ public class XpackShareManage {
|
||||
return CommonBeanFactory.getBean(this.getClass());
|
||||
}
|
||||
|
||||
private boolean peRequireValid(ShareBaseVO sharedBase, XpackShare share) {
|
||||
if (ObjectUtils.isEmpty(sharedBase) || !sharedBase.isPeRequire()) return true;
|
||||
Long exp = share.getExp();
|
||||
String pwd = share.getPwd();
|
||||
return StringUtils.isNotBlank(pwd) && ObjectUtils.isNotEmpty(exp) && exp > 0L;
|
||||
}
|
||||
|
||||
public XpackShareProxyVO proxyInfo(XpackShareProxyRequest request) {
|
||||
ShareBaseVO sharedBase = sysParameterManage.shareBase();
|
||||
if (ObjectUtils.isNotEmpty(sharedBase) && sharedBase.isDisable()) {
|
||||
XpackShareProxyVO vo = new XpackShareProxyVO();
|
||||
vo.setShareDisable(true);
|
||||
return vo;
|
||||
}
|
||||
boolean inIframeError = request.isInIframe() && !LicenseUtil.licenseValid();
|
||||
if (inIframeError) {
|
||||
return new XpackShareProxyVO();
|
||||
@ -200,13 +227,18 @@ public class XpackShareManage {
|
||||
XpackShare xpackShare = xpackShareMapper.selectOne(queryWrapper);
|
||||
if (ObjectUtils.isEmpty(xpackShare))
|
||||
return null;
|
||||
if (!peRequireValid(sharedBase, xpackShare)) {
|
||||
XpackShareProxyVO vo = new XpackShareProxyVO();
|
||||
vo.setPeRequireValid(false);
|
||||
return vo;
|
||||
}
|
||||
String linkToken = LinkTokenUtil.generate(xpackShare.getCreator(), xpackShare.getResourceId(), xpackShare.getExp(), xpackShare.getPwd(), xpackShare.getOid());
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
response.addHeader(AuthConstant.LINK_TOKEN_KEY, linkToken);
|
||||
Integer type = xpackShare.getType();
|
||||
String typeText = (ObjectUtils.isNotEmpty(type) && type == 1) ? "dashboard" : "dataV";
|
||||
TicketValidVO validVO = shareTicketManage.validateTicket(request.getTicket(), xpackShare);
|
||||
return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText, inIframeError, validVO);
|
||||
return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText, inIframeError, false, true, validVO);
|
||||
}
|
||||
|
||||
private boolean linkExp(XpackShare xpackShare) {
|
||||
|
||||
@ -9,7 +9,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import java.util.Date;
|
||||
|
||||
public class LinkTokenUtil {
|
||||
private static final String defaultPwd = "link-pwd-fit2cloud";
|
||||
public static final String defaultPwd = "link-pwd-fit2cloud";
|
||||
public static String generate(Long uid, Long resourceId, Long exp, String pwd, Long oid) {
|
||||
pwd = StringUtils.isBlank(pwd) ? defaultPwd : pwd;
|
||||
Algorithm algorithm = Algorithm.HMAC256(pwd);
|
||||
|
||||
@ -5,14 +5,17 @@ import com.auth0.jwt.JWTCreator;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import io.dataease.api.permissions.login.dto.PwdLoginDTO;
|
||||
import io.dataease.auth.bo.TokenUserBO;
|
||||
import io.dataease.auth.config.SubstituleLoginConfig;
|
||||
import io.dataease.auth.vo.TokenVO;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import io.dataease.utils.Md5Utils;
|
||||
import io.dataease.utils.RsaUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Component
|
||||
@ConditionalOnMissingBean(name = "loginServer")
|
||||
@ -21,11 +24,26 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
public class SubstituleLoginServer {
|
||||
|
||||
@PostMapping("/login/localLogin")
|
||||
public TokenVO localLogin(PwdLoginDTO dto) {
|
||||
public TokenVO localLogin(@RequestBody PwdLoginDTO dto) {
|
||||
|
||||
String name = dto.getName();
|
||||
name = RsaUtils.decryptStr(name);
|
||||
String pwd = dto.getPwd();
|
||||
pwd = RsaUtils.decryptStr(pwd);
|
||||
|
||||
dto.setName(name);
|
||||
dto.setPwd(pwd);
|
||||
|
||||
if (!StringUtils.equals("admin", name)) {
|
||||
DEException.throwException("仅admin账号可用");
|
||||
}
|
||||
if (!StringUtils.equals(pwd, SubstituleLoginConfig.getPwd())) {
|
||||
DEException.throwException(Translator.get("i18n_login_name_pwd_err"));
|
||||
}
|
||||
TokenUserBO tokenUserBO = new TokenUserBO();
|
||||
tokenUserBO.setUserId(1L);
|
||||
tokenUserBO.setDefaultOid(1L);
|
||||
String md5Pwd = "83d923c9f1d8fcaa46cae0ed2aaa81b5";
|
||||
String md5Pwd = Md5Utils.md5(pwd);
|
||||
return generate(tokenUserBO, md5Pwd);
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
package io.dataease.system.manage;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.dataease.api.system.request.OnlineMapEditor;
|
||||
import io.dataease.api.system.vo.SettingItemVO;
|
||||
import io.dataease.api.system.vo.ShareBaseVO;
|
||||
import io.dataease.datasource.server.DatasourceServer;
|
||||
import io.dataease.license.config.XpackInteract;
|
||||
import io.dataease.system.dao.auto.entity.CoreSysSetting;
|
||||
@ -13,6 +15,7 @@ import io.dataease.utils.IDUtils;
|
||||
import io.dataease.utils.SystemSettingUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -30,7 +33,7 @@ public class SysParameterManage {
|
||||
@Value("${dataease.demo-tips-content:#{null}}")
|
||||
private String demoTipsContent;
|
||||
|
||||
private static final String mapKey = "map.key";
|
||||
private static final String MAP_KEY_PREFIX = "map.";
|
||||
|
||||
@Resource
|
||||
private CoreSysSettingMapper coreSysSettingMapper;
|
||||
@ -50,26 +53,39 @@ public class SysParameterManage {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String queryOnlineMap() {
|
||||
return singleVal(mapKey);
|
||||
public OnlineMapEditor queryOnlineMap() {
|
||||
var editor = new OnlineMapEditor();
|
||||
List<String> fields = BeanUtils.getFieldNames(OnlineMapEditor.class);
|
||||
Map<String, String> mapVal = groupVal(MAP_KEY_PREFIX);
|
||||
fields.forEach(field -> {
|
||||
String val = mapVal.get(MAP_KEY_PREFIX + field);
|
||||
if (StringUtils.isNotBlank(val)) {
|
||||
BeanUtils.setFieldValueByName(editor, field, val, String.class);
|
||||
}
|
||||
});
|
||||
return editor;
|
||||
}
|
||||
|
||||
public void saveOnlineMap(String val) {
|
||||
|
||||
QueryWrapper<CoreSysSetting> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("pkey", mapKey);
|
||||
CoreSysSetting sysSetting = coreSysSettingMapper.selectOne(queryWrapper);
|
||||
if (ObjectUtils.isEmpty(sysSetting)) {
|
||||
sysSetting = new CoreSysSetting();
|
||||
sysSetting.setId(IDUtils.snowID());
|
||||
sysSetting.setPkey(mapKey);
|
||||
public void saveOnlineMap(OnlineMapEditor editor) {
|
||||
List<String> fieldNames = BeanUtils.getFieldNames(OnlineMapEditor.class);
|
||||
fieldNames.forEach(field -> {
|
||||
QueryWrapper<CoreSysSetting> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("pkey", MAP_KEY_PREFIX + field);
|
||||
CoreSysSetting sysSetting = coreSysSettingMapper.selectOne(queryWrapper);
|
||||
var val = (String) BeanUtils.getFieldValueByName(field, editor);
|
||||
if (ObjectUtils.isEmpty(sysSetting)) {
|
||||
sysSetting = new CoreSysSetting();
|
||||
sysSetting.setId(IDUtils.snowID());
|
||||
sysSetting.setPkey(MAP_KEY_PREFIX + field);
|
||||
sysSetting.setPval(val == null ? "" : val);
|
||||
sysSetting.setType("text");
|
||||
sysSetting.setSort(1);
|
||||
coreSysSettingMapper.insert(sysSetting);
|
||||
return;
|
||||
}
|
||||
sysSetting.setPval(val);
|
||||
sysSetting.setType("text");
|
||||
sysSetting.setSort(1);
|
||||
coreSysSettingMapper.insert(sysSetting);
|
||||
}
|
||||
sysSetting.setPval(val);
|
||||
coreSysSettingMapper.updateById(sysSetting);
|
||||
coreSysSettingMapper.updateById(sysSetting);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +97,7 @@ public class SysParameterManage {
|
||||
if (!CollectionUtils.isEmpty(sysSettings)) {
|
||||
return sysSettings.stream().collect(Collectors.toMap(CoreSysSetting::getPkey, CoreSysSetting::getPval));
|
||||
}
|
||||
return null;
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
public List<CoreSysSetting> groupList(String groupKey) {
|
||||
@ -143,4 +159,17 @@ public class SysParameterManage {
|
||||
private SysParameterManage proxy() {
|
||||
return CommonBeanFactory.getBean(SysParameterManage.class);
|
||||
}
|
||||
|
||||
public ShareBaseVO shareBase() {
|
||||
String disableText = singleVal("basic.shareDisable");
|
||||
String requireText = singleVal("basic.sharePeRequire");
|
||||
ShareBaseVO vo = new ShareBaseVO();
|
||||
if (StringUtils.isNotBlank(disableText) && StringUtils.equals("true", disableText)) {
|
||||
vo.setDisable(true);
|
||||
}
|
||||
if (StringUtils.isNotBlank(requireText) && StringUtils.equals("true", requireText)) {
|
||||
vo.setPeRequire(true);
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package io.dataease.system.server;
|
||||
import io.dataease.api.system.SysParameterApi;
|
||||
import io.dataease.api.system.request.OnlineMapEditor;
|
||||
import io.dataease.api.system.vo.SettingItemVO;
|
||||
import io.dataease.api.system.vo.ShareBaseVO;
|
||||
import io.dataease.constant.XpackSettingConstants;
|
||||
import io.dataease.system.dao.auto.entity.CoreSysSetting;
|
||||
import io.dataease.system.manage.SysParameterManage;
|
||||
@ -27,13 +28,12 @@ public class SysParameterServer implements SysParameterApi {
|
||||
|
||||
@Override
|
||||
public void saveOnlineMap(OnlineMapEditor editor) {
|
||||
sysParameterManage.saveOnlineMap(editor.getKey());
|
||||
sysParameterManage.saveOnlineMap(editor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String queryOnlineMap() {
|
||||
String key = sysParameterManage.queryOnlineMap();
|
||||
return StringUtils.isNotBlank(key) ? key : "";
|
||||
public OnlineMapEditor queryOnlineMap() {
|
||||
return sysParameterManage.queryOnlineMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -70,4 +70,9 @@ public class SysParameterServer implements SysParameterApi {
|
||||
public Integer defaultLogin() {
|
||||
return sysParameterManage.defaultLogin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShareBaseVO shareBase() {
|
||||
return sysParameterManage.shareBase();
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import io.dataease.api.template.vo.MarketLatestReleaseVO;
|
||||
import io.dataease.api.template.vo.MarketMetaDataVO;
|
||||
import io.dataease.constant.CommonConstants;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.operation.manage.CoreOptRecentManage;
|
||||
import io.dataease.system.manage.SysParameterManage;
|
||||
import io.dataease.template.dao.auto.entity.VisualizationTemplateCategoryMap;
|
||||
@ -166,11 +167,11 @@ public class TemplateCenterManage {
|
||||
public MarketPreviewBaseResponse searchTemplatePreview() {
|
||||
try {
|
||||
MarketBaseResponse baseContentRsp = searchTemplate();
|
||||
List<MarketMetaDataVO> categories = baseContentRsp.getCategories().stream().filter(category -> !"最近使用".equals(category.getLabel())).collect(Collectors.toList());
|
||||
List<MarketMetaDataVO> categories = baseContentRsp.getCategories().stream().filter(category -> !Translator.get("i18n_template_recent").equals(category.getLabel())).toList();
|
||||
List<TemplateMarketDTO> contents = baseContentRsp.getContents();
|
||||
List<TemplateMarketPreviewInfoDTO> previewContents = new ArrayList<>();
|
||||
categories.forEach(category -> {
|
||||
if ("推荐".equals(category.getLabel())) {
|
||||
if (Translator.get("i18n_template_recommend").equals(category.getLabel())) {
|
||||
previewContents.add(new TemplateMarketPreviewInfoDTO(category, contents.stream().filter(template -> "Y".equals(template.getSuggest())).collect(Collectors.toList())));
|
||||
} else {
|
||||
previewContents.add(new TemplateMarketPreviewInfoDTO(category, contents.stream().filter(template -> checkCategoryMatch(template, category.getLabel())).collect(Collectors.toList())));
|
||||
@ -235,7 +236,7 @@ public class TemplateCenterManage {
|
||||
List<MarketMetaDataVO> categoryVO = getCategoriesObject().stream().filter(node -> !"全部".equalsIgnoreCase(node.getLabel())).collect(Collectors.toList());
|
||||
Map<String, String> categoriesMap = categoryVO.stream()
|
||||
.collect(Collectors.toMap(MarketMetaDataVO::getValue, MarketMetaDataVO::getLabel));
|
||||
List<String> activeCategoriesName = new ArrayList<>(Arrays.asList("最近使用", "推荐"));
|
||||
List<String> activeCategoriesName = new ArrayList<>(Arrays.asList(Translator.get("i18n_template_recent"), Translator.get("i18n_template_recommend")));
|
||||
contents.stream().forEach(templateMarketDTO -> {
|
||||
Long recentUseTime = useTime.get(templateMarketDTO.getId());
|
||||
templateMarketDTO.setRecentUseTime(recentUseTime == null ? 0 : recentUseTime);
|
||||
@ -264,7 +265,7 @@ public class TemplateCenterManage {
|
||||
|
||||
public List<MarketMetaDataVO> getCategoriesObject() {
|
||||
List<MarketMetaDataVO> result = getCategoriesV2();
|
||||
result.add(0, new MarketMetaDataVO("recent", "最近使用", CommonConstants.TEMPLATE_SOURCE.PUBLIC));
|
||||
result.add(0, new MarketMetaDataVO("recent", Translator.get("i18n_template_recent"), CommonConstants.TEMPLATE_SOURCE.PUBLIC));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -285,7 +286,7 @@ public class TemplateCenterManage {
|
||||
String resultStr = marketGet(templateParams.get("template.url") + TEMPLATE_META_DATA_URL, null);
|
||||
MarketMetaDataBaseResponse metaData = JsonUtil.parseObject(resultStr, MarketMetaDataBaseResponse.class);
|
||||
allCategories.addAll(metaData.getLabels());
|
||||
allCategories.add(0, new MarketMetaDataVO("suggest", "推荐", CommonConstants.TEMPLATE_SOURCE.PUBLIC));
|
||||
allCategories.add(0, new MarketMetaDataVO("suggest", Translator.get("i18n_template_recommend"), CommonConstants.TEMPLATE_SOURCE.PUBLIC));
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("模板市场分类获取错误", e);
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Mapper
|
||||
public interface ExtDataVisualizationMapper {
|
||||
@ -51,5 +52,7 @@ public interface ExtDataVisualizationMapper {
|
||||
|
||||
List<VisualizationReportFilterVO> queryReportFilter(@Param("dvId") Long dvId,@Param("taskId") Long taskId);
|
||||
|
||||
void deleteDataVBatch(@Param("ids") Set<Long> ids);
|
||||
|
||||
void deleteViewsBatch(@Param("ids") Set<Long> ids);
|
||||
}
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
package io.dataease.visualization.manage;
|
||||
|
||||
import io.dataease.dataset.manage.DatasetGroupManage;
|
||||
import io.dataease.datasource.manage.DataSourceManage;
|
||||
import io.dataease.model.BusiNodeRequest;
|
||||
import io.dataease.model.BusiNodeVO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component("coreBusiManage")
|
||||
public class CoreBusiManage {
|
||||
|
||||
@Resource
|
||||
private CoreVisualizationManage coreVisualizationManage;
|
||||
|
||||
@Resource
|
||||
private DataSourceManage dataSourceManage;
|
||||
|
||||
@Resource
|
||||
private DatasetGroupManage datasetGroupManage;
|
||||
|
||||
public Map<String, List<BusiNodeVO>> interactiveTree(Map<String, BusiNodeRequest> requestMap) {
|
||||
Map<String, List<BusiNodeVO>> result = new HashMap<>();
|
||||
for (Map.Entry<String, BusiNodeRequest> entry : requestMap.entrySet()) {
|
||||
BusiNodeRequest busiNodeRequest = entry.getValue();
|
||||
String key = entry.getKey();
|
||||
if (StringUtils.equalsIgnoreCase(key, "datasource")) {
|
||||
result.put(key, dataSourceManage.tree(busiNodeRequest));
|
||||
} else if (StringUtils.equalsIgnoreCase(key, "dataset")) {
|
||||
result.put(key, datasetGroupManage.tree(busiNodeRequest));
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(key, "dashboard", "dataV")) {
|
||||
result.put(key, coreVisualizationManage.tree(busiNodeRequest));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -89,7 +89,11 @@ public class CoreVisualizationManage {
|
||||
});
|
||||
}
|
||||
}
|
||||
extMapper.batchDel(delIds, System.currentTimeMillis(), AuthUtils.getUser().getUserId());
|
||||
// 删除可视化资源
|
||||
extDataVisualizationMapper.deleteDataVBatch(delIds);
|
||||
// 删除图表信息
|
||||
extDataVisualizationMapper.deleteViewsBatch(delIds);
|
||||
|
||||
coreOptRecentManage.saveOpt(id, OptConstants.OPT_RESOURCE_TYPE.VISUALIZATION, OptConstants.OPT_TYPE.DELETE);
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ import io.dataease.api.visualization.request.DataVisualizationBaseRequest;
|
||||
import io.dataease.api.visualization.request.VisualizationAppExportRequest;
|
||||
import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest;
|
||||
import io.dataease.api.visualization.vo.*;
|
||||
import io.dataease.auth.DeLinkPermit;
|
||||
import io.dataease.chart.dao.auto.entity.CoreChartView;
|
||||
import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
|
||||
import io.dataease.chart.manage.ChartDataManage;
|
||||
@ -51,6 +52,7 @@ import io.dataease.visualization.dao.auto.entity.VisualizationWatermark;
|
||||
import io.dataease.visualization.dao.auto.mapper.DataVisualizationInfoMapper;
|
||||
import io.dataease.visualization.dao.auto.mapper.VisualizationWatermarkMapper;
|
||||
import io.dataease.visualization.dao.ext.mapper.ExtDataVisualizationMapper;
|
||||
import io.dataease.visualization.manage.CoreBusiManage;
|
||||
import io.dataease.visualization.manage.CoreVisualizationManage;
|
||||
import io.dataease.visualization.utils.VisualizationUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
@ -128,6 +130,9 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
@Autowired
|
||||
private CoreDatasourceMapper coreDatasourceMapper;
|
||||
|
||||
@Resource
|
||||
private CoreBusiManage coreBusiManage;
|
||||
|
||||
@Override
|
||||
public DataVisualizationVO findCopyResource(Long dvId, String busiFlag) {
|
||||
DataVisualizationVO result = findById(new DataVisualizationBaseRequest(dvId, busiFlag));
|
||||
@ -138,6 +143,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
}
|
||||
}
|
||||
|
||||
@DeLinkPermit("#p0.id")
|
||||
@DeLog(id = "#p0.id", ot = LogOT.READ, stExp = "#p0.busiFlag")
|
||||
@Override
|
||||
@XpackInteract(value = "dataVisualizationServer", original = true)
|
||||
@ -296,7 +302,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
coreDatasetTableFieldMapper.insert(dsTableFields);
|
||||
});
|
||||
|
||||
|
||||
List<String> dsGroupNameSave = new ArrayList<>();
|
||||
// 持久化数据集
|
||||
newDsGroupInfo.forEach(dsGroup -> {
|
||||
dsTableIdMap.forEach((key, value) -> {
|
||||
@ -321,8 +327,10 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
if(dsGroupNameSave.contains(dsGroup.getName())){
|
||||
dsGroup.setName(dsGroup.getName()+"-"+UUID.randomUUID().toString());
|
||||
}
|
||||
dsGroupNameSave.add(dsGroup.getName());
|
||||
datasetGroupManage.innerSave(dsGroup);
|
||||
});
|
||||
|
||||
@ -484,6 +492,11 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
return coreVisualizationManage.tree(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<BusiNodeVO>> interactiveTree(Map<String, BusiNodeRequest> requestMap) {
|
||||
return coreBusiManage.interactiveTree(requestMap);
|
||||
}
|
||||
|
||||
@DeLog(id = "#p0.id", pid = "#p0.pid", ot = LogOT.MODIFY, stExp = "#p0.type")
|
||||
@Transactional
|
||||
@Override
|
||||
@ -743,7 +756,6 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
wrapper.eq("name", request.getName().trim());
|
||||
wrapper.eq("node_type", request.getNodeType());
|
||||
wrapper.eq("type", request.getType());
|
||||
wrapper.eq("org_id", AuthUtils.getUser().getDefaultOid());
|
||||
if (visualizationInfoMapper.exists(wrapper)) {
|
||||
DEException.throwException("当前名称已经存在");
|
||||
}
|
||||
@ -772,6 +784,9 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
List<DataVisualizationInfo> list = new ArrayList<>();
|
||||
DataVisualizationInfo dataVisualizationInfo = visualizationInfoMapper.selectById(id);
|
||||
list.add(dataVisualizationInfo);
|
||||
if (dataVisualizationInfo.getPid().equals(dataVisualizationInfo.getId())) {
|
||||
return list;
|
||||
}
|
||||
getParent(list, dataVisualizationInfo);
|
||||
Collections.reverse(list);
|
||||
return list;
|
||||
|
||||
@ -7,6 +7,7 @@ import io.dataease.api.visualization.dto.VisualizationLinkJumpInfoDTO;
|
||||
import io.dataease.api.visualization.request.VisualizationLinkJumpBaseRequest;
|
||||
import io.dataease.api.visualization.response.VisualizationLinkJumpBaseResponse;
|
||||
import io.dataease.api.visualization.vo.VisualizationViewTableVO;
|
||||
import io.dataease.auth.DeLinkPermit;
|
||||
import io.dataease.chart.dao.auto.entity.CoreChartView;
|
||||
import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
|
||||
@ -67,6 +68,7 @@ public class VisualizationLinkJumpService implements VisualizationLinkJumpApi {
|
||||
return extVisualizationLinkageMapper.queryTableFieldWithViewId(viewId);
|
||||
}
|
||||
|
||||
@DeLinkPermit
|
||||
//获取仪表板的跳转信息
|
||||
@Override
|
||||
public VisualizationLinkJumpBaseResponse queryVisualizationJumpInfo(Long dvId) {
|
||||
|
||||
@ -6,6 +6,7 @@ import io.dataease.api.visualization.dto.LinkageInfoDTO;
|
||||
import io.dataease.api.visualization.dto.VisualizationLinkageDTO;
|
||||
import io.dataease.api.visualization.request.VisualizationLinkageRequest;
|
||||
import io.dataease.api.visualization.vo.VisualizationLinkageFieldVO;
|
||||
import io.dataease.auth.DeLinkPermit;
|
||||
import io.dataease.chart.dao.auto.entity.CoreChartView;
|
||||
import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
@ -108,6 +109,7 @@ public class VisualizationLinkageService implements VisualizationLinkageApi {
|
||||
return new BaseRspModel();
|
||||
}
|
||||
|
||||
@DeLinkPermit
|
||||
@Override
|
||||
public Map<String, List<String>> getVisualizationAllLinkageInfo(Long dvId) {
|
||||
List<LinkageInfoDTO> info = extVisualizationLinkageMapper.getPanelAllLinkageInfo(dvId);
|
||||
|
||||
@ -2,13 +2,13 @@ package io.dataease.visualization.server;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.ibm.icu.impl.coll.CollationLoader;
|
||||
import io.dataease.api.dataset.vo.CoreDatasetGroupVO;
|
||||
import io.dataease.api.dataset.vo.CoreDatasetTableFieldVO;
|
||||
import io.dataease.api.visualization.VisualizationOuterParamsApi;
|
||||
import io.dataease.api.visualization.dto.VisualizationOuterParamsDTO;
|
||||
import io.dataease.api.visualization.dto.VisualizationOuterParamsInfoDTO;
|
||||
import io.dataease.api.visualization.response.VisualizationOuterParamsBaseResponse;
|
||||
import io.dataease.auth.DeLinkPermit;
|
||||
import io.dataease.dataset.dao.auto.entity.CoreDatasetTable;
|
||||
import io.dataease.dataset.dao.auto.mapper.CoreDatasetTableMapper;
|
||||
import io.dataease.engine.constant.DeTypeConstants;
|
||||
@ -29,7 +29,10 @@ import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -98,6 +101,7 @@ public class VisualizationOuterParamsService implements VisualizationOuterParams
|
||||
|
||||
}
|
||||
|
||||
@DeLinkPermit
|
||||
@Override
|
||||
public VisualizationOuterParamsBaseResponse getOuterParamsInfo(String visualizationId) {
|
||||
List<VisualizationOuterParamsInfoDTO> result = extOuterParamsMapper.getVisualizationOuterParamsInfo(visualizationId);
|
||||
|
||||
@ -5,7 +5,7 @@ spring:
|
||||
username: root
|
||||
password: Password123@mysql
|
||||
messages:
|
||||
basename: i18n/lic,i18n/core,i18n/permissions,i18n/xpack
|
||||
basename: i18n/lic,i18n/core,i18n/permissions,i18n/xpack,i18n/sync
|
||||
flyway:
|
||||
enabled: true
|
||||
table: de_standalone_version
|
||||
|
||||
@ -47,9 +47,9 @@ quartz:
|
||||
dataease:
|
||||
version: '@project.version@'
|
||||
xpack-front-distributed: true
|
||||
origin-list: http://192.168.1.9:9080
|
||||
origin-list: http://127.0.0.1:9080
|
||||
apisix-api:
|
||||
domain: http://192.168.1.9:9180
|
||||
domain: http://127.0.0.1:9180
|
||||
key: edd1c9f034335f136f87ad84b625c8f1
|
||||
|
||||
# springdoc-openapi项目配置
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
INSERT INTO area (id, level, name, pid) VALUES ('156440315', 'district', '大鹏新区', '156440300');
|
||||
|
||||
DELETE ccv
|
||||
FROM
|
||||
core_chart_view ccv
|
||||
INNER JOIN data_visualization_info dvi ON ccv.scene_id = dvi.id
|
||||
WHERE
|
||||
dvi.delete_flag =1;
|
||||
delete from data_visualization_info dvi where dvi.delete_flag =1;
|
||||
|
||||
|
||||
ALTER TABLE `core_chart_view`
|
||||
ADD COLUMN `custom_attr_mobile` longtext NULL COMMENT '图形属性_移动端',
|
||||
ADD COLUMN `custom_style_mobile` longtext NULL COMMENT '组件样式_移动端';
|
||||
@ -1,12 +1,10 @@
|
||||
ALTER TABLE `visualization_outer_params_info`
|
||||
ADD COLUMN `required` tinyint(1) DEFAULT 0 COMMENT '是否必填',
|
||||
ADD COLUMN `required` tinyint(1) DEFAULT 0 COMMENT '是否必填',
|
||||
ADD COLUMN `default_value` varchar(255) DEFAULT NULL COMMENT '默认值 JSON格式',
|
||||
ADD COLUMN `enabled_default` tinyint(1) NULL DEFAULT 0 COMMENT '是否启用默认值';
|
||||
update visualization_outer_params_info
|
||||
set required =0;
|
||||
|
||||
ALTER TABLE `xpack_report_info`
|
||||
ADD COLUMN `show_watermark` tinyint(1) NOT NULL DEFAULT 0 COMMENT '显示水印' AFTER `rid`;
|
||||
|
||||
ALTER TABLE `visualization_link_jump_info`
|
||||
ADD COLUMN `window_size` varchar(255) NULL DEFAULT 'middle' COMMENT '窗口大小large middle small';
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
INSERT INTO area (id, level, name, pid)
|
||||
VALUES ('156440315', 'district', '大鹏新区', '156440300');
|
||||
|
||||
DELETE ccv
|
||||
FROM core_chart_view ccv
|
||||
INNER JOIN data_visualization_info dvi ON ccv.scene_id = dvi.id
|
||||
WHERE dvi.delete_flag = 1;
|
||||
delete
|
||||
from data_visualization_info dvi
|
||||
where dvi.delete_flag = 1;
|
||||
DELETE
|
||||
FROM area
|
||||
where pid = '156710100'
|
||||
OR id = '156710100';
|
||||
|
||||
ALTER TABLE `core_chart_view`
|
||||
ADD COLUMN `custom_attr_mobile` longtext NULL COMMENT '图形属性_移动端' AFTER `custom_attr`,
|
||||
ADD COLUMN `custom_style_mobile` longtext NULL COMMENT '组件样式_移动端' AFTER `custom_style`;
|
||||
|
||||
|
||||
INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||
VALUES (1048232869488627717, 'basic.shareDisable', 'false', 'text', 11);
|
||||
INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||
VALUES (1048232869488627718, 'basic.sharePeRequire', 'false', 'text', 12);
|
||||
@ -62,3 +62,52 @@ i18n_day=Day
|
||||
i18n_hour=Hour
|
||||
i18n_minute=Minute
|
||||
i18n_second=Second
|
||||
|
||||
i18n_no_datasource_permission_to_create_column=No datasource permission, cannot create column
|
||||
i18n_df_folder_cannot_to_search=Folder cannot for search data
|
||||
i18n_df_no_primary_key=No primary key
|
||||
i18n_df_cannot_operate_folder=Cannot Operate Folder
|
||||
i18n_df_cannot_be_none=[%s] Cannot be null
|
||||
i18n_df_value_cannot_be_none=[%s] value: %s Cannot be null
|
||||
i18n_df_value_exists_in_database=[%s] value: %s Exists in database
|
||||
i18n_df_data=Data
|
||||
i18n_df_start=Start
|
||||
i18n_df_end=End
|
||||
i18n_df_datasource_not_found=datasource not found
|
||||
i18n_df_datasource_does_not_enable_data_filling=function of dataFilling is not enabled
|
||||
i18n_df_builtin_datasource=builtin datasource
|
||||
i18n_df_folder_required=folder required
|
||||
i18n_df_form_not_exists=form not exists
|
||||
i18n_df_name_can_not_empty=name can not empty
|
||||
i18n_df_template=template
|
||||
i18n_df_task_status_is_null_or_finished=task status is null or finished
|
||||
i18n_df_task_need_task_id=task need taskID
|
||||
i18n_df_not_current_task_user=not current task user
|
||||
i18n_df_miss_parameter=miss parameter
|
||||
i18n_df_no_running_instance=no running instance
|
||||
i18n_df_value=value
|
||||
i18n_df_format_error=parse error
|
||||
i18n_df_cannot_earlier_than=cannot earlier than
|
||||
i18n_df_cannot_be_all_null=cannot be all null
|
||||
i18n_df_value_not_in_range=value not in range
|
||||
i18n_df_value_value_not_in_range=value: %s not in range
|
||||
i18n_df_required=required
|
||||
i18n_df_must_unique=must be unique
|
||||
i18n_df_excel_parsing_error=Excel parse error
|
||||
i18n_df_excel_is_empty=Excel is empty
|
||||
i18n_df_excel_template_column_not_fit=count of template columns are not fit
|
||||
i18n_df_selection=selection
|
||||
i18n_df_date_format=date format
|
||||
i18n_df_integer=integer
|
||||
i18n_df_decimal=decimal
|
||||
i18n_df_multiple_value_split=use ';' to split multiple value
|
||||
i18n_df_email_type=email type
|
||||
i18n_df_phone_type=phone type
|
||||
|
||||
|
||||
|
||||
i18n_copilot_cross_ds_error=This feature is not supported for cross-source datasets.
|
||||
|
||||
i18n_template_recommend=Recommend
|
||||
i18n_template_recent=Recently Used
|
||||
|
||||
|
||||
@ -81,3 +81,51 @@ i18n_day=\u5929
|
||||
i18n_hour=\u5C0F\u65F6
|
||||
i18n_minute=\u5206\u949F
|
||||
i18n_second=\u79D2
|
||||
|
||||
i18n_no_datasource_permission_to_create_column=\u65E0\u6570\u636E\u6E90\u8BBF\u95EE\u6743\u9650\uFF0C\u65E0\u6CD5\u521B\u5EFA\u8868\u5B57\u6BB5
|
||||
i18n_df_folder_cannot_to_search=\u6587\u4EF6\u5939\u4E0D\u80FD\u67E5\u8BE2\u6570\u636E
|
||||
i18n_df_no_primary_key=\u6CA1\u6709\u4E3B\u952E
|
||||
i18n_df_cannot_operate_folder=\u4E0D\u80FD\u64CD\u4F5C\u6587\u4EF6\u5939
|
||||
i18n_df_cannot_be_none=[%s] \u4E0D\u80FD\u4E3A\u7A7A
|
||||
i18n_df_value_cannot_be_none=[%s] \u503C: %s \u4E0D\u80FD\u4E3A\u7A7A
|
||||
i18n_df_value_exists_in_database=[%s] \u503C: %s \u5728\u6570\u636E\u5E93\u4E2D\u5DF2\u5B58\u5728, \u4E0D\u80FD\u91CD\u590D
|
||||
i18n_df_data=\u6570\u636E
|
||||
i18n_df_start=\u5F00\u59CB
|
||||
i18n_df_end=\u7ED3\u675F
|
||||
i18n_df_datasource_not_found=\u6CA1\u6709\u627E\u5230\u6570\u636E\u6E90
|
||||
i18n_df_datasource_does_not_enable_data_filling=\u8BE5\u6570\u636E\u6E90\u6CA1\u6709\u542F\u7528\u6570\u636E\u586B\u62A5\u914D\u7F6E
|
||||
i18n_df_builtin_datasource=\u5185\u5EFA\u6570\u636E\u5E93
|
||||
i18n_df_folder_required=\u76EE\u5F55\u5FC5\u9009
|
||||
i18n_df_form_not_exists=\u8868\u5355\u4E0D\u5B58\u5728
|
||||
i18n_df_name_can_not_empty=\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A
|
||||
i18n_df_template=\u6A21\u677F
|
||||
i18n_df_task_status_is_null_or_finished=\u4EFB\u52A1\u72B6\u6001\u4E3A\u7A7A\u6216\u5DF2\u5B8C\u6210
|
||||
i18n_df_task_need_task_id=\u9700\u6307\u5B9A\u4EFB\u52A1ID
|
||||
i18n_df_not_current_task_user=\u4E0D\u662F\u5F53\u524D\u4EFB\u52A1\u7684\u76EE\u6807\u7528\u6237
|
||||
i18n_df_miss_parameter=\u7F3A\u5931\u53C2\u6570
|
||||
i18n_df_no_running_instance=\u5F53\u524D\u4EFB\u52A1\u6682\u65F6\u65E0\u8FD0\u884C\u5B9E\u4F8B
|
||||
i18n_df_value=\u503C
|
||||
i18n_df_format_error=\u683C\u5F0F\u89E3\u6790\u9519\u8BEF
|
||||
i18n_df_cannot_earlier_than=\u4E0D\u80FD\u65E9\u4E8E
|
||||
i18n_df_cannot_be_all_null=\u4E0D\u80FD\u53EA\u6709\u4E00\u4E2A\u4E3A\u7A7A
|
||||
i18n_df_value_not_in_range=\u503C\u4E0D\u5728\u8303\u56F4\u5185
|
||||
i18n_df_value_value_not_in_range=\u503C: %s \u4E0D\u5728\u8303\u56F4\u5185
|
||||
i18n_df_required=\u5FC5\u586B
|
||||
i18n_df_must_unique=\u4E0D\u5141\u8BB8\u91CD\u590D\u503C
|
||||
i18n_df_excel_parsing_error=Excel\u89E3\u6790\u9519\u8BEF
|
||||
i18n_df_excel_is_empty=\u8BE5Excel\u6CA1\u6709\u6570\u636E
|
||||
i18n_df_excel_template_column_not_fit=\u6A21\u677F\u5B57\u6BB5\u4E2A\u6570\u4E0D\u5339\u914D
|
||||
i18n_df_selection=\u9009\u9879\u503C\u4E3A
|
||||
i18n_df_date_format=\u65E5\u671F\u683C\u5F0F
|
||||
i18n_df_integer=\u6574\u5F62\u6570\u5B57
|
||||
i18n_df_decimal=\u5C0F\u6570\u6570\u5B57
|
||||
i18n_df_multiple_value_split=\u591A\u4E2A\u503C\u4F7F\u7528\u5206\u53F7";"\u5206\u5272
|
||||
i18n_df_email_type=\u90AE\u7BB1\u683C\u5F0F
|
||||
i18n_df_phone_type=\u624B\u673A\u53F7\u683C\u5F0F
|
||||
|
||||
|
||||
|
||||
i18n_copilot_cross_ds_error=\u8DE8\u6E90\u6570\u636E\u96C6\u4E0D\u652F\u6301\u8BE5\u529F\u80FD
|
||||
|
||||
i18n_template_recommend=\u63A8\u8350
|
||||
i18n_template_recent=\u6700\u8FD1\u4F7F\u7528
|
||||
|
||||
@ -2,23 +2,38 @@ login.validator.name1=\u8CEC\u865F/\u90F5\u7BB1/\u624B\u6A5F\u865F\u4E0D\u80FD\u
|
||||
login.validator.pwd1=\u5BC6\u78BC\u4E0D\u80FD\u70BA\u7A7A
|
||||
|
||||
i18n_menu.home=\u9996\u9801
|
||||
i18n_menu.workbranch=\u5DE5\u4F5C\u81FA
|
||||
i18n_menu.workbranch=\u5DE5\u4F5C\u53F0
|
||||
i18n_menu.visualized=\u53EF\u8996\u5316
|
||||
i18n_menu.template=\u6A21\u7248
|
||||
i18n_menu.application=\u61C9\u7528
|
||||
i18n_menu.system=\u7CFB\u7D71\u7BA1\u7406
|
||||
|
||||
i18n_menu.template-market=\u6A21\u677F\u5E02\u5834
|
||||
i18n_menu.template-setting=\u6A21\u677F\u7BA1\u7406
|
||||
i18n_menu.view=\u6578\u64DA\u5C55\u793A
|
||||
i18n_menu.data=\u6578\u64DA\u6E96\u5099
|
||||
i18n_menu.data=\u6578\u64DA\u51C6\u5099
|
||||
i18n_menu.panel=\u5100\u8868\u677F
|
||||
i18n_menu.data-filling-manage=\u6578\u64DA\u586B\u5831
|
||||
i18n_menu.screen=\u6578\u64DA\u5927\u5C4F
|
||||
i18n_menu.dataset=\u6578\u64DA\u96C6
|
||||
i18n_menu.datasource=\u6578\u64DA\u6E90
|
||||
i18n_menu.user=\u7528\u6236\u7BA1\u7406
|
||||
i18n_menu.org=\u7D44\u7E54\u7BA1\u7406
|
||||
i18n_menu.auth=\u6B0A\u9650\u914D\u7F6E
|
||||
i18n_menu.sysVariable=\u7CFB\u7EDF\u53D8\u91CF
|
||||
i18n_field_name_repeat=\u5177\u6709\u91CD\u8907\u7684\u6B04\u4F4D\u540D\u7A31\uFF1A
|
||||
i18n_menu.report=\u5B9A\u6642\u5831\u544A
|
||||
i18n_menu.sync=\u540C\u6B65\u7BA1\u7406
|
||||
i18n_menu.association=\u8840\u7DE3\u5206\u6790
|
||||
i18n_menu.threshold=\u544A\u8B66\u7BA1\u7406
|
||||
i18n_menu.summary=\u6982\u89BD
|
||||
i18n_menu.ds=\u6578\u64DA\u9023\u63A5\u7BA1\u7406
|
||||
i18n_menu.task=\u4EFB\u52D9\u7BA1\u7406
|
||||
i18n_menu.embedded=\u5D4C\u5165\u5F0F\u7BA1\u7406
|
||||
i18n_menu.plugin=\u63D2\u4EF6\u7BA1\u7406
|
||||
i18n_menu.platform=\u5E73\u53F0\u5C0D\u63A5
|
||||
i18n_menu.appearance=\u5916\u89C0\u914D\u7F6E
|
||||
i18n_menu.sysVariable=\u7CFB\u7D71\u8B8A\u91CF
|
||||
i18n_menu.sysTypeface=\u5B57\u9AD4\u7BA1\u7406
|
||||
i18n_menu.font=\u5B57\u9AD4\u7BA1\u7406
|
||||
i18n_field_name_repeat=\u6709\u91CD\u5FA9\u5B57\u6BB5\u540D\uFF1A
|
||||
i18n_pid_not_eq_id=\u79FB\u52D5\u76EE\u6A19\u4E0D\u80FD\u662F\u81EA\u5DF1\u6216\u5B50\u76EE\u9304
|
||||
i18n_ds_name_exists=\u8A72\u5206\u7D44\u4E0B\u540D\u7A31\u91CD\u5FA9
|
||||
i18n_table_id_can_not_empty=\u67E5\u8A62\u7BC0\u9EDE\u4E0D\u80FD\u70BA\u7A7A
|
||||
@ -32,14 +47,14 @@ i18n_union_field_can_not_empty=\u95DC\u806F\u5B57\u6BB5\u4E0D\u80FD\u70BA\u7A7A
|
||||
i18n_table_duplicate=\u76F8\u540C\u7BC0\u9EDE\u9700\u91CD\u65B0\u62D6\u5165\u624D\u80FD\u7E7C\u7E8C\u65B0\u5EFA\u6578\u64DA\u96C6
|
||||
i18n_no_column_permission=\u6C92\u6709\u5217\u6B0A\u9650
|
||||
i18n_fetch_error=SQL\u57F7\u884C\u5931\u6557\uFF0C\u8ACB\u6AA2\u67E5\u8868\u3001\u5B57\u6BB5\u3001\u95DC\u806F\u95DC\u7CFB\u7B49\u4FE1\u606F\u662F\u5426\u6B63\u78BA\u4E26\u91CD\u65B0\u7DE8\u8F2F\u3002
|
||||
i18n_no_datasource_permission=\u65E0\u6570\u636E\u6E90\u8BBF\u95EE\u6743\u9650
|
||||
i18n_no_dataset_permission=\u65e0\u6570\u636e\u96c6\u8bbf\u95ee\u6743\u9650
|
||||
i18n_no_datasource_permission=\u7121\u6578\u64DA\u6E90\u8A2A\u554F\u6B0A\u9650
|
||||
i18n_no_dataset_permission=\u7121\u6578\u64DA\u96C6\u8A2A\u554F\u6B0A\u9650
|
||||
i18n_not_full=\u7576\u524D\u6578\u64DA\u6E90\u4E0D\u652F\u6301\u5168\u9023\u63A5
|
||||
|
||||
i18n_field_circular_ref=\u5B57\u6BB5\u5B58\u5728\u5FAA\u74B0\u5F15\u7528
|
||||
|
||||
i18n_chart_not_handler=\u7121\u6CD5\u8655\u7406\u8A72\u5716\u8868\u985E\u578B
|
||||
i18n_chart_delete=\u8996\u5716\u4E0D\u5B58\u5728
|
||||
i18n_chart_delete=\u5716\u8868\u4E0D\u5B58\u5728
|
||||
i18n_no_ds=\u6578\u64DA\u96C6\u4E0D\u5B58\u5728\u6216\u6C92\u6709\u6B0A\u9650
|
||||
i18n_datasource_delete=\u6578\u64DA\u6E90\u4E0D\u5B58\u5728
|
||||
i18n_gauge_field_change=\u6240\u7528\u5B57\u6BB5\u767C\u751F\u8B8A\u66F4\uFF0C\u8ACB\u91CD\u65B0\u7DE8\u8F2F
|
||||
@ -53,9 +68,12 @@ i18n_invalid_ds=\u6578\u64DA\u6E90\u7121\u6548
|
||||
i18n_user_disable=\u7528\u6236\u5DF2\u88AB\u7981\u7528\uFF0C\u7121\u6CD5\u767B\u9304
|
||||
i18n_login_name_pwd_err=\u7528\u6236\u540D\u6216\u5BC6\u78BC\u932F\u8AA4
|
||||
i18n_error_login_type=\u767B\u9304\u985E\u578B\u932F\u8AA4
|
||||
i18n_schema_is_empty=schema\u70BA\u7A7A\uFF01
|
||||
i18n_table_name_repeat=\u540D\u7A31\u91CD\u8907:
|
||||
i18n_sql_not_empty=sql\u4E0D\u80FD\u70BA\u7A7A
|
||||
i18n_schema_is_empty=schema \u70BA\u7A7A\uFF01
|
||||
i18n_table_name_repeat=\u540D\u7A31\u91CD\u5FA9:
|
||||
i18n_sql_not_empty=sql \u4E0D\u80FD\u70BA\u7A7A
|
||||
i18n_menu.parameter=\u7CFB\u7D71\u53C3\u6578
|
||||
i18n_user_old_pwd_error=\u539F\u59CB\u5BC6\u78BC\u932F\u8AA4
|
||||
i18n_menu.toolbox-log=\u64CD\u4F5C\u65E5\u5FD7
|
||||
|
||||
i18n_year=\u5E74
|
||||
i18n_month=\u6708
|
||||
@ -63,3 +81,53 @@ i18n_day=\u5929
|
||||
i18n_hour=\u5C0F\u6642
|
||||
i18n_minute=\u5206\u9418
|
||||
i18n_second=\u79D2
|
||||
|
||||
i18n_no_datasource_permission_to_create_column=\u7121\u6578\u64DA\u6E90\u8A2A\u554F\u6B0A\u9650\uFF0C\u7121\u6CD5\u5275\u5EFA\u8868\u5B57\u6BB5
|
||||
i18n_df_folder_cannot_to_search=\u6587\u4EF6\u593E\u4E0D\u80FD\u67E5\u8A62\u6578\u64DA
|
||||
i18n_df_no_primary_key=\u6C92\u6709\u4E3B\u9375
|
||||
i18n_df_cannot_operate_folder=\u4E0D\u80FD\u64CD\u4F5C\u6587\u4EF6\u593E
|
||||
i18n_df_cannot_be_none=[%s] \u4E0D\u80FD\u70BA\u7A7A
|
||||
i18n_df_value_cannot_be_none=[%s] \u503C: %s \u4E0D\u80FD\u70BA\u7A7A
|
||||
i18n_df_value_exists_in_database=[%s] \u503C: %s \u5728\u6578\u64DA\u5EAB\u4E2D\u5DF2\u5B58\u5728, \u4E0D\u80FD\u91CD\u5FA9
|
||||
i18n_df_data=\u6578\u64DA
|
||||
i18n_df_start=\u958B\u59CB
|
||||
i18n_df_end=\u7D50\u675F
|
||||
i18n_df_datasource_not_found=\u6C92\u6709\u627E\u5230\u6578\u64DA\u6E90
|
||||
i18n_df_datasource_does_not_enable_data_filling=\u8A72\u6578\u64DA\u6E90\u6C92\u6709\u555F\u7528\u6578\u64DA\u586B\u5831\u914D\u7F6E
|
||||
i18n_df_builtin_datasource=\u5167\u5EFA\u6578\u64DA\u5EAB
|
||||
i18n_df_folder_required=\u76EE\u9304\u5FC5\u9078
|
||||
i18n_df_form_not_exists=\u8868\u55AE\u4E0D\u5B58\u5728
|
||||
i18n_df_name_can_not_empty=\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A
|
||||
i18n_df_template=\u6A21\u677F
|
||||
i18n_df_task_status_is_null_or_finished=\u4EFB\u52D9\u72C0\u614B\u70BA\u7A7A\u6216\u5DF2\u5B8C\u6210
|
||||
i18n_df_task_need_task_id=\u9700\u6307\u5B9A\u4EFB\u52D9ID
|
||||
i18n_df_not_current_task_user=\u4E0D\u662F\u7576\u524D\u4EFB\u52D9\u7684\u76EE\u6A19\u7528\u6236
|
||||
i18n_df_miss_parameter=\u7F3A\u5931\u53C3\u6578
|
||||
i18n_df_no_running_instance=\u7576\u524D\u4EFB\u52D9\u66AB\u6642\u7121\u904B\u884C\u5BE6\u4F8B
|
||||
i18n_df_value=\u503C
|
||||
i18n_df_format_error=\u683C\u5F0F\u89E3\u6790\u932F\u8AA4
|
||||
i18n_df_cannot_earlier_than=\u4E0D\u80FD\u65E9\u4E8E
|
||||
i18n_df_cannot_be_all_null=\u4E0D\u80FD\u53EA\u6709\u4E00\u500B\u70BA\u7A7A
|
||||
i18n_df_value_not_in_range=\u503C\u4E0D\u5728\u8303\u570D\u5167
|
||||
i18n_df_value_value_not_in_range=\u503C: %s \u4E0D\u5728\u8303\u570D\u5167
|
||||
i18n_df_required=\u5FC5\u586B
|
||||
i18n_df_must_unique=\u4E0D\u5141\u8A31\u91CD\u5FA9\u503C
|
||||
i18n_df_excel_parsing_error=Excel\u89E3\u6790\u932F\u8AA4
|
||||
i18n_df_excel_is_empty=\u8A72Excel\u6C92\u6709\u6578\u64DA
|
||||
i18n_df_excel_template_column_not_fit=\u6A21\u677F\u5B57\u6BB5\u500B\u6578\u4E0D\u5339\u914D
|
||||
i18n_df_selection=\u9078\u9805\u503C\u70BA
|
||||
i18n_df_date_format=\u65E5\u671F\u683C\u5F0F
|
||||
i18n_df_integer=\u6574\u5F62\u6578\u5B57
|
||||
i18n_df_decimal=\u5C0F\u6578\u6578\u5B57
|
||||
i18n_df_multiple_value_split=\u591A\u500B\u503C\u4F7F\u7528\u5206\u865F";"\u5206\u5272
|
||||
i18n_df_email_type=\u90F5\u7BB1\u683C\u5F0F
|
||||
i18n_df_phone_type=\u624B\u6A5F\u865F\u683C\u5F0F
|
||||
|
||||
|
||||
|
||||
i18n_copilot_cross_ds_error=\u8DE8\u6E90\u6578\u64DA\u96C6\u4E0D\u652F\u6301\u8A72\u529F\u80FD
|
||||
|
||||
i18n_template_recommend=\u63A8\u85A6
|
||||
i18n_template_recent=\u6700\u8FD1\u4F7F\u7528
|
||||
|
||||
|
||||
|
||||
@ -19,7 +19,9 @@
|
||||
`ext_label`,
|
||||
`ext_tooltip`,
|
||||
`custom_attr`,
|
||||
`custom_attr_mobile`,
|
||||
`custom_style`,
|
||||
`custom_style_mobile`,
|
||||
`custom_filter`,
|
||||
`drill_fields`,
|
||||
`senior`,
|
||||
@ -59,7 +61,9 @@
|
||||
`ext_label`,
|
||||
`ext_tooltip`,
|
||||
`custom_attr`,
|
||||
`custom_attr_mobile`,
|
||||
`custom_style`,
|
||||
`custom_style_mobile`,
|
||||
`custom_filter`,
|
||||
`drill_fields`,
|
||||
`senior`,
|
||||
@ -419,4 +423,25 @@
|
||||
visualization_report_filter
|
||||
where visualization_report_filter.resource_id = #{dvId} and visualization_report_filter.task_id = #{taskId}
|
||||
</select>
|
||||
|
||||
<delete id="deleteDataVBatch">
|
||||
DELETE
|
||||
FROM
|
||||
data_visualization_info dvi
|
||||
WHERE
|
||||
dvi.id IN
|
||||
<foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
<delete id="deleteViewsBatch">
|
||||
DELETE
|
||||
FROM
|
||||
core_chart_view ccv
|
||||
WHERE
|
||||
ccv.scene_id IN
|
||||
<foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import pkg from '../package.json'
|
||||
import viteCompression from 'vite-plugin-compression'
|
||||
|
||||
export default {
|
||||
plugins: [
|
||||
viteCompression({
|
||||
@ -12,6 +13,7 @@ export default {
|
||||
})
|
||||
],
|
||||
build: {
|
||||
cssCodeSplit: false,
|
||||
rollupOptions: {
|
||||
external: id => /de-xpack/.test(id) || /extensions/.test(id),
|
||||
output: {
|
||||
@ -19,10 +21,15 @@ export default {
|
||||
chunkFileNames: `assets/chunk/[name]-${pkg.version}-${pkg.name}.js`,
|
||||
assetFileNames: `assets/[ext]/[name]-${pkg.version}-${pkg.name}.[ext]`,
|
||||
entryFileNames: `js/[name]-${pkg.version}-${pkg.name}.js`,
|
||||
manualChunks(id: string) {
|
||||
if (id.includes('node_modules')) {
|
||||
return id.toString().split('node_modules/')[1].split('/')[0].toString()
|
||||
}
|
||||
manualChunks: {
|
||||
echarts: ['echarts'],
|
||||
vue: ['vue', 'vue-router', 'pinia', 'vue-i18n', 'mitt'],
|
||||
lodash: ['lodash-es', 'lodash'],
|
||||
library: ['jspdf', '@tinymce/tinymce-vue', 'screenfull'],
|
||||
antv: ['@antv/g2', '@antv/g2plot', '@antv/l7', '@antv/l7plot', '@antv/s2'],
|
||||
tinymce: ['tinymce'],
|
||||
axios: ['axios'],
|
||||
'vuedraggable-es': ['vuedraggable']
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/dataease.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/pages/index/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/pages/index/main.ts"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -3,10 +3,8 @@
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover" />
|
||||
<title>DataEase</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -14,4 +12,4 @@
|
||||
<script type="module" src="/src/pages/mobile/main.ts"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@ -7,7 +7,7 @@
|
||||
"build:flush": "cd ./flushbonading && rimraf ./demo.html && npm i && node ./index.js",
|
||||
"ts:check": "vue-tsc --noEmit",
|
||||
"build:base": "NODE_OPTIONS=--max_old_space_size=4096 vite build --mode base && npm run build:flush",
|
||||
"build:distributed": "NODE_OPTIONS=--max_old_space_size=4096 vite build --mode distributed && npm run build:flush",
|
||||
"build:distributed": "NODE_OPTIONS=--max_old_space_size=5020 vite build --mode distributed && npm run build:flush",
|
||||
"build:lib": "vite build --mode lib",
|
||||
"lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix",
|
||||
"lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
|
||||
|
||||
@ -415,5 +415,9 @@ tinymce.addI18n('zh_CN', {
|
||||
"Whole words": "\u5168\u5b57\u5339\u914d",
|
||||
"Spellcheck": "\u62fc\u5199\u68c0\u67e5",
|
||||
"Caption": "\u6807\u9898",
|
||||
"Insert template": "\u63d2\u5165\u6a21\u677f"
|
||||
"Insert template": "\u63d2\u5165\u6a21\u677f",
|
||||
"Cut column": "\u526a\u5207\u5217",
|
||||
"Copy column": "\u590d\u5236\u5217",
|
||||
"Paste column before": "\u7c98\u8d34\u5230\u524d\u65b9",
|
||||
"Paste column after": "\u7c98\u8d34\u5230\u540e\u65b9"
|
||||
});
|
||||
|
||||
@ -88,7 +88,7 @@ export const saveChart = async (data): Promise<IResponse> => {
|
||||
}
|
||||
|
||||
// 获取单个字段枚举值
|
||||
export const getFieldData = async (fieldId, fieldType, data): Promise<IResponse> => {
|
||||
export const getFieldData = async ({ fieldId, fieldType, data }): Promise<IResponse> => {
|
||||
delete data.data
|
||||
return request
|
||||
.post({ url: `/chartData/getFieldData/${fieldId}/${fieldType}`, data })
|
||||
@ -97,6 +97,14 @@ export const getFieldData = async (fieldId, fieldType, data): Promise<IResponse>
|
||||
})
|
||||
}
|
||||
|
||||
// 获取下钻字段枚举值
|
||||
export const getDrillFieldData = async ({ fieldId, data }): Promise<IResponse> => {
|
||||
delete data.data
|
||||
return request.post({ url: `/chartData/getDrillFieldData/${fieldId}`, data }).then(res => {
|
||||
return res
|
||||
})
|
||||
}
|
||||
|
||||
export const getChartDetail = async (id: string): Promise<IResponse> => {
|
||||
return request.post({ url: `chart/getDetail/${id}`, data: {} }).then(res => {
|
||||
return res
|
||||
|
||||
@ -32,6 +32,8 @@ export const queryFormApi = uid => request.get({ url: `/user/queryById/${uid}` }
|
||||
|
||||
export const personInfoApi = () => request.get({ url: `/user/personInfo` })
|
||||
|
||||
export const ipInfoApi = () => request.get({ url: `/user/ipInfo` })
|
||||
|
||||
export const roleCreateApi = data => request.post({ url: '/role/create', data })
|
||||
|
||||
export const roleEditApi = data => request.post({ url: '/role/edit', data })
|
||||
|
||||
@ -41,6 +41,12 @@ export const queryTreeApi = async (data: BusiTreeRequest): Promise<IResponse> =>
|
||||
})
|
||||
}
|
||||
|
||||
export const queryBusiTreeApi = async (data): Promise<IResponse> => {
|
||||
return request.post({ url: '/dataVisualization/interactiveTree', data }).then(res => {
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
|
||||
export const findDvType = async dvId =>
|
||||
request.get({ url: `/dataVisualization/findDvType/${dvId}` })
|
||||
|
||||
@ -115,3 +121,10 @@ export const queryOuterParamsDsInfo = async dvId => {
|
||||
loading: false
|
||||
})
|
||||
}
|
||||
|
||||
export const queryShareBaseApi = () => {
|
||||
return request.get({
|
||||
url: '/sysParameter/shareBase',
|
||||
loading: false
|
||||
})
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 742 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 739 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 742 KiB After Width: | Height: | Size: 61 KiB |
1
core/core-frontend/src/assets/svg/es-ds.svg
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 741 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 739 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 742 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 744 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 739 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 744 KiB After Width: | Height: | Size: 62 KiB |
@ -1 +1,3 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1715769658859" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4704" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M1023.853735 948.673618v75.25325H596.248536V948.673618zM511.926868 0.073132a511.926868 511.926868 0 0 1 511.926867 511.926868h-75.253249a436.600486 436.600486 0 1 0-436.600486 436.600486h5.119269v75.253249h-5.119269a511.926868 511.926868 0 1 1 0-1023.853735z m511.926867 803.505785v75.25325H596.248536v-75.180117zM362.590487 290.116269l192.11884 110.941866 192.11884 110.941865-192.11884 110.941865-192.11884 110.941866V290.189402zM1023.853735 658.484217v75.399514H596.248536V658.630481zM437.843737 420.438223v182.831024l79.202399-45.780888 79.2024-45.707756-79.2024-45.707756z" p-id="4705"></path></svg>
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M36.6667 5C37.5871 5 38.3333 5.83947 38.3333 6.875V33.125C38.3333 34.1605 37.5871 35 36.6667 35H3.33333C2.41286 35 1.66667 34.1605 1.66667 33.125V6.875C1.66667 5.83947 2.41286 5 3.33333 5H36.6667ZM14.3426 25.5486C14.7543 26.3719 15.7554 26.7057 16.5787 26.294L26.1853 21.4907C26.5078 21.3295 26.7693 21.0679 26.9306 20.7454C27.3423 19.9221 27.0086 18.9209 26.1853 18.5093L16.5787 13.706C16.3473 13.5903 16.0921 13.5301 15.8333 13.5301C14.9129 13.5301 14.1667 14.2763 14.1667 15.1967V24.8033C14.1667 25.062 14.2269 25.3172 14.3426 25.5486ZM10 9.16667H6.66667V14.1667H10V9.16667ZM10 17.5H6.66667V22.5H10V17.5ZM10 25.8333H6.66667V30.8333H10V25.8333ZM33.3333 9.16667H30V14.1667H33.3333V9.16667ZM30 17.5H33.3333V22.5H30V17.5ZM30 25.8333H33.3333V30.8333H30V25.8333Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 938 B After Width: | Height: | Size: 904 B |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 715 B |
@ -1,4 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.85738 4.85729L9.98911 11.989L2.85738 19.1207C2.66212 19.316 2.66212 19.6326 2.85738 19.8279L3.56449 20.535C3.75975 20.7302 4.07634 20.7302 4.2716 20.535L12.1104 12.6961C12.501 12.3056 12.501 11.6724 12.1104 11.2819L4.2716 3.44308C4.07634 3.24782 3.75975 3.24782 3.56449 3.44308L2.85738 4.15018C2.66212 4.34545 2.66212 4.66203 2.85738 4.85729Z" fill="#1F2329"/>
|
||||
<path d="M11.7431 4.85729L18.8749 11.989L11.7431 19.1207C11.5479 19.316 11.5479 19.6326 11.7431 19.8279L12.4502 20.535C12.6455 20.7302 12.9621 20.7302 13.1573 20.535L20.9962 12.6961C21.3867 12.3056 21.3867 11.6724 20.9962 11.2819L13.1573 3.44308C12.9621 3.24782 12.6455 3.24782 12.4502 3.44308L11.7431 4.15018C11.5479 4.34545 11.5479 4.66203 11.7431 4.85729Z" fill="#1F2329"/>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.85738 4.85729L9.98911 11.989L2.85738 19.1207C2.66212 19.316 2.66212 19.6326 2.85738 19.8279L3.56449 20.535C3.75975 20.7302 4.07634 20.7302 4.2716 20.535L12.1104 12.6961C12.501 12.3056 12.501 11.6724 12.1104 11.2819L4.2716 3.44308C4.07634 3.24782 3.75975 3.24782 3.56449 3.44308L2.85738 4.15018C2.66212 4.34545 2.66212 4.66203 2.85738 4.85729Z" />
|
||||
<path d="M11.7431 4.85729L18.8749 11.989L11.7431 19.1207C11.5479 19.316 11.5479 19.6326 11.7431 19.8279L12.4502 20.535C12.6455 20.7302 12.9621 20.7302 13.1573 20.535L20.9962 12.6961C21.3867 12.3056 21.3867 11.6724 20.9962 11.2819L13.1573 3.44308C12.9621 3.24782 12.6455 3.24782 12.4502 3.44308L11.7431 4.15018C11.5479 4.34545 11.5479 4.66203 11.7431 4.85729Z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 853 B After Width: | Height: | Size: 812 B |
@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21 18.5V21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21V18.5C3 18.2239 3.22386 18 3.5 18H4.5C4.77614 18 5 18.2239 5 18.5V20H19V18.5C19 18.2239 19.2239 18 19.5 18H20.5C20.7761 18 21 18.2239 21 18.5ZM13 14.0357L16.0105 11.0252C16.2057 10.83 16.5223 10.83 16.7176 11.0252L17.4247 11.7324C17.6199 11.9276 17.6199 12.2442 17.4247 12.4395L12.4749 17.3892C12.3773 17.4868 12.2493 17.5357 12.1214 17.5357C11.9934 17.5357 11.8655 17.4868 11.7678 17.3892L6.81808 12.4395C6.62282 12.2442 6.62282 11.9276 6.81808 11.7324L7.52519 11.0252C7.72045 10.83 8.03703 10.83 8.2323 11.0252L11 13.793V3C11 2.72386 11.2239 2.5 11.5 2.5H12.5C12.7761 2.5 13 2.72386 13 3V14.0357Z" fill="#1F2329"/>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21 18.5V21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21V18.5C3 18.2239 3.22386 18 3.5 18H4.5C4.77614 18 5 18.2239 5 18.5V20H19V18.5C19 18.2239 19.2239 18 19.5 18H20.5C20.7761 18 21 18.2239 21 18.5ZM13 14.0357L16.0105 11.0252C16.2057 10.83 16.5223 10.83 16.7176 11.0252L17.4247 11.7324C17.6199 11.9276 17.6199 12.2442 17.4247 12.4395L12.4749 17.3892C12.3773 17.4868 12.2493 17.5357 12.1214 17.5357C11.9934 17.5357 11.8655 17.4868 11.7678 17.3892L6.81808 12.4395C6.62282 12.2442 6.62282 11.9276 6.81808 11.7324L7.52519 11.0252C7.72045 10.83 8.03703 10.83 8.2323 11.0252L11 13.793V3C11 2.72386 11.2239 2.5 11.5 2.5H12.5C12.7761 2.5 13 2.72386 13 3V14.0357Z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 796 B After Width: | Height: | Size: 769 B |
@ -1,3 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.1518 11.5968C7.31452 11.4341 7.57834 11.4341 7.74106 11.5968L8.33031 12.186C8.49303 12.3487 8.49303 12.6126 8.33031 12.7753L4.99587 16.1086H7.36621C7.59633 16.1086 7.78288 16.2952 7.78288 16.5253V17.3586C7.78288 17.5887 7.59633 17.7753 7.36621 17.7753H3.05555C2.82544 17.7753 2.6171 17.682 2.4663 17.5312C2.3155 17.3804 2.22222 17.1721 2.22222 16.9419V12.6421C2.22222 12.412 2.40877 12.2255 2.63889 12.2255H3.47222C3.70234 12.2255 3.88889 12.412 3.88889 12.6421V14.8586L7.1518 11.5968ZM16.9367 2.22217C17.1668 2.22217 17.3751 2.31544 17.5259 2.46625C17.6767 2.61705 17.77 2.82538 17.77 3.0555V7.35531C17.77 7.58543 17.5835 7.77198 17.3533 7.77198H16.52C16.2899 7.77198 16.1033 7.58543 16.1033 7.35531V5.13888L12.8404 8.40068C12.6777 8.5634 12.4139 8.5634 12.2512 8.40068L11.6619 7.81142C11.4992 7.6487 11.4992 7.38489 11.6619 7.22217L14.9964 3.88883H12.626C12.3959 3.88883 12.2094 3.70229 12.2094 3.47217V2.63883C12.2094 2.40872 12.3959 2.22217 12.626 2.22217H16.9367Z" fill="#1F2329"/>
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.1518 11.5968C7.31452 11.4341 7.57834 11.4341 7.74106 11.5968L8.33031 12.186C8.49303 12.3487 8.49303 12.6126 8.33031 12.7753L4.99587 16.1086H7.36621C7.59633 16.1086 7.78288 16.2952 7.78288 16.5253V17.3586C7.78288 17.5887 7.59633 17.7753 7.36621 17.7753H3.05555C2.82544 17.7753 2.6171 17.682 2.4663 17.5312C2.3155 17.3804 2.22222 17.1721 2.22222 16.9419V12.6421C2.22222 12.412 2.40877 12.2255 2.63889 12.2255H3.47222C3.70234 12.2255 3.88889 12.412 3.88889 12.6421V14.8586L7.1518 11.5968ZM16.9367 2.22217C17.1668 2.22217 17.3751 2.31544 17.5259 2.46625C17.6767 2.61705 17.77 2.82538 17.77 3.0555V7.35531C17.77 7.58543 17.5835 7.77198 17.3533 7.77198H16.52C16.2899 7.77198 16.1033 7.58543 16.1033 7.35531V5.13888L12.8404 8.40068C12.6777 8.5634 12.4139 8.5634 12.2512 8.40068L11.6619 7.81142C11.4992 7.6487 11.4992 7.38489 11.6619 7.22217L14.9964 3.88883H12.626C12.3959 3.88883 12.2094 3.70229 12.2094 3.47217V2.63883C12.2094 2.40872 12.3959 2.22217 12.626 2.22217H16.9367Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.00839 13.9974C9.28453 13.9974 9.53453 14.1093 9.71549 14.2903C9.89646 14.4712 10.0084 14.7212 10.0084 14.9974V20.1572C10.0084 20.4333 9.78453 20.6572 9.50839 20.6572H8.50839C8.23224 20.6572 8.00839 20.4333 8.00839 20.1572V17.4974L4.09289 21.4116C3.89762 21.6069 3.58104 21.6069 3.38578 21.4116L2.67867 20.7045C2.48341 20.5092 2.48341 20.1927 2.67867 19.9974L6.68001 15.9974H3.83559C3.55945 15.9974 3.33559 15.7735 3.33559 15.4974V14.4974C3.33559 14.2212 3.55945 13.9974 3.83559 13.9974H9.00839ZM19.919 2.58865C20.1142 2.39338 20.4308 2.39338 20.6261 2.58865L21.3332 3.29575C21.5284 3.49102 21.5284 3.8076 21.3332 4.00286L17.3318 8.00286H20.1763C20.4524 8.00286 20.6763 8.22672 20.6763 8.50286V9.50286C20.6763 9.779 20.4524 10.0029 20.1763 10.0029H15.0035C14.7273 10.0029 14.4773 9.89093 14.2964 9.70997C14.1154 9.529 14.0035 9.279 14.0035 9.00286V3.84309C14.0035 3.56695 14.2273 3.34309 14.5035 3.34309H15.5035C15.7796 3.34309 16.0035 3.56695 16.0035 3.84309V6.50281L19.919 2.58865Z" fill="#1F2329"/>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.00839 13.9974C9.28453 13.9974 9.53453 14.1093 9.71549 14.2903C9.89646 14.4712 10.0084 14.7212 10.0084 14.9974V20.1572C10.0084 20.4333 9.78453 20.6572 9.50839 20.6572H8.50839C8.23224 20.6572 8.00839 20.4333 8.00839 20.1572V17.4974L4.09289 21.4116C3.89762 21.6069 3.58104 21.6069 3.38578 21.4116L2.67867 20.7045C2.48341 20.5092 2.48341 20.1927 2.67867 19.9974L6.68001 15.9974H3.83559C3.55945 15.9974 3.33559 15.7735 3.33559 15.4974V14.4974C3.33559 14.2212 3.55945 13.9974 3.83559 13.9974H9.00839ZM19.919 2.58865C20.1142 2.39338 20.4308 2.39338 20.6261 2.58865L21.3332 3.29575C21.5284 3.49102 21.5284 3.8076 21.3332 4.00286L17.3318 8.00286H20.1763C20.4524 8.00286 20.6763 8.22672 20.6763 8.50286V9.50286C20.6763 9.779 20.4524 10.0029 20.1763 10.0029H15.0035C14.7273 10.0029 14.4773 9.89093 14.2964 9.70997C14.1154 9.529 14.0035 9.279 14.0035 9.00286V3.84309C14.0035 3.56695 14.2273 3.34309 14.5035 3.34309H15.5035C15.7796 3.34309 16.0035 3.56695 16.0035 3.84309V6.50281L19.919 2.58865Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |