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"
|
||||
@ -11,13 +11,12 @@
|
||||
|
||||
## 什么是 DataEase?
|
||||
|
||||
DataEase 是开源的数据可视化分析工具,帮助用户快速分析数据并洞察业务趋势,从而实现业务的改进与优化。DataEase 支持丰富的数据源连接,能够通过拖拉拽方式快速制作图表,并可以方便的与他人分享。
|
||||
DataEase 是开源的 BI 工具,帮助用户快速分析数据并洞察业务趋势,从而实现业务的改进与优化。DataEase 支持丰富的数据源连接,能够通过拖拉拽方式快速制作图表,并可以方便的与他人分享。
|
||||
|
||||
**DataEase 的优势:**
|
||||
|
||||
- 开源开放:零门槛,线上快速获取和安装,按月迭代;
|
||||
- 简单易用:极易上手,通过鼠标点击和拖拽即可完成分析;
|
||||
- AI Copilot:借助生成式 AI 技术,通过自然语言交互实现数据即问即答;
|
||||
- 全场景支持:多平台安装和多样化嵌入支持;
|
||||
- 安全分享:支持多种数据分享方式,确保数据安全。
|
||||
|
||||
@ -29,6 +28,8 @@ DataEase 是开源的数据可视化分析工具,帮助用户快速分析数
|
||||
- 数据文件: Excel、CSV 等;
|
||||
- API 数据源。
|
||||
|
||||
如果您需要向团队介绍 DataEase,可以使用这个 [官方 PPT 材料](https://fit2cloud.com/dataease/download/introduce-dataease_202411.pdf)。
|
||||
|
||||
## 快速开始
|
||||
|
||||
```
|
||||
|
||||
@ -131,6 +131,22 @@
|
||||
<artifactId>flexmark-all</artifactId>
|
||||
<version>${flexmark.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>xpack-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>xpack-permissions</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>xpack-sync</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -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;
|
||||
@ -364,14 +368,45 @@ public class DefaultChartHandler extends AbstractChartPlugin {
|
||||
return conditionField;
|
||||
}
|
||||
|
||||
protected String assistSQL(String sql, List<ChartViewFieldDTO> assistFields) {
|
||||
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";
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -98,7 +98,7 @@ public class TableInfoHandler extends DefaultChartHandler {
|
||||
}
|
||||
}
|
||||
assert fieldDTO != null;
|
||||
if (fieldDTO.isAgg()) {
|
||||
if (fieldDTO != null && fieldDTO.isAgg()) {
|
||||
sqlMeta.getXFields().get(i).setFieldName("'-'");
|
||||
}
|
||||
}
|
||||
@ -154,7 +154,7 @@ public class TableInfoHandler extends DefaultChartHandler {
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(querySql, assistFields);
|
||||
var assistSql = assistSQL(querySql, assistFields, dsMap);
|
||||
req.setQuery(assistSql);
|
||||
logger.debug("calcite assistSql sql: " + assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
|
||||
@ -34,7 +34,7 @@ public class TableNormalHandler 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");
|
||||
|
||||
@ -33,7 +33,7 @@ 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 {
|
||||
@ -45,7 +45,7 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
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");
|
||||
@ -98,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);
|
||||
@ -137,7 +137,7 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
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);
|
||||
@ -181,7 +181,7 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
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);
|
||||
@ -202,7 +202,7 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
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);
|
||||
@ -223,7 +223,7 @@ public class TablePivotHandler extends GroupChartHandler {
|
||||
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>>();
|
||||
@ -231,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);
|
||||
@ -284,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);
|
||||
@ -298,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++) {
|
||||
@ -315,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);
|
||||
|
||||
@ -316,6 +316,11 @@ public class ChartDataManage {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,9 +362,9 @@ public class ChartViewThresholdManage {
|
||||
}
|
||||
} else {
|
||||
if (timeFlag == 4) {
|
||||
return now.withDayOfMonth(1).format(formatter);
|
||||
return now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).format(formatter);
|
||||
} else if (timeFlag == 5) {
|
||||
return now.plusMonths(1).withDayOfMonth(1).minusDays(1).format(formatter);
|
||||
return now.plusMonths(1).withDayOfMonth(1).minusDays(1).withHour(0).withMinute(0).withSecond(0).format(formatter);
|
||||
} else {
|
||||
return getCustomTimeValue(format, 3, suffix, count, true);
|
||||
}
|
||||
@ -381,7 +381,9 @@ public class ChartViewThresholdManage {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
String fullFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
int len = format.length();
|
||||
if (!hasTime) {
|
||||
if (hasTime) {
|
||||
now = now.withHour(0).withMinute(0).withSecond(0);
|
||||
} else {
|
||||
len = Math.min(len, 10);
|
||||
}
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(fullFormat.substring(0, len));
|
||||
|
||||
@ -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,8 +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;
|
||||
@ -73,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 {
|
||||
@ -123,13 +128,105 @@ public class ChartDataServer implements ChartDataApi {
|
||||
request.setHeader(dsHeader);
|
||||
request.setExcelTypes(dsTypes);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(tableRow)) {
|
||||
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);
|
||||
request.setData(chartViewInfo.getData());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@ -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("/**");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -259,6 +260,7 @@ public class DatasetDataManage {
|
||||
|
||||
public Long getDatasetTotal(Long datasetGroupId) throws Exception {
|
||||
DatasetGroupInfoDTO dto = datasetGroupManage.getForCount(datasetGroupId);
|
||||
if (ObjectUtils.isEmpty(dto)) return 0L;
|
||||
if (StringUtils.equalsIgnoreCase(dto.getNodeType(), "dataset")) {
|
||||
return getDatasetTotal(dto, null, new ChartExtRequest());
|
||||
}
|
||||
@ -452,11 +454,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -209,8 +209,6 @@ public class DatasetSQLManage {
|
||||
String tablePrefix = "";
|
||||
String tableSuffix = "";
|
||||
if (ObjectUtils.isNotEmpty(currentSQLObj.getTableSchema())) {
|
||||
ts = currentSQLObj.getTableSchema() + ".";
|
||||
|
||||
if (isCross) {
|
||||
tablePrefix = "`";
|
||||
tableSuffix = "`";
|
||||
@ -219,6 +217,8 @@ public class DatasetSQLManage {
|
||||
tablePrefix = datasourceType.getPrefix();
|
||||
tableSuffix = datasourceType.getSuffix();
|
||||
}
|
||||
|
||||
ts = tablePrefix + currentSQLObj.getTableSchema() + tableSuffix + ".";
|
||||
}
|
||||
// build join
|
||||
join.append(" ").append(joinType).append(" ")
|
||||
|
||||
@ -44,7 +44,6 @@ public class TableUtils {
|
||||
String prefix = "";
|
||||
String suffix = "";
|
||||
if (StringUtils.isNotEmpty(sqlObj.getTableSchema())) {
|
||||
schema = sqlObj.getTableSchema() + ".";
|
||||
if (isCross) {
|
||||
prefix = "`";
|
||||
suffix = "`";
|
||||
@ -52,6 +51,7 @@ public class TableUtils {
|
||||
prefix = datasourceType.getPrefix();
|
||||
suffix = datasourceType.getSuffix();
|
||||
}
|
||||
schema = prefix + sqlObj.getTableSchema() + suffix + ".";
|
||||
}
|
||||
return schema + prefix + sqlObj.getTableName() + suffix + " " + sqlObj.getTableAlias();
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ 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;
|
||||
@ -11,12 +10,10 @@ 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;
|
||||
@ -98,7 +95,7 @@ public class EsProvider extends Provider {
|
||||
try {
|
||||
String sql;
|
||||
if (datasourceRequest.getTable() != null) {
|
||||
sql = "select * from " + datasourceRequest.getTable() + " limit 0";
|
||||
sql = "select * from \"" + datasourceRequest.getTable() + "\" limit 0";
|
||||
} else {
|
||||
sql = datasourceRequest.getQuery();
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ public class MysqlEngineProvider extends EngineProvider {
|
||||
int size = tableField.getPrecision() * 4;
|
||||
switch (tableField.getDeExtractType()) {
|
||||
case 0:
|
||||
Column_Fields.append("varchar(2048)").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("varchar(2048)").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(() -> {
|
||||
@ -479,6 +483,23 @@ public class DatasourceServer implements DatasourceApi {
|
||||
return getDatasourceDTOById(datasourceId, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatasourceDTO getSimpleDs(Long datasourceId) throws DEException {
|
||||
CoreDatasource datasource = datasourceMapper.selectById(datasourceId);
|
||||
if (datasource == null) {
|
||||
DEException.throwException("不存在的数据源!");
|
||||
}
|
||||
if (datasource.getType().equalsIgnoreCase("api")) {
|
||||
datasource.setConfiguration("[]");
|
||||
} else {
|
||||
datasource.setConfiguration("");
|
||||
}
|
||||
datasource.setConfiguration("");
|
||||
DatasourceDTO datasourceDTO = new DatasourceDTO();
|
||||
BeanUtils.copyBean(datasourceDTO, datasource);
|
||||
return datasourceDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatasourceDTO get(Long datasourceId) throws DEException {
|
||||
return getDatasourceDTOById(datasourceId, false);
|
||||
@ -1128,8 +1149,12 @@ public class DatasourceServer implements DatasourceApi {
|
||||
params.add(apiDefinition);
|
||||
}
|
||||
}
|
||||
datasourceDTO.setApiConfigurationStr(new String(Base64.getEncoder().encode(Objects.requireNonNull(JsonUtil.toJSONString(apiDefinitionListWithStatus)).toString().getBytes())));
|
||||
datasourceDTO.setParamsStr(new String(Base64.getEncoder().encode(Objects.requireNonNull(JsonUtil.toJSONString(params)).toString().getBytes())));
|
||||
if(CollectionUtils.isNotEmpty(params)){
|
||||
datasourceDTO.setParamsStr(RsaUtils.symmetricEncrypt(JsonUtil.toJSONString(params).toString()));
|
||||
}
|
||||
if(CollectionUtils.isNotEmpty(apiDefinitionListWithStatus)){
|
||||
datasourceDTO.setApiConfigurationStr(RsaUtils.symmetricEncrypt(JsonUtil.toJSONString(apiDefinitionListWithStatus).toString()));
|
||||
}
|
||||
if (success == apiDefinitionList.size()) {
|
||||
datasourceDTO.setStatus("Success");
|
||||
} else {
|
||||
@ -1143,7 +1168,6 @@ public class DatasourceServer implements DatasourceApi {
|
||||
TaskDTO taskDTO = new TaskDTO();
|
||||
BeanUtils.copyBean(taskDTO, coreDatasourceTask);
|
||||
datasourceDTO.setSyncSetting(taskDTO);
|
||||
|
||||
CoreDatasourceTask task = datasourceTaskServer.selectByDSId(datasourceDTO.getId());
|
||||
if (task != null) {
|
||||
datasourceDTO.setLastSyncTime(task.getStartTime());
|
||||
@ -1153,13 +1177,12 @@ public class DatasourceServer implements DatasourceApi {
|
||||
Provider provider = ProviderFactory.getProvider(datasourceDTO.getType());
|
||||
provider.hidePW(datasourceDTO);
|
||||
}
|
||||
|
||||
}
|
||||
if (datasourceDTO.getType().equalsIgnoreCase(DatasourceConfiguration.DatasourceType.Excel.toString())) {
|
||||
datasourceDTO.setFileName(ExcelUtils.getFileName(datasource));
|
||||
datasourceDTO.setSize(ExcelUtils.getSize(datasource));
|
||||
}
|
||||
datasourceDTO.setConfiguration(new String(Base64.getEncoder().encode(datasourceDTO.getConfiguration().getBytes())));
|
||||
datasourceDTO.setConfiguration(RsaUtils.symmetricEncrypt(datasourceDTO.getConfiguration()));
|
||||
datasourceDTO.setCreator(coreUserManage.getUserName(Long.valueOf(datasourceDTO.getCreateBy())));
|
||||
return datasourceDTO;
|
||||
}
|
||||
|
||||
@ -5,9 +5,12 @@ import io.dataease.datasource.dao.auto.entity.CoreDeEngine;
|
||||
import io.dataease.datasource.dao.auto.mapper.CoreDeEngineMapper;
|
||||
import io.dataease.datasource.manage.EngineManage;
|
||||
import io.dataease.datasource.provider.CalciteProvider;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceDTO;
|
||||
import io.dataease.utils.AuthUtils;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.IDUtils;
|
||||
import io.dataease.utils.RsaUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -30,33 +33,44 @@ public class EngineServer implements EngineApi {
|
||||
|
||||
@Override
|
||||
public DatasourceDTO getEngine() {
|
||||
if (!AuthUtils.getUser().getUserId().equals(1L)) {
|
||||
DEException.throwException("非管理员,无权访问!");
|
||||
}
|
||||
DatasourceDTO datasourceDTO = new DatasourceDTO();
|
||||
List<CoreDeEngine> deEngines = deEngineMapper.selectList(null);
|
||||
if (CollectionUtils.isEmpty(deEngines)) {
|
||||
return datasourceDTO;
|
||||
}
|
||||
return BeanUtils.copyBean(datasourceDTO, deEngines.get(0));
|
||||
BeanUtils.copyBean(datasourceDTO, deEngines.get(0));
|
||||
datasourceDTO.setConfiguration(RsaUtils.symmetricEncrypt(datasourceDTO.getConfiguration()));
|
||||
return datasourceDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DatasourceDTO datasourceDTO) {
|
||||
if (!AuthUtils.getUser().getUserId().equals(1L)) {
|
||||
DEException.throwException("非管理员,无权访问!");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(datasourceDTO.getConfiguration())) {
|
||||
datasourceDTO.setConfiguration(new String(Base64.getDecoder().decode(datasourceDTO.getConfiguration())));
|
||||
}
|
||||
CoreDeEngine coreDeEngine = new CoreDeEngine();
|
||||
BeanUtils.copyBean(coreDeEngine, datasourceDTO);
|
||||
if(coreDeEngine.getId() == null){
|
||||
if (coreDeEngine.getId() == null) {
|
||||
coreDeEngine.setId(IDUtils.snowID());
|
||||
datasourceDTO.setId(coreDeEngine.getId());
|
||||
deEngineMapper.insert(coreDeEngine);
|
||||
}else {
|
||||
} else {
|
||||
deEngineMapper.updateById(coreDeEngine);
|
||||
}
|
||||
calciteProvider.update(datasourceDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(DatasourceDTO datasourceDTO) throws Exception{
|
||||
public void validate(DatasourceDTO datasourceDTO) throws Exception {
|
||||
if (!AuthUtils.getUser().getUserId().equals(1L)) {
|
||||
DEException.throwException("非管理员,无权访问!");
|
||||
}
|
||||
CoreDeEngine coreDeEngine = new CoreDeEngine();
|
||||
BeanUtils.copyBean(coreDeEngine, datasourceDTO);
|
||||
coreDeEngine.setConfiguration(new String(Base64.getDecoder().decode(coreDeEngine.getConfiguration())));
|
||||
@ -65,6 +79,9 @@ public class EngineServer implements EngineApi {
|
||||
|
||||
@Override
|
||||
public void validateById(Long id) throws Exception {
|
||||
if (!AuthUtils.getUser().getUserId().equals(1L)) {
|
||||
DEException.throwException("非管理员,无权访问!");
|
||||
}
|
||||
engineManage.validate(deEngineMapper.selectById(id));
|
||||
}
|
||||
|
||||
|
||||
@ -147,19 +147,55 @@ public class ExtWhere2Str {
|
||||
if (value.contains(SQLConstants.EMPTY_SIGN)) {
|
||||
whereValue = "('" + StringUtils.join(value, "','") + "', '')" + " or " + whereName + " is null ";
|
||||
} 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(",")) + ")";
|
||||
// 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 {
|
||||
whereValue = "('" + StringUtils.join(value, "','") + "')";
|
||||
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")) {
|
||||
if (StringUtils.containsIgnoreCase(request.getDatasetTableField().getType(), "NVARCHAR")
|
||||
|| StringUtils.containsIgnoreCase(request.getDatasetTableField().getType(), "NCHAR")) {
|
||||
whereValue = "'" + SQLConstants.MSSQL_N_PREFIX + "%" + 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 {
|
||||
whereValue = "'%" + value.get(0) + "%'";
|
||||
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) {
|
||||
@ -191,11 +227,29 @@ public class ExtWhere2Str {
|
||||
if (StringUtils.equals(value.get(0), SQLConstants.EMPTY_SIGN)) {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, "") + " or " + whereName + " is null ";
|
||||
} 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));
|
||||
// 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 {
|
||||
whereValue = String.format(SQLConstants.WHERE_VALUE_VALUE, value.get(0));
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -631,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");
|
||||
@ -654,16 +655,18 @@ public class ExportCenterManage implements BaseExportApi {
|
||||
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
|
||||
if (CollectionUtils.isEmpty(request.getMultiInfo())) {
|
||||
List<Object[]> details = request.getDetails();
|
||||
Integer[] excelTypes = request.getExcelTypes();
|
||||
details.add(0, request.getHeader());
|
||||
ViewDetailField[] detailFields = request.getDetailFields();
|
||||
Object[] header = request.getHeader();
|
||||
if(request.getViewInfo().getType().equalsIgnoreCase("chart-mix-dual-line")){
|
||||
|
||||
//明细sheet
|
||||
Sheet detailsSheet = wb.createSheet("数据");
|
||||
}else {
|
||||
List<Object[]> details = request.getDetails();
|
||||
Integer[] excelTypes = request.getExcelTypes();
|
||||
details.add(0, request.getHeader());
|
||||
ViewDetailField[] detailFields = request.getDetailFields();
|
||||
Object[] header = request.getHeader();
|
||||
Sheet detailsSheet = wb.createSheet("数据");
|
||||
ChartDataServer.setExcelData(detailsSheet, cellStyle, header, details, detailFields, excelTypes);
|
||||
}
|
||||
|
||||
ChartDataServer.setExcelData(detailsSheet, cellStyle, header, details, detailFields, excelTypes);
|
||||
} else {
|
||||
//多个sheet
|
||||
for (int i = 0; i < request.getMultiInfo().size(); i++) {
|
||||
|
||||
@ -23,6 +23,13 @@ public class RestIndexController {
|
||||
return RsaUtils.publicKey();
|
||||
}
|
||||
|
||||
@GetMapping("/symmetricKey")
|
||||
@ResponseBody
|
||||
public String symmetricKey() {
|
||||
return RsaUtils.generateSymmetricKey();
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/model")
|
||||
@ResponseBody
|
||||
public boolean model() {
|
||||
|
||||
@ -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, /datasetData/enumValue, /datasetData/enumValueObj, /datasetData/getFieldTree, /dekey, /symmetricKey, /share/validate, /sysParameter/queryOnlineMap, /chartData/innerExportDetails";
|
||||
|
||||
|
||||
@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) || WhitelistUtils.match(requestURI);
|
||||
if (!valid) {
|
||||
DEException.throwException("分享链接Token不支持访问当前url[" + requestURI + "]");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -64,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);
|
||||
@ -199,7 +208,7 @@ public class XpackShareManage {
|
||||
if (ObjectUtils.isEmpty(sharedBase) || !sharedBase.isPeRequire()) return true;
|
||||
Long exp = share.getExp();
|
||||
String pwd = share.getPwd();
|
||||
return StringUtils.isNotBlank(pwd) && ObjectUtils.isNotEmpty(exp);
|
||||
return StringUtils.isNotBlank(pwd) && ObjectUtils.isNotEmpty(exp) && exp > 0L;
|
||||
}
|
||||
|
||||
public XpackShareProxyVO proxyInfo(XpackShareProxyRequest request) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package io.dataease.substitute.permissions.user;
|
||||
|
||||
|
||||
import io.dataease.api.permissions.user.vo.CurIpVO;
|
||||
import io.dataease.api.permissions.user.vo.UserFormVO;
|
||||
import io.dataease.utils.IPUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@ -27,6 +28,7 @@ public class SubstituteUserServer {
|
||||
result.put("language", "zh-CN");
|
||||
return result;
|
||||
}
|
||||
|
||||
@GetMapping("/personInfo")
|
||||
public UserFormVO personInfo() {
|
||||
UserFormVO userFormVO = new UserFormVO();
|
||||
@ -38,4 +40,13 @@ public class SubstituteUserServer {
|
||||
userFormVO.setModel("lose");
|
||||
return userFormVO;
|
||||
}
|
||||
|
||||
@GetMapping("/ipInfo")
|
||||
public CurIpVO ipInfo() {
|
||||
CurIpVO curIpVO = new CurIpVO();
|
||||
curIpVO.setAccount("admin");
|
||||
curIpVO.setName("管理员");
|
||||
curIpVO.setIp(IPUtils.get());
|
||||
return curIpVO;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,9 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/sysParameter")
|
||||
@ -61,6 +63,21 @@ public class SysParameterServer implements SysParameterApi {
|
||||
return frontTimeOut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> defaultSettings() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(XpackSettingConstants.DEFAULT_SORT, "1");
|
||||
|
||||
List<SettingItemVO> settingItemVOS = queryBasicSetting();
|
||||
for (int i = 0; i < settingItemVOS.size(); i++) {
|
||||
SettingItemVO settingItemVO = settingItemVOS.get(i);
|
||||
if (StringUtils.isNotBlank(settingItemVO.getPkey()) && settingItemVO.getPkey().equalsIgnoreCase(XpackSettingConstants.DEFAULT_SORT) && StringUtils.isNotBlank(settingItemVO.getPval())) {
|
||||
map.put(XpackSettingConstants.DEFAULT_SORT, settingItemVO.getPval());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> ui() {
|
||||
return sysParameterManage.getUiList();
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -142,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)
|
||||
@ -300,7 +302,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
coreDatasetTableFieldMapper.insert(dsTableFields);
|
||||
});
|
||||
|
||||
|
||||
List<String> dsGroupNameSave = new ArrayList<>();
|
||||
// 持久化数据集
|
||||
newDsGroupInfo.forEach(dsGroup -> {
|
||||
dsTableIdMap.forEach((key, value) -> {
|
||||
@ -325,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);
|
||||
});
|
||||
|
||||
|
||||
@ -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) {
|
||||
@ -135,6 +137,7 @@ public class VisualizationLinkJumpService implements VisualizationLinkJumpApi {
|
||||
});
|
||||
}
|
||||
|
||||
@DeLinkPermit("#p0.targetDvId")
|
||||
@Override
|
||||
public VisualizationLinkJumpBaseResponse queryTargetVisualizationJumpInfo(VisualizationLinkJumpBaseRequest request) {
|
||||
List<VisualizationLinkJumpDTO> result = extVisualizationLinkJumpMapper.getTargetVisualizationJumpInfo(request);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -4,7 +4,7 @@ spring:
|
||||
username: root
|
||||
password: 123456
|
||||
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
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||
VALUES (1048232869488627719, 'basic.defaultSort', '1', 'text', 13);
|
||||
@ -0,0 +1,2 @@
|
||||
INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||
VALUES (1048232869488627719, 'basic.defaultSort', '1', 'text', 13);
|
||||
@ -104,3 +104,10 @@ 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
|
||||
|
||||
|
||||
@ -126,3 +126,6 @@ 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
|
||||
|
||||
@ -124,3 +124,10 @@ 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
|
||||
|
||||
|
||||
|
||||
@ -6,3 +6,10 @@ export const getRoleRouters = async (): Promise<Array<AppCustomRouteRecordRaw>>
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取默认排序
|
||||
export const getDefaultSettings = async (): Promise<IResponse> => {
|
||||
return request.get({ url: '/sysParameter/defaultSettings' }).then(res => {
|
||||
return res?.data
|
||||
})
|
||||
}
|
||||
|
||||
@ -155,6 +155,8 @@ export const getById = (id: number) => request.get({ url: '/datasource/get/' + i
|
||||
|
||||
export const getHidePwById = (id: number) => request.get({ url: '/datasource/hidePw/' + id })
|
||||
|
||||
export const getSimpleDs = (id: number) => request.get({ url: '/datasource/getSimpleDs/' + id })
|
||||
|
||||
export const uploadFile = async (data): Promise<IResponse> => {
|
||||
return request
|
||||
.post({
|
||||
|
||||
@ -4,6 +4,8 @@ export const loginApi = data => request.post({ url: '/login/localLogin', data })
|
||||
|
||||
export const queryDekey = () => request.get({ url: 'dekey' })
|
||||
|
||||
export const querySymmetricKey = () => request.get({ url: 'symmetricKey' })
|
||||
|
||||
export const modelApi = () => request.get({ url: 'model' })
|
||||
|
||||
export const platformLoginApi = origin => request.post({ url: '/login/platformLogin/' + origin })
|
||||
|
||||
@ -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 })
|
||||
|
||||
1
core/core-frontend/src/assets/svg/dv-style-tab-head.svg
Normal file
@ -0,0 +1 @@
|
||||
<?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="1731382660397" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7069" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M810.688 960H213.312A149.376 149.376 0 0 1 64 810.688V312.896a149.376 149.376 0 0 1 149.312-149.312h597.312A149.376 149.376 0 0 1 960 312.896v497.792A149.376 149.376 0 0 1 810.688 960z m99.584-647.104c0-54.976-44.608-99.52-99.584-99.52H213.312c-54.976 0-99.584 44.544-99.584 99.52v497.792c0 54.912 44.544 99.584 99.584 99.584h597.312c54.912 0 99.584-44.608 99.584-99.584V312.896z m-127.616 281.536l28.032 16.128v100.544h-149.376V462.208h149.376v116.032l-28.032 16.192zM760.896 512h-49.728v49.792h49.728V512z m0 99.584h-49.728v49.728h49.728v-49.728z m-199.104 0H462.208v99.584h-49.792v-248.96h199.104v248.896h-49.728V611.584z m0-99.584H462.208v49.792h99.584V512z m-248.896 199.104h-49.792V512h-49.792v-49.792h149.312V512h-49.728v199.104zM113.792 64h497.792v49.792H113.792V64z" p-id="7070"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.1 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 |
@ -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="M12.2496 19.1355L5.11783 12.0038L12.2496 4.87206C12.4448 4.6768 12.4448 4.36022 12.2496 4.16495L11.5424 3.45785C11.3472 3.26259 11.0306 3.26259 10.8353 3.45785L2.99651 11.2967C2.60598 11.6872 2.60598 12.3204 2.99651 12.7109L10.8353 20.5497C11.0306 20.745 11.3472 20.745 11.5424 20.5497L12.2496 19.8426C12.4448 19.6474 12.4448 19.3308 12.2496 19.1355Z" fill="#1F2329"/>
|
||||
<path d="M21.1497 19.1355L14.018 12.0038L21.1497 4.87206C21.345 4.6768 21.345 4.36022 21.1497 4.16495L20.4426 3.45785C20.2473 3.26259 19.9307 3.26259 19.7355 3.45785L11.8967 11.2967C11.5061 11.6872 11.5061 12.3204 11.8967 12.7109L19.7355 20.5497C19.9307 20.745 20.2473 20.745 20.4426 20.5497L21.1497 19.8426C21.345 19.6474 21.345 19.3308 21.1497 19.1355Z" fill="#1F2329"/>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.2496 19.1355L5.11783 12.0038L12.2496 4.87206C12.4448 4.6768 12.4448 4.36022 12.2496 4.16495L11.5424 3.45785C11.3472 3.26259 11.0306 3.26259 10.8353 3.45785L2.99651 11.2967C2.60598 11.6872 2.60598 12.3204 2.99651 12.7109L10.8353 20.5497C11.0306 20.745 11.3472 20.745 11.5424 20.5497L12.2496 19.8426C12.4448 19.6474 12.4448 19.3308 12.2496 19.1355Z"/>
|
||||
<path d="M21.1497 19.1355L14.018 12.0038L21.1497 4.87206C21.345 4.6768 21.345 4.36022 21.1497 4.16495L20.4426 3.45785C20.2473 3.26259 19.9307 3.26259 19.7355 3.45785L11.8967 11.2967C11.5061 11.6872 11.5061 12.3204 11.8967 12.7109L19.7355 20.5497C19.9307 20.745 20.2473 20.745 20.4426 20.5497L21.1497 19.8426C21.345 19.6474 21.345 19.3308 21.1497 19.1355Z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 854 B After Width: | Height: | Size: 813 B |
@ -1 +1,4 @@
|
||||
<?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="1726302584557" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6066" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M0 0h938.666667v938.666667H0V0z m64 64v810.666667h810.666667v-810.666667h-810.666667z" fill="#2C82FC" p-id="6067"></path><path d="M170.666667 170.666667h853.333333v853.333333H170.666667z" fill="#2C82FC" p-id="6068"></path><path d="M967.082667 334.208v362.965333l-151.850667-162.986666s-17.962667-21.461333-32.64-21.461334a35.072 35.072 0 0 0-30.506667 17.706667c-4.053333 7.04-73.344 76.330667-207.872 207.872-6.016 4.309333-6.016 4.309333-12.586666 0L413.653333 641.706667s-16.768-14.293333-28.373333-14.293334c-5.930667 0-11.477333 1.621333-16.426667 4.224s-8.917333 6.528-10.496 8.192l-130.816 125.312V284.458667 227.541333h739.541334v106.666667z m-55.68 632.917333H227.541333v-55.68-68.650666l151.381334-144.896c5.077333-4.266667 8.362667-4.565333 13.482666-0.085334l116.224 95.061334c10.026667 7.082667 20.949333 15.786667 29.525334 15.786666 8.576 0 18.773333-2.944 29.781333-13.952l211.242667-211.242666c1.109333 0.128 2.218667 0.384 3.370666 0.384l1.066667-0.085334 183.424 196.906667v79.744h0.042667v106.666667h-55.68z" fill="#FFFFFF" p-id="6069"></path><path d="M758.698667 672.64a35.584 35.584 0 0 1 45.013333 4.437333c1.536 1.578667 4.352 4.736 4.352 4.736l15.104 15.061334a21.461333 21.461333 0 0 1 0 30.208 21.077333 21.077333 0 0 1-24.064 4.010666c-0.469333 0.256-21.162667-19.157333-21.162667-19.157333l-30.08 30.208-63.701333 63.701333c-0.512 0.554667-0.682667 1.322667-1.28 1.834667a21.418667 21.418667 0 0 1-30.165333 0 21.418667 21.418667 0 0 1 0-30.165333l0.341333-0.298667 105.642667-104.576z m84.949333 104.917333c-0.170667-0.042667-0.256-0.213333-0.469333-0.298666a21.418667 21.418667 0 0 1 0-30.165334 21.461333 21.461333 0 0 1 30.208 0l0.256 0.384 0.085333-0.128 9.728 9.770667a21.333333 21.333333 0 0 1-30.165333 30.165333l-9.642667-9.728zM426.666667 312.874667a85.333333 85.333333 0 1 1-0.042667 170.709333A85.333333 85.333333 0 0 1 426.666667 312.874667zM426.666667 426.666667a28.458667 28.458667 0 1 0-0.042667-56.96A28.458667 28.458667 0 0 0 426.666667 426.666667z" fill="#2C82FC" p-id="6070"></path></svg>
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.33251 3.33334C2.41205 3.33334 1.66585 4.07954 1.66585 5.00001V28.3333C1.66585 29.2538 2.41205 30 3.33251 30H29.9992C30.9197 30 31.6658 29.2538 31.6658 28.3333V5.00001C31.6658 4.07954 30.9197 3.33334 29.9992 3.33334H3.33251ZM28.3325 6.66654V21.6668L24.7552 18.0893C24.4297 17.764 23.902 17.764 23.5765 18.0893L18.9218 22.7442C18.5963 23.0697 18.0687 23.0697 17.7432 22.7442L10.5884 15.5893C10.263 15.264 9.73536 15.264 9.40993 15.5893L4.99918 20.0002V6.66654H28.3325ZM21.6658 9.16668C21.2057 9.16668 20.8325 9.53978 20.8325 10V12.5C20.8325 12.9602 21.2057 13.3333 21.6658 13.3333H24.1658C24.626 13.3333 24.9992 12.9602 24.9992 12.5V10C24.9992 9.53978 24.626 9.16668 24.1658 9.16668H21.6658Z" fill="#3370FF"/>
|
||||
<path d="M38.3333 35C38.3333 35.4603 38.1468 35.8769 37.8452 36.1785C37.5436 36.4801 37.1269 36.6667 36.6667 36.6667H19.1667C18.7064 36.6667 18.3333 36.2936 18.3333 35.8333V34.1667C18.3333 33.7064 18.7064 33.3333 19.1667 33.3333H35V14.1667C35 13.7064 35.3731 13.3333 35.8333 13.3333H37.5C37.9602 13.3333 38.3333 13.7064 38.3333 14.1667V35Z" fill="#3370FF"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.2 KiB |
@ -1 +1,4 @@
|
||||
<?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="1726300744320" class="icon" viewBox="0 0 1448 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4293" xmlns:xlink="http://www.w3.org/1999/xlink" width="282.8125" height="200"><path d="M1081.624727 143.803796H302.916849c-49.712078 0-89.96338 40.251302-89.96338 89.96338V892.753234c0 49.712078 40.251302 89.96338 89.96338 89.963379h778.879892c49.712078 0 89.96338-40.251302 89.96338-89.963379V233.767176c-0.172014-49.712078-40.423316-89.96338-90.135394-89.96338M302.744835 203.836721h778.879892c16.513355 0 29.930455 13.417101 29.930455 29.930455V586.568117c-48.335965-39.563245-131.934823-93.059634-232.391063-93.059634-92.543591 0-183.883084 71.729884-272.126323 141.051571-67.601545 53.15236-137.611288 108.196876-186.63531 108.196875-68.805644 0-127.806484-50.572148-147.760121-69.837729V233.767176c0.172014-16.513355 13.589115-29.930455 30.10247-29.930455m778.879892 718.846968H302.744835c-16.513355 0-29.930455-13.417101-29.930456-29.930455v-142.25567c35.950949 25.458088 87.89921 52.120275 147.760121 52.120276 69.837729 0 144.491853-58.656812 223.618344-120.92592 80.33059-63.129179 163.241391-128.322526 235.143289-128.322526 128.838569 0 230.842936 113.357299 231.875021 114.561397l0.516042-0.344028V892.753234c0 16.513355-13.417101 29.930455-30.102469 29.930455m-569.366706-359.165463c66.225433 0 120.065849-53.668402 120.065849-120.065849 0-66.225433-53.668402-120.065849-120.065849-120.065849-66.225433 0-120.065849 53.668402-120.065849 120.065849 0 66.397447 53.668402 120.065849 120.065849 120.065849M512.602049 383.591466c33.026709 0 59.688896 26.662187 59.688897 59.688897 0 33.026709-26.662187 59.688896-59.688897 59.688896-33.026709 0-59.688896-26.662187-59.688896-59.688896 0-33.026709 26.662187-59.688896 59.688896-59.688897m0 0" p-id="4294"></path><path d="M1217.687888 833.236351h-96.843944v-51.08819h96.843944c24.770032 0 45.067697-20.125651 45.067697-44.895683V134.34302c0-24.770032-20.125651-44.895683-45.067697-44.895683h-844.589282c-24.770032 0-44.895683 20.125651-44.895683 44.895683v59.688897H276.942718V134.34302c0-52.980346 43.003528-95.983874 95.983874-95.983873h844.589282c52.980346 0 95.983874 43.003528 95.983874 95.983873v602.909458c0.172014 52.980346-42.831514 95.983874-95.81186 95.983873z" p-id="4295"></path></svg>
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.33251 3.33334C2.41205 3.33334 1.66585 4.07954 1.66585 5.00001V28.3333C1.66585 29.2538 2.41205 30 3.33251 30H29.9992C30.9197 30 31.6658 29.2538 31.6658 28.3333V5.00001C31.6658 4.07954 30.9197 3.33334 29.9992 3.33334H3.33251ZM28.3325 6.66654V21.6668L24.7552 18.0893C24.4297 17.764 23.902 17.764 23.5765 18.0893L18.9218 22.7442C18.5963 23.0697 18.0687 23.0697 17.7432 22.7442L10.5884 15.5893C10.263 15.264 9.73536 15.264 9.40993 15.5893L4.99918 20.0002V6.66654H28.3325ZM21.6658 9.16668C21.2057 9.16668 20.8325 9.53978 20.8325 10V12.5C20.8325 12.9602 21.2057 13.3333 21.6658 13.3333H24.1658C24.626 13.3333 24.9992 12.9602 24.9992 12.5V10C24.9992 9.53978 24.626 9.16668 24.1658 9.16668H21.6658Z" />
|
||||
<path d="M38.3333 35C38.3333 35.4603 38.1468 35.8769 37.8452 36.1785C37.5436 36.4801 37.1269 36.6667 36.6667 36.6667H19.1667C18.7064 36.6667 18.3333 36.2936 18.3333 35.8333V34.1667C18.3333 33.7064 18.7064 33.3333 19.1667 33.3333H35V14.1667C35 13.7064 35.3731 13.3333 35.8333 13.3333H37.5C37.9602 13.3333 38.3333 13.7064 38.3333 14.1667V35Z" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.1 KiB |
@ -1 +1,4 @@
|
||||
<?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="1726302584557" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6066" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M0 0h938.666667v938.666667H0V0z m64 64v810.666667h810.666667v-810.666667h-810.666667z" fill="#2C82FC" p-id="6067"></path><path d="M170.666667 170.666667h853.333333v853.333333H170.666667z" fill="#2C82FC" p-id="6068"></path><path d="M967.082667 334.208v362.965333l-151.850667-162.986666s-17.962667-21.461333-32.64-21.461334a35.072 35.072 0 0 0-30.506667 17.706667c-4.053333 7.04-73.344 76.330667-207.872 207.872-6.016 4.309333-6.016 4.309333-12.586666 0L413.653333 641.706667s-16.768-14.293333-28.373333-14.293334c-5.930667 0-11.477333 1.621333-16.426667 4.224s-8.917333 6.528-10.496 8.192l-130.816 125.312V284.458667 227.541333h739.541334v106.666667z m-55.68 632.917333H227.541333v-55.68-68.650666l151.381334-144.896c5.077333-4.266667 8.362667-4.565333 13.482666-0.085334l116.224 95.061334c10.026667 7.082667 20.949333 15.786667 29.525334 15.786666 8.576 0 18.773333-2.944 29.781333-13.952l211.242667-211.242666c1.109333 0.128 2.218667 0.384 3.370666 0.384l1.066667-0.085334 183.424 196.906667v79.744h0.042667v106.666667h-55.68z" fill="#FFFFFF" p-id="6069"></path><path d="M758.698667 672.64a35.584 35.584 0 0 1 45.013333 4.437333c1.536 1.578667 4.352 4.736 4.352 4.736l15.104 15.061334a21.461333 21.461333 0 0 1 0 30.208 21.077333 21.077333 0 0 1-24.064 4.010666c-0.469333 0.256-21.162667-19.157333-21.162667-19.157333l-30.08 30.208-63.701333 63.701333c-0.512 0.554667-0.682667 1.322667-1.28 1.834667a21.418667 21.418667 0 0 1-30.165333 0 21.418667 21.418667 0 0 1 0-30.165333l0.341333-0.298667 105.642667-104.576z m84.949333 104.917333c-0.170667-0.042667-0.256-0.213333-0.469333-0.298666a21.418667 21.418667 0 0 1 0-30.165334 21.461333 21.461333 0 0 1 30.208 0l0.256 0.384 0.085333-0.128 9.728 9.770667a21.333333 21.333333 0 0 1-30.165333 30.165333l-9.642667-9.728zM426.666667 312.874667a85.333333 85.333333 0 1 1-0.042667 170.709333A85.333333 85.333333 0 0 1 426.666667 312.874667zM426.666667 426.666667a28.458667 28.458667 0 1 0-0.042667-56.96A28.458667 28.458667 0 0 0 426.666667 426.666667z" fill="#2C82FC" p-id="6070"></path></svg>
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.33251 3.33334C2.41205 3.33334 1.66585 4.07954 1.66585 5.00001V28.3333C1.66585 29.2538 2.41205 30 3.33251 30H29.9992C30.9197 30 31.6658 29.2538 31.6658 28.3333V5.00001C31.6658 4.07954 30.9197 3.33334 29.9992 3.33334H3.33251ZM28.3325 6.66654V21.6668L24.7552 18.0893C24.4297 17.764 23.902 17.764 23.5765 18.0893L18.9218 22.7442C18.5963 23.0697 18.0687 23.0697 17.7432 22.7442L10.5884 15.5893C10.263 15.264 9.73536 15.264 9.40993 15.5893L4.99918 20.0002V6.66654H28.3325ZM21.6658 9.16668C21.2057 9.16668 20.8325 9.53978 20.8325 10V12.5C20.8325 12.9602 21.2057 13.3333 21.6658 13.3333H24.1658C24.626 13.3333 24.9992 12.9602 24.9992 12.5V10C24.9992 9.53978 24.626 9.16668 24.1658 9.16668H21.6658Z" fill="#3370FF"/>
|
||||
<path d="M38.3333 35C38.3333 35.4603 38.1468 35.8769 37.8452 36.1785C37.5436 36.4801 37.1269 36.6667 36.6667 36.6667H19.1667C18.7064 36.6667 18.3333 36.2936 18.3333 35.8333V34.1667C18.3333 33.7064 18.7064 33.3333 19.1667 33.3333H35V14.1667C35 13.7064 35.3731 13.3333 35.8333 13.3333H37.5C37.9602 13.3333 38.3333 13.7064 38.3333 14.1667V35Z" fill="#3370FF"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.2 KiB |
@ -2,7 +2,6 @@
|
||||
import { useAttrs, computed } from 'vue'
|
||||
import icon_visible_outlined from '@/assets/svg/icon_visible_outlined.svg'
|
||||
import icon_invisible_outlined from '@/assets/svg/icon_invisible_outlined.svg'
|
||||
import { hIcon } from '@/components/icon-custom'
|
||||
const attrs = useAttrs()
|
||||
const props = defineProps(['modelValue'])
|
||||
const emits = defineEmits(['update:modelValue'])
|
||||
@ -14,15 +13,12 @@ const value = computed({
|
||||
emits('update:modelValue', value)
|
||||
}
|
||||
})
|
||||
|
||||
const iconView = hIcon(icon_visible_outlined)
|
||||
const iconHide = hIcon(icon_invisible_outlined)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-input
|
||||
:icon-view-custom="iconView"
|
||||
:icon-hide-custom="iconHide"
|
||||
:icon-view-custom="icon_visible_outlined"
|
||||
:icon-hide-custom="icon_invisible_outlined"
|
||||
v-bind="attrs"
|
||||
v-model="value"
|
||||
/>
|
||||
|
||||
@ -138,7 +138,7 @@ const previewOuter = () => {
|
||||
return
|
||||
}
|
||||
canvasSave(() => {
|
||||
const url = '#/preview?dvId=' + dvInfo.value.id
|
||||
const url = '#/preview?ignoreParams=true&dvId=' + dvInfo.value.id
|
||||
const newWindow = window.open(url, '_blank')
|
||||
initOpenHandler(newWindow)
|
||||
})
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
<el-checkbox
|
||||
size="small"
|
||||
:effect="themes"
|
||||
v-model="colorForm.basicStyle.gradient"
|
||||
v-model="colorForm['basicStyle']['gradient']"
|
||||
@change="changeColorCase('gradient')"
|
||||
>
|
||||
{{ $t('chart.gradient') }}{{ $t('chart.color') }}
|
||||
@ -36,7 +36,7 @@
|
||||
<el-form-item class="form-item alpha-slider" :class="'form-item-' + themes">
|
||||
<el-slider
|
||||
:effect="themes"
|
||||
v-model="colorForm.basicStyle.alpha"
|
||||
v-model="colorForm['basicStyle']['alpha']"
|
||||
@change="changeColorCase('alpha')"
|
||||
/>
|
||||
</el-form-item>
|
||||
@ -50,7 +50,7 @@
|
||||
<el-input
|
||||
type="number"
|
||||
:effect="themes"
|
||||
v-model="colorForm.basicStyle.alpha"
|
||||
v-model="colorForm['basicStyle']['alpha']"
|
||||
:min="0"
|
||||
:max="100"
|
||||
class="alpha-input-number"
|
||||
@ -78,7 +78,7 @@
|
||||
<el-form-item :label="t('chart.table_header_bg')" class="form-item">
|
||||
<el-color-picker
|
||||
:trigger-width="colorPickerWidth"
|
||||
v-model="colorForm.tableHeader.tableHeaderBgColor"
|
||||
v-model="colorForm['tableHeader']['tableHeaderBgColor']"
|
||||
size="small"
|
||||
:predefine="predefineColors"
|
||||
is-custom
|
||||
@ -91,7 +91,7 @@
|
||||
<el-form-item :label="t('chart.table_item_bg')" class="form-item">
|
||||
<el-color-picker
|
||||
:trigger-width="colorPickerWidth"
|
||||
v-model="colorForm.tableCell.tableItemBgColor"
|
||||
v-model="colorForm['tableCell']['tableItemBgColor']"
|
||||
size="small"
|
||||
:predefine="predefineColors"
|
||||
:effect="themes"
|
||||
@ -106,7 +106,7 @@
|
||||
<el-form-item :label="t('chart.table_header_font_color')" class="form-item">
|
||||
<el-color-picker
|
||||
:trigger-width="colorPickerWidth"
|
||||
v-model="colorForm.tableHeader.tableHeaderFontColor"
|
||||
v-model="colorForm['tableHeader']['tableHeaderFontColor']"
|
||||
:effect="themes"
|
||||
size="small"
|
||||
:predefine="predefineColors"
|
||||
@ -119,7 +119,7 @@
|
||||
<el-form-item :label="t('chart.table_item_font_color')" class="form-item">
|
||||
<el-color-picker
|
||||
:trigger-width="colorPickerWidth"
|
||||
v-model="colorForm.tableCell.tableFontColor"
|
||||
v-model="colorForm['tableCell']['tableFontColor']"
|
||||
size="small"
|
||||
:predefine="predefineColors"
|
||||
:effect="themes"
|
||||
@ -134,7 +134,7 @@
|
||||
<el-form-item :label="t('chart.table_border_color')" class="form-item">
|
||||
<el-color-picker
|
||||
:trigger-width="colorPickerWidth"
|
||||
v-model="colorForm.basicStyle.tableBorderColor"
|
||||
v-model="colorForm.basicStyle['tableBorderColor']"
|
||||
size="small"
|
||||
:predefine="predefineColors"
|
||||
:effect="themes"
|
||||
@ -147,7 +147,7 @@
|
||||
<el-form-item :label="t('chart.table_scroll_bar_color')" class="form-item">
|
||||
<el-color-picker
|
||||
:trigger-width="colorPickerWidth"
|
||||
v-model="colorForm.basicStyle.tableScrollBarColor"
|
||||
v-model="colorForm.basicStyle['tableScrollBarColor']"
|
||||
size="small"
|
||||
:predefine="predefineColors"
|
||||
color-format="rgb"
|
||||
|
||||
@ -180,6 +180,26 @@
|
||||
:disabled="canvasStyleData.dashboard.resultMode === 'all'"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item style="margin-top: 16px; margin-bottom: 8px" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
:effect="themes"
|
||||
size="small"
|
||||
v-model="canvasStyleData.suspensionButtonAvailable"
|
||||
@change="themeChange"
|
||||
>
|
||||
<span class="data-area-label">
|
||||
<span style="margin-right: 4px"> 显示放大、导出等悬浮按钮 </span>
|
||||
<el-tooltip class="item" :effect="toolTip" placement="bottom">
|
||||
<template #content>
|
||||
<div>预览时启用</div>
|
||||
</template>
|
||||
<el-icon class="hint-icon" :class="{ 'hint-icon--dark': themes === 'dark' }">
|
||||
<Icon name="icon_info_outlined"><icon_info_outlined class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
|
||||
@ -349,7 +349,7 @@ const coordinates = ref([]) //坐标点集合
|
||||
|
||||
let lastTask = undefined
|
||||
let isOverlay = false //是否正在交换位置
|
||||
let moveTime = 200 //移动动画时间
|
||||
let moveTime = 100 //移动动画时间
|
||||
|
||||
const itemMaxY = ref(0)
|
||||
let itemMaxX = 0
|
||||
@ -874,6 +874,11 @@ function removeItemById(componentId) {
|
||||
removeItem(index)
|
||||
}
|
||||
})
|
||||
if (!isMainCanvas(canvasId.value)) {
|
||||
nextTick(() => {
|
||||
canvasInit()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1514,6 +1519,7 @@ defineExpose({
|
||||
:style="editStyle"
|
||||
@contextmenu="handleContextMenu"
|
||||
>
|
||||
<slot name="canvasDragTips" />
|
||||
<drag-info v-if="dragInfoShow"></drag-info>
|
||||
<canvas-opt-bar
|
||||
v-if="dvInfo.type === 'dataV'"
|
||||
|
||||
@ -37,8 +37,14 @@ const popComponentDataLength = computed(
|
||||
)
|
||||
|
||||
const lock = () => {
|
||||
if (curComponent.value && !isGroupArea.value) {
|
||||
lockStore.lock()
|
||||
} else if (areaData.value.components.length) {
|
||||
areaData.value.components.forEach(component => {
|
||||
lockStore.lock(component)
|
||||
})
|
||||
}
|
||||
snapshotStore.recordSnapshotCache()
|
||||
lockStore.lock()
|
||||
menuOpt('lock')
|
||||
}
|
||||
|
||||
@ -75,14 +81,26 @@ const copy = () => {
|
||||
}
|
||||
|
||||
const hide = () => {
|
||||
if (curComponent.value && !isGroupArea.value) {
|
||||
layerStore.hideComponentWithComponent()
|
||||
} else if (areaData.value.components.length) {
|
||||
areaData.value.components.forEach(component => {
|
||||
layerStore.hideComponentWithComponent(component.id)
|
||||
})
|
||||
}
|
||||
snapshotStore.recordSnapshotCache()
|
||||
layerStore.hideComponent()
|
||||
menuOpt('hide')
|
||||
}
|
||||
|
||||
const show = () => {
|
||||
if (curComponent.value && !isGroupArea.value) {
|
||||
layerStore.showComponent()
|
||||
} else if (areaData.value.components.length) {
|
||||
areaData.value.components.forEach(component => {
|
||||
layerStore.showComponent(component.id)
|
||||
})
|
||||
}
|
||||
snapshotStore.recordSnapshotCache()
|
||||
layerStore.showComponent()
|
||||
menuOpt('show')
|
||||
}
|
||||
const categoryChange = type => {
|
||||
|
||||
@ -19,8 +19,9 @@ import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import DatasetParamsComponent from '@/components/visualization/DatasetParamsComponent.vue'
|
||||
import DeFullscreen from '@/components/visualization/common/DeFullscreen.vue'
|
||||
import EmptyBackground from '../../empty-background/src/EmptyBackground.vue'
|
||||
import LinkOptBar from '@/components/data-visualization/canvas/LinkOptBar.vue'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { pcMatrixCount, curComponent, mobileInPc, canvasState } = storeToRefs(dvMainStore)
|
||||
const { pcMatrixCount, curComponent, mobileInPc, canvasState, inMobile } = storeToRefs(dvMainStore)
|
||||
const openHandler = ref(null)
|
||||
const customDatasetParamsRef = ref(null)
|
||||
const emits = defineEmits(['onResetLayout'])
|
||||
@ -77,6 +78,11 @@ const props = defineProps({
|
||||
isSelector: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 显示悬浮按钮
|
||||
showPopBar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
@ -90,7 +96,8 @@ const {
|
||||
previewActive,
|
||||
downloadStatus,
|
||||
outerScale,
|
||||
outerSearchCount
|
||||
outerSearchCount,
|
||||
showPopBar
|
||||
} = toRefs(props)
|
||||
const domId = 'preview-' + canvasId.value
|
||||
const scaleWidthPoint = ref(100)
|
||||
@ -234,7 +241,8 @@ const resetLayout = () => {
|
||||
baseComponentData.value,
|
||||
canvasStyleData.value,
|
||||
scaleMin.value || outerScale.value * 100,
|
||||
scaleMinHeight || outerScale.value * 100
|
||||
scaleMinHeight || outerScale.value * 100,
|
||||
outerScale.value * 100
|
||||
)
|
||||
scaleMin.value = isMainCanvas(canvasId.value) ? scaleMin.value : outerScale.value * 100
|
||||
}
|
||||
@ -393,6 +401,19 @@ const datasetParamsInit = item => {
|
||||
const dataVPreview = computed(
|
||||
() => dvInfo.value.type === 'dataV' && canvasId.value === 'canvas-main'
|
||||
)
|
||||
|
||||
const linkOptBarShow = computed(() => {
|
||||
return Boolean(
|
||||
canvasStyleData.value.suspensionButtonAvailable &&
|
||||
!inMobile.value &&
|
||||
!mobileInPc.value &&
|
||||
showPopBar.value
|
||||
)
|
||||
})
|
||||
|
||||
const downloadAsPDF = () => {
|
||||
// test
|
||||
}
|
||||
defineExpose({
|
||||
restore
|
||||
})
|
||||
@ -455,6 +476,13 @@ defineExpose({
|
||||
<de-fullscreen ref="fullScreeRef"></de-fullscreen>
|
||||
<dataset-params-component ref="customDatasetParamsRef"></dataset-params-component>
|
||||
<XpackComponent ref="openHandler" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI=" />
|
||||
<link-opt-bar
|
||||
v-if="linkOptBarShow"
|
||||
ref="link-opt-bar"
|
||||
:terminal="'pc'"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
@link-export-pdf="downloadAsPDF"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@ -0,0 +1,242 @@
|
||||
<template>
|
||||
<div
|
||||
id="fullscreenElement"
|
||||
ref="widget-div"
|
||||
class="link-bar-main bar-light"
|
||||
:class="[{ ['link-bar-main-active']: state.barActive }, functionClass]"
|
||||
:style="{
|
||||
'--fullWidth': state.fullWidth + 'px',
|
||||
'--fullContent': 28 - state.fullWidth + 'px',
|
||||
'--firstHoveMove': 32 - state.fullWidth + 'px'
|
||||
}"
|
||||
>
|
||||
<div class="bar-first">
|
||||
<el-tooltip :content="state.barActive ? '收起' : '展开'">
|
||||
<el-icon style="width: 16px; height: 16px" @click="firstBarClick">
|
||||
<Icon name="icon_down_right_outlined" v-if="state.barActive">
|
||||
<icon_down_right_outlined />
|
||||
</Icon>
|
||||
<Icon name="icon_up_left_outlined" v-else>
|
||||
<icon_up_left_outlined />
|
||||
</Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="bar-content">
|
||||
<div class="bar-diver" />
|
||||
<div v-show="fromLink" class="link-icon-active">
|
||||
<el-tooltip content="返回上一级">
|
||||
<el-icon style="width: 16px; height: 16px" @click="back2Last">
|
||||
<Icon name="icon_left_outlined">
|
||||
<icon_left_outlined class="svg-icon" />
|
||||
</Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="link-icon-active">
|
||||
<el-tooltip content="导出PDF">
|
||||
<el-icon style="width: 16px; height: 16px" @click="exportPDF">
|
||||
<Icon name="icon_download_outlined">
|
||||
<icon_download_outlined class="svg-icon" />
|
||||
</Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div id="fullscreenElement" class="link-icon-active" style="padding-right: 4px">
|
||||
<el-tooltip :content="fullscreenFlag ? '退出全屏' : '全屏'">
|
||||
<el-icon style="width: 16px; height: 16px" @click="toggleFullscreen">
|
||||
<Icon name="icon_minify_outlined" v-if="fullscreenFlag">
|
||||
<icon_minify_outlined class="svg-icon" />
|
||||
</Icon>
|
||||
<Icon name="icon_magnify_outlined" v-else>
|
||||
<icon_magnify_outlined class="svg-icon" />
|
||||
</Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, reactive, toRefs } from 'vue'
|
||||
import router from '@/router'
|
||||
import { ElIcon } from 'element-plus-secondary'
|
||||
import Icon from '../../icon-custom/src/Icon.vue'
|
||||
import icon_down_right_outlined from '@/assets/svg/icon_down-right_outlined.svg'
|
||||
import icon_up_left_outlined from '@/assets/svg/icon_up-left_outlined.svg'
|
||||
import icon_left_outlined from '@/assets/svg/icon_left_outlined.svg'
|
||||
import icon_download_outlined from '@/assets/svg/icon_download_outlined.svg'
|
||||
import icon_minify_outlined from '@/assets/svg/icon_minify_outlined.svg'
|
||||
import icon_magnify_outlined from '@/assets/svg/icon_magnify_outlined.svg'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const props = defineProps({
|
||||
canvasStyleData: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const { canvasStyleData } = toRefs(props)
|
||||
const { fullscreenFlag } = storeToRefs(dvMainStore)
|
||||
|
||||
const state = reactive({
|
||||
fullscreenElement: null,
|
||||
barActive: false,
|
||||
fullWidth: router.currentRoute.value.query?.fromLink === 'true' ? 126 : 94
|
||||
})
|
||||
|
||||
const functionClass = computed(() => {
|
||||
let result = 'link-bar-main-light'
|
||||
if (canvasStyleData.value?.dashboard?.themeColor === 'dark') {
|
||||
result = 'link-bar-main-dark'
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
||||
const fromLink = computed(() => {
|
||||
return router.currentRoute.value.query?.fromLink === 'true'
|
||||
})
|
||||
|
||||
const firstBarClick = () => {
|
||||
state.barActive = !state.barActive
|
||||
}
|
||||
const toggleFullscreen = () => {
|
||||
if (!document.fullscreenElement) {
|
||||
// 如果当前不是全屏状态,则启动全屏
|
||||
useEmitt().emitter.emit('canvasFullscreen')
|
||||
} else {
|
||||
// 如果当前是全屏状态,则退出全屏
|
||||
document.exitFullscreen().catch(error => {
|
||||
console.error('Exit fullscreen failed:', error)
|
||||
})
|
||||
}
|
||||
}
|
||||
const back2Last = () => {
|
||||
const parentUrl = localStorage.getItem('beforeJumpUrl')
|
||||
localStorage.removeItem('beforeJumpUrl')
|
||||
window.location.href = parentUrl
|
||||
window.location.reload()
|
||||
}
|
||||
const exportPDF = () => {
|
||||
useEmitt().emitter.emit('canvasDownload')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.link-bar-main {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
z-index: 10;
|
||||
height: 30px;
|
||||
width: var(--fullWidth);
|
||||
bottom: 24px;
|
||||
right: var(--fullContent);
|
||||
border-top-left-radius: 50%;
|
||||
border-bottom-left-radius: 50%;
|
||||
|
||||
&:hover {
|
||||
right: var(--firstHoveMove);
|
||||
}
|
||||
|
||||
transition: 0.2s; /* 添加过渡动画 */
|
||||
}
|
||||
|
||||
.link-bar-main-light {
|
||||
color: rgba(31, 35, 41, 1);
|
||||
|
||||
.bar-first {
|
||||
border-left: 1px solid rgba(222, 224, 227, 1);
|
||||
border-top: 1px solid rgba(222, 224, 227, 1);
|
||||
border-bottom: 1px solid rgba(222, 224, 227, 1);
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
.bar-content {
|
||||
border-top: 1px solid rgba(222, 224, 227, 1);
|
||||
border-bottom: 1px solid rgba(222, 224, 227, 1);
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
|
||||
.bar-diver {
|
||||
background: rgba(187, 191, 196, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.link-bar-main-dark {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
|
||||
.bar-first {
|
||||
border-left: 1px solid rgba(67, 67, 67, 1);
|
||||
border-top: 1px solid rgba(67, 67, 67, 1);
|
||||
border-bottom: 1px solid rgba(67, 67, 67, 1);
|
||||
background-color: rgba(26, 26, 26, 1);
|
||||
}
|
||||
|
||||
.bar-content {
|
||||
border-top: 1px solid rgba(67, 67, 67, 1);
|
||||
border-bottom: 1px solid rgba(67, 67, 67, 1);
|
||||
background-color: rgba(26, 26, 26, 1);
|
||||
|
||||
.bar-diver {
|
||||
background: rgba(95, 95, 95, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.link-bar-main-active {
|
||||
right: 0px !important;
|
||||
transition: 0.2s; /* 添加过渡动画 */
|
||||
}
|
||||
|
||||
.bar-first {
|
||||
width: 36px;
|
||||
border-top-left-radius: 50%;
|
||||
border-bottom-left-radius: 50%;
|
||||
padding: 4px 0 4px 8px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: rgba(31, 35, 41, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.bar-diver {
|
||||
width: 1px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.bar-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.link-icon-active {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
cursor: pointer;
|
||||
transition: 0.1s;
|
||||
border-radius: 3px;
|
||||
padding-top: 2px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
margin-left: 4px;
|
||||
text-align: center;
|
||||
|
||||
&:active {
|
||||
color: #000;
|
||||
border-color: #3a8ee6;
|
||||
background-color: red;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(31, 35, 41, 0.1);
|
||||
color: #3a8ee6;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -9,7 +9,21 @@
|
||||
element-loading-background="rgba(255, 255, 255, 1)"
|
||||
@dblclick="handleDbClick"
|
||||
>
|
||||
<div v-if="showCheck" class="del-from-mobile" @click="delFromMobile">
|
||||
<div
|
||||
title="同步PC设计"
|
||||
v-if="showCheck && ['VQuery'].includes(element.component)"
|
||||
class="refresh-from-pc"
|
||||
@click="updateFromMobile($event, 'syncPcDesign')"
|
||||
>
|
||||
<el-icon>
|
||||
<Icon name="icon_replace_outlined"><replaceOutlined class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
</div>
|
||||
<div
|
||||
v-if="showCheck"
|
||||
class="del-from-mobile"
|
||||
@click="updateFromMobile($event, 'delFromMobile')"
|
||||
>
|
||||
<el-icon>
|
||||
<Icon name="mobile-checkbox"><mobileCheckbox class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
@ -98,6 +112,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import mobileCheckbox from '@/assets/svg/mobile-checkbox.svg'
|
||||
import replaceOutlined from '@/assets/svg/icon_replace_outlined.svg'
|
||||
import dvLock from '@/assets/svg/dv-lock.svg'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import calculateComponentPositionAndSize, {
|
||||
@ -141,7 +156,8 @@ const {
|
||||
tabCollisionActiveId,
|
||||
tabMoveInActiveId,
|
||||
tabMoveOutComponentId,
|
||||
mobileInPc
|
||||
mobileInPc,
|
||||
mainScrollTop
|
||||
} = storeToRefs(dvMainStore)
|
||||
const { editorMap, areaData, isCtrlOrCmdDown } = storeToRefs(composeStore)
|
||||
const emit = defineEmits([
|
||||
@ -282,9 +298,13 @@ const showCheck = computed(() => {
|
||||
return mobileInPc.value && element.value.canvasId === 'canvas-main'
|
||||
})
|
||||
|
||||
const delFromMobile = () => {
|
||||
const updateFromMobile = (e, type) => {
|
||||
if (type === 'syncPcDesign') {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}
|
||||
useEmitt().emitter.emit('onMobileStatusChange', {
|
||||
type: 'delFromMobile',
|
||||
type: type,
|
||||
value: element.value.id
|
||||
})
|
||||
}
|
||||
@ -539,7 +559,7 @@ const handleMouseDownOnShape = e => {
|
||||
mouseY:
|
||||
!isDashboard() && outerTabDom
|
||||
? outerTabDom.offsetTop + curDom.offsetTop + offsetY + 100
|
||||
: curY,
|
||||
: curY + mainScrollTop.value,
|
||||
width: componentWidth,
|
||||
height: componentHeight
|
||||
})
|
||||
@ -865,9 +885,7 @@ const componentBackgroundStyle = computed(() => {
|
||||
innerPadding,
|
||||
borderRadius
|
||||
} = element.value.commonBackground
|
||||
const innerPaddingTarget = ['Group', 'DeTabs'].includes(element.value.component)
|
||||
? 0
|
||||
: innerPadding
|
||||
const innerPaddingTarget = ['Group'].includes(element.value.component) ? 0 : innerPadding
|
||||
const style = {
|
||||
padding: innerPaddingTarget * scale.value + 'px',
|
||||
borderRadius: borderRadius + 'px'
|
||||
@ -1080,6 +1098,15 @@ onMounted(() => {
|
||||
<style lang="less" scoped>
|
||||
.shape {
|
||||
position: absolute;
|
||||
.refresh-from-pc {
|
||||
position: absolute;
|
||||
right: 38px;
|
||||
top: 12px;
|
||||
z-index: 2;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
color: var(--ed-color-primary);
|
||||
}
|
||||
.del-from-mobile {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
|
||||
@ -21,6 +21,27 @@
|
||||
</div>
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-item no-margin-bottom" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
size="small"
|
||||
:effect="themes"
|
||||
v-model="canvasStyleData.suspensionButtonAvailable"
|
||||
@change="onPopButtonChange"
|
||||
>
|
||||
<div style="display: flex; line-height: 14px">
|
||||
<span style="margin-right: 4px">显示放大、导出等悬浮按钮</span>
|
||||
<el-tooltip class="item" :effect="themes" placement="bottom">
|
||||
<template #content>
|
||||
<div>预览时启用</div>
|
||||
</template>
|
||||
<el-icon class="hint-icon" :class="{ 'hint-icon--dark': themes === 'dark' }">
|
||||
<Icon name="icon_info_outlined"><icon_info_outlined class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -47,7 +47,8 @@ const dialogInfo = {
|
||||
}
|
||||
|
||||
const dialogInit = initInfo => {
|
||||
const canvasTypeName = initInfo.canvasType === 'dataV' ? '数据大屏' : '仪表板'
|
||||
const canvasTypeName =
|
||||
initInfo.canvasType === 'dataV' ? t('work_branch.big_data_screen') : t('work_branch.dashboard')
|
||||
dialogInfo.resourceId = initInfo.resourceId
|
||||
dialogInfo.title = '存在未保存的' + canvasTypeName
|
||||
dialogInfo.tips = canvasTypeName + '存在未保存的修改,立即恢复?'
|
||||
|
||||
@ -465,7 +465,9 @@ const { t } = useI18n()
|
||||
const dialogShow = ref(false)
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
|
||||
const resourceType = computed(() => (dvInfo.value.type === 'dashboard' ? '仪表板' : '数据大屏'))
|
||||
const resourceType = computed(() =>
|
||||
dvInfo.value.type === 'dashboard' ? t('work_branch.dashboard') : t('work_branch.big_data_screen')
|
||||
)
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
|
||||
@ -205,7 +205,7 @@
|
||||
<div class="select-filed">
|
||||
<el-select
|
||||
v-model="itemLinkage.targetField"
|
||||
:placeholder="'请选择'"
|
||||
:placeholder="t('common.selectText')"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
|
||||
@ -166,7 +166,7 @@
|
||||
filterable
|
||||
clearable
|
||||
style="width: 100%"
|
||||
placeholder="请选择"
|
||||
:placeholder="t('common.selectText')"
|
||||
>
|
||||
<template #header>
|
||||
<el-tabs
|
||||
|
||||
@ -183,7 +183,8 @@ const DETAIL_CHART_ATTR: DeepPartial<ChartObj> = {
|
||||
tableCell: {
|
||||
tableItemBgColor: '#FFFFFF',
|
||||
tableFontColor: '#7C7E81',
|
||||
enableTableCrossBG: false
|
||||
enableTableCrossBG: false,
|
||||
mergeCells: false
|
||||
},
|
||||
tooltip: {
|
||||
show: false
|
||||
|
||||
@ -16,13 +16,17 @@
|
||||
import dvDragTips from '@/assets/svg/dv-drag-tips.svg'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
const { t } = useI18n()
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { dvInfo, mobileInPc } = storeToRefs(dvMainStore)
|
||||
|
||||
const tips =
|
||||
'从顶部工具栏中选择组件,添加到这里创建' +
|
||||
(dvInfo.value.type === 'dashboard' ? '仪表板' : '数据大屏')
|
||||
(dvInfo.value.type === 'dashboard'
|
||||
? t('work_branch.dashboard')
|
||||
: t('work_branch.big_data_screen'))
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@ -68,6 +68,7 @@
|
||||
<div class="indented-item">
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||
<el-color-picker
|
||||
v-if="state.commonBackground.backgroundColor"
|
||||
v-model="state.commonBackground.backgroundColor"
|
||||
:effect="themes"
|
||||
:disabled="!state.commonBackground.backgroundColorSelect"
|
||||
@ -324,7 +325,6 @@ const upload = file => {
|
||||
}
|
||||
|
||||
const onBackgroundChange = () => {
|
||||
snapshotStore.recordSnapshotCacheToMobile('commonBackground')
|
||||
emits('onBackgroundChange', state.commonBackground)
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { ref } from 'vue'
|
||||
import { personInfoApi } from '@/api/user'
|
||||
import { ipInfoApi } from '@/api/user'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
|
||||
const { dvInfo } = storeToRefs(dvMainStore)
|
||||
@ -163,7 +163,7 @@ export function activeWatermarkCheckUser(domId, canvasId, scale = 1) {
|
||||
scale
|
||||
)
|
||||
} else {
|
||||
personInfoApi().then(res => {
|
||||
ipInfoApi().then(res => {
|
||||
userInfo.value = res.data
|
||||
if (userInfo.value && userInfo.value.model !== 'lose') {
|
||||
activeWatermark(
|
||||
|
||||
@ -53,6 +53,7 @@ const dashboardActive = computed(() => {
|
||||
|
||||
const onBackgroundChange = val => {
|
||||
element.value.commonBackground = val
|
||||
snapshotStore.recordSnapshotCacheToMobile('commonBackground')
|
||||
emits('onAttrChange', { custom: 'commonBackground' })
|
||||
}
|
||||
|
||||
|
||||
@ -290,6 +290,7 @@ import dvStyleHeadFontActiveColor from '@/assets/svg/dv-style-headFontActiveColo
|
||||
import dvStyleHeadFontColor from '@/assets/svg/dv-style-headFontColor.svg'
|
||||
import dvStyleScrollSpeed from '@/assets/svg/dv-style-scroll-speed.svg'
|
||||
import dvStyleOpacity from '@/assets/svg/dv-style-opacity.svg'
|
||||
import dvStyleTabHead from '@/assets/svg/dv-style-tab-head.svg'
|
||||
import dvStyleFontSize from '@/assets/svg/dv-style-fontSize.svg'
|
||||
import dvStyleLetterSpacing from '@/assets/svg/dv-style-letterSpacing.svg'
|
||||
import dvStyleActiveFont from '@/assets/svg/dv-style-activeFont.svg'
|
||||
@ -371,6 +372,11 @@ const opacitySizeList = [
|
||||
{ name: '1', value: 1 }
|
||||
]
|
||||
|
||||
const titleHideList = [
|
||||
{ name: '隐藏', value: true },
|
||||
{ name: '显示', value: false }
|
||||
]
|
||||
|
||||
const styleForm = computed<any>(() => element.value.style)
|
||||
const state = reactive({
|
||||
fontSize: [],
|
||||
@ -466,6 +472,13 @@ const styleOptionKeyArray = [
|
||||
customOption: opacitySizeList,
|
||||
width: '90px',
|
||||
icon: dvStyleOpacity
|
||||
},
|
||||
{
|
||||
value: 'titleHide',
|
||||
label: '标题样式',
|
||||
customOption: titleHideList,
|
||||
width: '90px',
|
||||
icon: dvStyleTabHead
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@ -2,7 +2,12 @@
|
||||
<div
|
||||
v-if="state.tabShow"
|
||||
style="width: 100%; height: 100%"
|
||||
:class="[headClass, `ed-tabs-${curThemes}`]"
|
||||
:class="[
|
||||
headClass,
|
||||
`ed-tabs-${curThemes}`,
|
||||
{ 'title-hidde-tab': hideTitle },
|
||||
{ 'title-show-tab': !hideTitle }
|
||||
]"
|
||||
class="custom-tabs-head"
|
||||
ref="tabComponentRef"
|
||||
>
|
||||
@ -14,8 +19,9 @@
|
||||
:active-color="activeColor"
|
||||
:border-color="noBorderColor"
|
||||
:border-active-color="borderActiveColor"
|
||||
:hide-title="hideTitle"
|
||||
>
|
||||
<template :key="tabItem.name" v-for="(tabItem, index) in element.propValue">
|
||||
<template :key="tabItem.name" v-for="tabItem in element.propValue">
|
||||
<el-tab-pane
|
||||
class="el-tab-pane-custom"
|
||||
:lazy="isEditMode"
|
||||
@ -54,32 +60,39 @@
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
<de-canvas
|
||||
v-if="isEdit && !mobileInPc"
|
||||
:ref="'tabCanvas_' + index"
|
||||
:component-data="tabItem.componentData"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:canvas-view-info="canvasViewInfo"
|
||||
:canvas-id="element.id + '--' + tabItem.name"
|
||||
:class="moveActive ? 'canvas-move-in' : ''"
|
||||
:canvas-active="editableTabsValue === tabItem.name"
|
||||
></de-canvas>
|
||||
<de-preview
|
||||
v-else
|
||||
:ref="'dashboardPreview'"
|
||||
:dv-info="dvInfo"
|
||||
:cur-gap="curPreviewGap"
|
||||
:component-data="tabItem.componentData"
|
||||
:canvas-style-data="{}"
|
||||
:canvas-view-info="canvasViewInfo"
|
||||
:canvas-id="element.id + '--' + tabItem.name"
|
||||
:preview-active="editableTabsValue === tabItem.name"
|
||||
:show-position="showPosition"
|
||||
:outer-scale="scale"
|
||||
:outer-search-count="searchCount"
|
||||
></de-preview>
|
||||
</el-tab-pane>
|
||||
</template>
|
||||
<div
|
||||
style="position: absolute; width: 100%; height: 100%"
|
||||
:key="tabItem.name + '-content'"
|
||||
v-for="(tabItem, index) in element.propValue"
|
||||
:class="{ 'switch-hidden': editableTabsValue !== tabItem.name }"
|
||||
>
|
||||
<de-canvas
|
||||
v-if="isEdit && !mobileInPc"
|
||||
:ref="'tabCanvas_' + index"
|
||||
:component-data="tabItem.componentData"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:canvas-view-info="canvasViewInfo"
|
||||
:canvas-id="element.id + '--' + tabItem.name"
|
||||
:class="moveActive ? 'canvas-move-in' : ''"
|
||||
:canvas-active="editableTabsValue === tabItem.name"
|
||||
></de-canvas>
|
||||
<de-preview
|
||||
v-else
|
||||
:ref="'dashboardPreview'"
|
||||
:dv-info="dvInfo"
|
||||
:cur-gap="curPreviewGap"
|
||||
:component-data="tabItem.componentData"
|
||||
:canvas-style-data="{}"
|
||||
:canvas-view-info="canvasViewInfo"
|
||||
:canvas-id="element.id + '--' + tabItem.name"
|
||||
:preview-active="editableTabsValue === tabItem.name"
|
||||
:show-position="showPosition"
|
||||
:outer-scale="scale"
|
||||
:outer-search-count="searchCount"
|
||||
></de-preview>
|
||||
</div>
|
||||
</de-custom-tab>
|
||||
<el-dialog
|
||||
title="编辑标题"
|
||||
@ -111,6 +124,7 @@ import {
|
||||
getCurrentInstance,
|
||||
nextTick,
|
||||
onBeforeMount,
|
||||
onBeforeUnmount,
|
||||
onMounted,
|
||||
reactive,
|
||||
ref,
|
||||
@ -128,12 +142,13 @@ import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { getPanelAllLinkageInfo } from '@/api/visualization/linkage'
|
||||
import { dataVTabComponentAdd, groupSizeStyleAdaptor } from '@/utils/style'
|
||||
import { copyStoreWithOut, deepCopyTabItemHelper } from '@/store/modules/data-visualization/copy'
|
||||
import { deepCopyTabItemHelper } from '@/store/modules/data-visualization/copy'
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const { tabMoveInActiveId, bashMatrixInfo, editMode, mobileInPc } = storeToRefs(dvMainStore)
|
||||
const tabComponentRef = ref(null)
|
||||
let carouselTimer = null
|
||||
const copyStore = copyStoreWithOut()
|
||||
|
||||
const props = defineProps({
|
||||
canvasStyleData: {
|
||||
@ -202,6 +217,19 @@ const editableTabsValue = ref(null)
|
||||
const noBorderColor = ref('none')
|
||||
let currentInstance
|
||||
|
||||
const hideTitle = computed(() => {
|
||||
if (
|
||||
element.value &&
|
||||
element.value.style &&
|
||||
element.value.style.titleHide &&
|
||||
typeof element.value.style.titleHide === 'boolean'
|
||||
) {
|
||||
return element.value.style.titleHide
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
const isEditMode = computed(() => editMode.value === 'edit' && isEdit.value && !mobileInPc.value)
|
||||
const curThemes = isDashboard() ? 'light' : 'dark'
|
||||
const calcTabLength = () => {
|
||||
@ -233,6 +261,7 @@ const curPreviewGap = computed(() =>
|
||||
function sureCurTitle() {
|
||||
state.curItem.title = state.textarea
|
||||
state.dialogVisible = false
|
||||
snapshotStore.recordSnapshotCache()
|
||||
}
|
||||
|
||||
function addTab() {
|
||||
@ -245,6 +274,7 @@ function addTab() {
|
||||
}
|
||||
element.value.propValue.push(newTab)
|
||||
editableTabsValue.value = newTab.name
|
||||
snapshotStore.recordSnapshotCache()
|
||||
}
|
||||
|
||||
function deleteCur(param) {
|
||||
@ -286,9 +316,11 @@ function handleCommand(command) {
|
||||
break
|
||||
case 'deleteCur':
|
||||
deleteCur(command.param)
|
||||
snapshotStore.recordSnapshotCache()
|
||||
break
|
||||
case 'copyCur':
|
||||
copyCur(command.param)
|
||||
snapshotStore.recordSnapshotCache()
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -322,8 +354,9 @@ const componentMoveIn = component => {
|
||||
component.style.left = 0
|
||||
component.style.top = 0
|
||||
tabItem.componentData.push(component)
|
||||
refInstance.addItemBox(component) //在适当的时候初始化布局组件
|
||||
nextTick(() => {
|
||||
refInstance.addItemBox(component) //在适当的时候初始化布局组件
|
||||
refInstance.canvasInitImmediately()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@ -496,20 +529,26 @@ onMounted(() => {
|
||||
editableTabsValue.value = element.value.propValue[0].name
|
||||
}
|
||||
calcTabLength()
|
||||
eventBus.on('onTabMoveIn-' + element.value.id, componentMoveIn)
|
||||
eventBus.on('onTabMoveOut-' + element.value.id, componentMoveOut)
|
||||
eventBus.on('onTabSortChange-' + element.value.id, reShow)
|
||||
if (['canvas', 'canvasDataV', 'edit'].includes(showPosition.value) && !mobileInPc.value) {
|
||||
eventBus.on('onTabMoveIn-' + element.value.id, componentMoveIn)
|
||||
eventBus.on('onTabMoveOut-' + element.value.id, componentMoveOut)
|
||||
eventBus.on('onTabSortChange-' + element.value.id, reShow)
|
||||
}
|
||||
|
||||
currentInstance = getCurrentInstance()
|
||||
initCarousel()
|
||||
nextTick(() => {
|
||||
groupSizeStyleAdaptor(element.value)
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (['canvas', 'canvasDataV', 'edit'].includes(showPosition.value) && !mobileInPc.value) {
|
||||
eventBus.off('onTabMoveIn-' + element.value.id, componentMoveIn)
|
||||
eventBus.off('onTabMoveOut-' + element.value.id, componentMoveOut)
|
||||
eventBus.off('onTabSortChange-' + element.value.id, reShow)
|
||||
}
|
||||
})
|
||||
onBeforeMount(() => {
|
||||
eventBus.off('onTabMoveIn-' + element.value.id, componentMoveIn)
|
||||
eventBus.off('onTabMoveOut-' + element.value.id, componentMoveOut)
|
||||
eventBus.off('onTabSortChange-' + element.value.id, reShow)
|
||||
if (carouselTimer) {
|
||||
clearInterval(carouselTimer)
|
||||
carouselTimer = null
|
||||
@ -517,9 +556,18 @@ onBeforeMount(() => {
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
:deep(.ed-tabs__content) {
|
||||
height: calc(100% - 46px) !important;
|
||||
.title-hidde-tab {
|
||||
:deep(.ed-tabs__content) {
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.title-show-tab {
|
||||
:deep(.ed-tabs__content) {
|
||||
height: calc(100% - 46px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ed-tabs-dark {
|
||||
:deep(.ed-tabs__new-tab) {
|
||||
margin-right: 25px;
|
||||
@ -537,7 +585,6 @@ onBeforeMount(() => {
|
||||
}
|
||||
.el-tab-pane-custom {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.canvas-move-in {
|
||||
border: 2px dotted transparent;
|
||||
@ -558,4 +605,9 @@ onBeforeMount(() => {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.switch-hidden {
|
||||
opacity: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
const props = defineProps({
|
||||
hideTitle: Boolean,
|
||||
/* 颜色可以单词,如red;也可以是颜色值 */
|
||||
// 字体颜色
|
||||
fontColor: String,
|
||||
@ -37,7 +38,8 @@ const tabClassName = computed(() =>
|
||||
props.fontColor && 'fontColor',
|
||||
props.activeColor && 'activeColor',
|
||||
noBorder.value ? 'noBorder' : props.borderColor && 'borderColor',
|
||||
props.borderActiveColor && 'borderActiveColor'
|
||||
props.borderActiveColor && 'borderActiveColor',
|
||||
props.hideTitle && 'no-header'
|
||||
]
|
||||
)
|
||||
|
||||
@ -47,6 +49,11 @@ const noBorder = computed(() => props.borderColor === 'none')
|
||||
<style lang="less">
|
||||
.de-tabs {
|
||||
height: 100%;
|
||||
&.no-header {
|
||||
.ed-tabs__header {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.ed-tabs--card {
|
||||
> .ed-tabs__header {
|
||||
height: auto !important;
|
||||
|
||||
@ -67,7 +67,7 @@ import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const errMsg = ref('')
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { canvasViewInfo } = storeToRefs(dvMainStore)
|
||||
const { canvasViewInfo, mobileInPc } = storeToRefs(dvMainStore)
|
||||
const isError = ref(false)
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
|
||||
@ -459,7 +459,8 @@ const computedCanEdit = computed<boolean>(() => {
|
||||
editStatus.value &&
|
||||
canEdit.value === false &&
|
||||
!isError.value &&
|
||||
!disabled.value
|
||||
!disabled.value &&
|
||||
!mobileInPc.value
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ const { curComponent } = storeToRefs(dvMainStore)
|
||||
<div class="attr-list">
|
||||
<CommonAttr :element="curComponent"></CommonAttr>
|
||||
<div class="content">
|
||||
<span>内容</span>
|
||||
<span>{{ $t('visualization.content') }}</span>
|
||||
<el-input v-model="curComponent['propValue']" type="textarea" :rows="3" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
import icon_edit_outlined from '@/assets/svg/icon_edit_outlined.svg'
|
||||
import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import { isMobile } from '@/utils/utils'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
import QueryConditionConfiguration from './QueryConditionConfiguration.vue'
|
||||
@ -256,6 +257,7 @@ const releaseSelect = id => {
|
||||
|
||||
const queryDataForId = id => {
|
||||
let requiredName = ''
|
||||
let numName = ''
|
||||
const emitterList = (element.value.propValue || [])
|
||||
.filter(ele => ele.id === id)
|
||||
.reduce((pre, next) => {
|
||||
@ -288,6 +290,22 @@ const queryDataForId = id => {
|
||||
requiredName = next.name
|
||||
}
|
||||
}
|
||||
|
||||
if (next.displayType === '22') {
|
||||
if (
|
||||
!isNaN(next.numValueEnd) &&
|
||||
!isNaN(next.numValueStart) &&
|
||||
next.numValueEnd < next.numValueStart
|
||||
) {
|
||||
numName = next.name
|
||||
}
|
||||
if (
|
||||
[next.numValueEnd, next.numValueStart].filter(itx => ![null, undefined, ''].includes(itx))
|
||||
.length === 1
|
||||
) {
|
||||
requiredName = next.name
|
||||
}
|
||||
}
|
||||
const keyList = Object.entries(next.checkedFieldsMap)
|
||||
.filter(ele => next.checkedFields.includes(ele[0]))
|
||||
.filter(ele => !!ele[1])
|
||||
@ -296,7 +314,11 @@ const queryDataForId = id => {
|
||||
return pre
|
||||
}, [])
|
||||
if (!!requiredName) {
|
||||
ElMessage.error(`【${requiredName}】查询条件是必填项,请设置选项值后,再进行查询!`)
|
||||
ElMessage.error(`【${requiredName}】${t('v_query.before_querying')}`)
|
||||
return
|
||||
}
|
||||
if (!!numName) {
|
||||
ElMessage.error(`【${numName}】${t('v_query.the_minimum_value')}`)
|
||||
return
|
||||
}
|
||||
if (!emitterList.length) return
|
||||
@ -339,6 +361,7 @@ onBeforeUnmount(() => {
|
||||
})
|
||||
|
||||
const updateQueryCriteria = () => {
|
||||
if (dvMainStore.mobileInPc && !isMobile()) return
|
||||
Array.isArray(element.value.propValue) &&
|
||||
element.value.propValue.forEach(ele => {
|
||||
if (ele.auto) {
|
||||
@ -380,6 +403,10 @@ onMounted(() => {
|
||||
emitter.on(`editQueryCriteria${element.value.id}`, editQueryCriteria)
|
||||
emitter.on(`updateQueryCriteria${element.value.id}`, updateQueryCriteria)
|
||||
updateQueryCriteria()
|
||||
|
||||
if (dvMainStore.mobileInPc && !isMobile()) {
|
||||
queryData()
|
||||
}
|
||||
})
|
||||
|
||||
const dragover = () => {
|
||||
@ -488,6 +515,9 @@ const clearData = () => {
|
||||
})
|
||||
})
|
||||
;(list.value || []).reduce((pre, next) => {
|
||||
if (!next.visible) {
|
||||
return pre
|
||||
}
|
||||
next.selectValue = next.multiple || +next.displayType === 7 ? [] : undefined
|
||||
if (next.optionValueSource === 1 && next.defaultMapValue?.length) {
|
||||
next.mapValue = next.multiple ? [] : undefined
|
||||
@ -534,6 +564,7 @@ const boxWidth = computed(() => {
|
||||
|
||||
const queryData = () => {
|
||||
let requiredName = ''
|
||||
let numName = ''
|
||||
const emitterList = (element.value.propValue || []).reduce((pre, next) => {
|
||||
if (next.required) {
|
||||
if (!next.defaultValueCheck) {
|
||||
@ -564,6 +595,22 @@ const queryData = () => {
|
||||
requiredName = next.name
|
||||
}
|
||||
}
|
||||
|
||||
if (next.displayType === '22') {
|
||||
if (
|
||||
!isNaN(next.numValueEnd) &&
|
||||
!isNaN(next.numValueStart) &&
|
||||
next.numValueEnd < next.numValueStart
|
||||
) {
|
||||
numName = next.name
|
||||
}
|
||||
if (
|
||||
[next.numValueEnd, next.numValueStart].filter(itx => ![null, undefined, ''].includes(itx))
|
||||
.length === 1
|
||||
) {
|
||||
requiredName = next.name
|
||||
}
|
||||
}
|
||||
const keyList = Object.entries(next.checkedFieldsMap)
|
||||
.filter(ele => next.checkedFields.includes(ele[0]))
|
||||
.filter(ele => !!ele[1])
|
||||
@ -572,11 +619,18 @@ const queryData = () => {
|
||||
return pre
|
||||
}, [])
|
||||
if (!!requiredName) {
|
||||
ElMessage.error(`【${requiredName}】查询条件是必填项,请设置选项值后,再进行查询!`)
|
||||
ElMessage.error(`【${requiredName}】${t('v_query.before_querying')}`)
|
||||
return
|
||||
}
|
||||
|
||||
if (!!numName) {
|
||||
ElMessage.error(`【${numName}】${t('v_query.the_minimum_value')}`)
|
||||
return
|
||||
}
|
||||
if (!emitterList.length) return
|
||||
dvMainStore.setFirstLoadMap([...new Set([...emitterList, ...firstLoadMap.value])])
|
||||
if (!(dvMainStore.mobileInPc && !isMobile())) {
|
||||
dvMainStore.setFirstLoadMap([...new Set([...emitterList, ...firstLoadMap.value])])
|
||||
}
|
||||
emitterList.forEach(ele => {
|
||||
emitter.emit(`query-data-${ele}`)
|
||||
})
|
||||
@ -640,13 +694,13 @@ const autoStyle = computed(() => {
|
||||
>
|
||||
<div v-if="!listVisible.length" class="no-list-label flex-align-center">
|
||||
<div class="container flex-align-center">
|
||||
将右侧的字段拖拽到这里 或 点击
|
||||
{{ t('v_query.here_or_click') }}
|
||||
<el-button
|
||||
:disabled="showPosition === 'preview' || mobileInPc"
|
||||
@click="addCriteriaConfigOut"
|
||||
text
|
||||
>
|
||||
添加查询条件
|
||||
{{ t('v_query.add_query_condition') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@ -677,12 +731,16 @@ const autoStyle = computed(() => {
|
||||
class="label-wrapper-tooltip"
|
||||
v-if="showPosition !== 'preview' && !dvMainStore.mobileInPc"
|
||||
>
|
||||
<el-tooltip effect="dark" content="设置过滤条件" placement="top">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="t('v_query.set_filter_condition')"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon @click="editeQueryConfig(ele.id)">
|
||||
<Icon name="icon_edit_outlined"><icon_edit_outlined class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" content="删除条件" placement="top">
|
||||
<el-tooltip effect="dark" :content="t('v_query.delete_condition')" placement="top">
|
||||
<el-icon style="margin-left: 8px" @click="delQueryConfig(index)">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
><icon_deleteTrash_outlined class="svg-icon"
|
||||
@ -865,6 +923,7 @@ const autoStyle = computed(() => {
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
color: #575757;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -69,15 +69,15 @@ const relativeToCurrentTypeList = computed(() => {
|
||||
}
|
||||
return [
|
||||
{
|
||||
label: '年',
|
||||
label: t('dynamic_time.year'),
|
||||
value: 'year'
|
||||
},
|
||||
{
|
||||
label: '月',
|
||||
label: t('dynamic_time.month'),
|
||||
value: 'month'
|
||||
},
|
||||
{
|
||||
label: '日',
|
||||
label: t('dynamic_time.date'),
|
||||
value: 'date'
|
||||
}
|
||||
].slice(0, index)
|
||||
@ -90,11 +90,11 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'year':
|
||||
list = [
|
||||
{
|
||||
label: '今年',
|
||||
label: t('dynamic_year.current'),
|
||||
value: 'thisYear'
|
||||
},
|
||||
{
|
||||
label: '去年',
|
||||
label: t('dynamic_year.last'),
|
||||
value: 'lastYear'
|
||||
}
|
||||
]
|
||||
@ -102,11 +102,11 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'month':
|
||||
list = [
|
||||
{
|
||||
label: '本月',
|
||||
label: t('cron.this_month'),
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: '上月',
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
}
|
||||
]
|
||||
@ -114,19 +114,19 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'date':
|
||||
list = [
|
||||
{
|
||||
label: '今天',
|
||||
label: t('dynamic_time.today'),
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
label: t('dynamic_time.yesterday'),
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '月初',
|
||||
label: t('dynamic_time.firstOfMonth'),
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初',
|
||||
label: t('dynamic_time.firstOfYear'),
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
]
|
||||
@ -134,19 +134,19 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'datetime':
|
||||
list = [
|
||||
{
|
||||
label: '今天',
|
||||
label: t('dynamic_time.today'),
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
label: t('dynamic_time.yesterday'),
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '月初',
|
||||
label: t('dynamic_time.firstOfMonth'),
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初',
|
||||
label: t('dynamic_time.firstOfYear'),
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
]
|
||||
@ -159,7 +159,7 @@ const relativeToCurrentList = computed(() => {
|
||||
return [
|
||||
...list,
|
||||
{
|
||||
label: '自定义',
|
||||
label: t('dynamic_time.custom'),
|
||||
value: 'custom'
|
||||
}
|
||||
]
|
||||
@ -172,11 +172,11 @@ const relativeToCurrentListRange = computed(() => {
|
||||
case 'yearrange':
|
||||
list = [
|
||||
{
|
||||
label: '今年',
|
||||
label: t('dynamic_year.current'),
|
||||
value: 'thisYear'
|
||||
},
|
||||
{
|
||||
label: '去年',
|
||||
label: t('dynamic_year.last'),
|
||||
value: 'lastYear'
|
||||
}
|
||||
]
|
||||
@ -184,23 +184,23 @@ const relativeToCurrentListRange = computed(() => {
|
||||
case 'monthrange':
|
||||
list = [
|
||||
{
|
||||
label: '本月',
|
||||
label: t('cron.this_month'),
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: '上月',
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
label: '最近 3 个 月',
|
||||
label: t('v_query.last_3_months'),
|
||||
value: 'LastThreeMonths'
|
||||
},
|
||||
{
|
||||
label: '最近 6 个 月',
|
||||
label: t('v_query.last_6_months'),
|
||||
value: 'LastSixMonths'
|
||||
},
|
||||
{
|
||||
label: '最近 12 个 月',
|
||||
label: t('v_query.last_12_months'),
|
||||
value: 'LastTwelveMonths'
|
||||
}
|
||||
]
|
||||
@ -209,23 +209,23 @@ const relativeToCurrentListRange = computed(() => {
|
||||
case 'datetimerange':
|
||||
list = [
|
||||
{
|
||||
label: '今天',
|
||||
label: t('dynamic_time.today'),
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
label: t('dynamic_time.yesterday'),
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '最近 3 天',
|
||||
label: t('v_query.last_3_days'),
|
||||
value: 'LastThreeDays'
|
||||
},
|
||||
{
|
||||
label: '月初至今',
|
||||
label: t('v_query.month_to_date'),
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初至今',
|
||||
label: t('v_query.year_to_date'),
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
]
|
||||
@ -238,7 +238,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
return [
|
||||
...list,
|
||||
{
|
||||
label: '自定义',
|
||||
label: t('dynamic_time.custom'),
|
||||
value: 'custom'
|
||||
}
|
||||
]
|
||||
@ -246,11 +246,11 @@ const relativeToCurrentListRange = computed(() => {
|
||||
|
||||
const aroundList = [
|
||||
{
|
||||
label: '前',
|
||||
label: t('dynamic_time.before'),
|
||||
value: 'f'
|
||||
},
|
||||
{
|
||||
label: '后',
|
||||
label: t('dynamic_time.after'),
|
||||
value: 'b'
|
||||
}
|
||||
]
|
||||
@ -262,11 +262,11 @@ const dynamicTime = computed(() => {
|
||||
|
||||
const operators = [
|
||||
{
|
||||
label: '精确匹配',
|
||||
label: t('v_query.exact_match'),
|
||||
value: 'eq'
|
||||
},
|
||||
{
|
||||
label: '模糊匹配',
|
||||
label: t('v_query.fuzzy_match'),
|
||||
value: 'like'
|
||||
}
|
||||
]
|
||||
@ -320,18 +320,11 @@ defineExpose({
|
||||
mult,
|
||||
single
|
||||
})
|
||||
const handleInputStart = value => {
|
||||
curComponent.value.defaultNumValueStart = value.replace(/[^\d.]/g, '')
|
||||
}
|
||||
|
||||
const handleInputEnd = value => {
|
||||
curComponent.value.defaultNumValueEnd = value.replace(/[^\d.]/g, '')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="list-item top-item" v-if="curComponent.displayType === '8'" @click.stop>
|
||||
<div class="label">设置默认值</div>
|
||||
<div class="label">{{ t('dynamic_time.set_default') }}</div>
|
||||
<div class="value" :class="curComponent.hideConditionSwitching && 'hide-condition_switching'">
|
||||
<div class="condition-type">
|
||||
<el-select
|
||||
@ -352,7 +345,9 @@ const handleInputEnd = value => {
|
||||
<div class="bottom-line"></div>
|
||||
</div>
|
||||
<div class="condition-type" v-if="[1, 2].includes(curComponent.conditionType)">
|
||||
<sapn class="condition-type-tip">{{ curComponent.conditionType === 1 ? '与' : '或' }}</sapn>
|
||||
<sapn class="condition-type-tip">{{
|
||||
curComponent.conditionType === 1 ? t('chart.and') : t('chart.or')
|
||||
}}</sapn>
|
||||
<el-select
|
||||
v-if="!curComponent.hideConditionSwitching"
|
||||
class="condition-value-select"
|
||||
@ -374,19 +369,22 @@ const handleInputEnd = value => {
|
||||
</div>
|
||||
<div class="list-item top-item" v-if="curComponent.displayType === '22'" @click.stop>
|
||||
<div class="label">
|
||||
<el-checkbox v-model="curComponent.defaultValueCheck" label="设置默认值" />
|
||||
<el-checkbox
|
||||
v-model="curComponent.defaultValueCheck"
|
||||
:label="t('dynamic_time.set_default')"
|
||||
/>
|
||||
</div>
|
||||
<div class="setting-content" style="display: flex; align-items: center">
|
||||
<el-input-number
|
||||
:disabled="!curComponent.defaultValueCheck"
|
||||
placeholder="请输入最小值"
|
||||
:placeholder="t('system.the_minimum_value')"
|
||||
style="width: 192.5px"
|
||||
controls-position="right"
|
||||
v-model="curComponent.defaultNumValueStart"
|
||||
/>
|
||||
<div class="num-value_line"></div>
|
||||
<el-input-number
|
||||
placeholder="请输入最大值"
|
||||
:placeholder="t('system.the_maximum_value')"
|
||||
style="width: 192.5px"
|
||||
controls-position="right"
|
||||
:disabled="!curComponent.defaultValueCheck"
|
||||
@ -398,7 +396,7 @@ const handleInputEnd = value => {
|
||||
v-if="!['1', '7', '8', '22'].includes(curComponent.displayType) && showFlag"
|
||||
class="list-item"
|
||||
>
|
||||
<div class="label">选项类型</div>
|
||||
<div class="label">{{ t('v_query.option_type') }}</div>
|
||||
<div class="value">
|
||||
<el-radio-group
|
||||
class="larger-radio"
|
||||
@ -412,7 +410,7 @@ const handleInputEnd = value => {
|
||||
</div>
|
||||
<div v-if="curComponent.displayType === '7' && showFlag" class="list-item">
|
||||
<div class="label">
|
||||
<el-checkbox v-model="curComponent.setTimeRange" label="设置时间筛选范围" />
|
||||
<el-checkbox v-model="curComponent.setTimeRange" :label="t('v_query.time_filter_range')" />
|
||||
</div>
|
||||
<div class="setting-content">
|
||||
<el-popover
|
||||
@ -433,7 +431,7 @@ const handleInputEnd = value => {
|
||||
<template #icon>
|
||||
<Icon name="icon_admin_outlined"><icon_admin_outlined class="svg-icon" /></Icon>
|
||||
</template>
|
||||
设置
|
||||
{{ t('dynamic_time.set') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<RangeFilterTime
|
||||
@ -446,7 +444,7 @@ const handleInputEnd = value => {
|
||||
curComponent.timeRange.intervalType !== 'none' || curComponent.timeRange.dynamicWindow
|
||||
"
|
||||
class="config-flag range-filter-time-flag"
|
||||
>已配置</span
|
||||
>{{ t('v_query.configured') }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@ -457,21 +455,24 @@ const handleInputEnd = value => {
|
||||
<div class="label">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
content="绑定参数后,不支持传空数据"
|
||||
:content="t('v_query.is_not_supported')"
|
||||
:disabled="!curComponent.parametersCheck"
|
||||
placement="top"
|
||||
>
|
||||
<el-checkbox
|
||||
:disabled="curComponent.parametersCheck"
|
||||
v-model="curComponent.showEmpty"
|
||||
label="选项值包含空数据"
|
||||
:label="t('v_query.contains_empty_data')"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!['8', '22'].includes(curComponent.displayType)" class="list-item">
|
||||
<div class="label">
|
||||
<el-checkbox v-model="curComponent.defaultValueCheck" label="设置默认值" />
|
||||
<el-checkbox
|
||||
v-model="curComponent.defaultValueCheck"
|
||||
:label="t('dynamic_time.set_default')"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="setting-content"
|
||||
@ -479,13 +480,13 @@ const handleInputEnd = value => {
|
||||
>
|
||||
<div class="setting">
|
||||
<el-radio-group @change="handleTimeTypeChange" v-model="curComponent.timeType">
|
||||
<el-radio label="fixed">固定时间</el-radio>
|
||||
<el-radio label="dynamic">动态时间</el-radio>
|
||||
<el-radio label="fixed">{{ t('dynamic_time.fix') }}</el-radio>
|
||||
<el-radio label="dynamic">{{ t('dynamic_time.dynamic') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<template v-if="dynamicTime && curComponent.displayType === '1'">
|
||||
<div class="setting">
|
||||
<div class="setting-label">相对当前</div>
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select @focus="handleDialogClick" v-model="curComponent.relativeToCurrent">
|
||||
<el-option
|
||||
@ -533,7 +534,7 @@ const handleInputEnd = value => {
|
||||
</template>
|
||||
<template v-else-if="dynamicTime && curComponent.displayType === '7'">
|
||||
<div class="setting">
|
||||
<div class="setting-label">相对当前</div>
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select @focus="handleDialogClick" v-model="curComponent.relativeToCurrentRange">
|
||||
<el-option
|
||||
@ -554,7 +555,7 @@ const handleInputEnd = value => {
|
||||
) && 'is-year-month-range'
|
||||
"
|
||||
>
|
||||
<div class="setting-label">开始时间</div>
|
||||
<div class="setting-label">{{ t('datasource.start_time') }}</div>
|
||||
<div class="setting-input with-date range">
|
||||
<el-input-number
|
||||
step-strictly
|
||||
@ -590,7 +591,7 @@ const handleInputEnd = value => {
|
||||
) && 'is-year-month-range'
|
||||
"
|
||||
>
|
||||
<div class="setting-label">结束时间</div>
|
||||
<div class="setting-label">{{ t('datasource.end_time') }}</div>
|
||||
<div class="setting-input with-date range">
|
||||
<el-input-number
|
||||
v-model="curComponent.timeNumRange"
|
||||
@ -620,7 +621,7 @@ const handleInputEnd = value => {
|
||||
</template>
|
||||
</div>
|
||||
<div v-if="curComponent.defaultValueCheck" class="parameters" :class="dynamicTime && 'setting'">
|
||||
<div class="setting-label" v-if="dynamicTime">预览</div>
|
||||
<div class="setting-label" v-if="dynamicTime">{{ t('template_manage.preview') }}</div>
|
||||
<div :class="dynamicTime ? 'setting-value' : 'w100'">
|
||||
<component :config="curComponent" isConfig ref="inputCom" :is="filterTypeCom"></component>
|
||||
</div>
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
import { toRefs, onBeforeMount, type PropType, type Ref, inject, computed, nextTick } from 'vue'
|
||||
interface SelectConfig {
|
||||
id: string
|
||||
defaultValueCheck: boolean
|
||||
defaultNumValueEnd: number
|
||||
numValueEnd: number
|
||||
numValueStart: number
|
||||
@ -11,7 +12,7 @@ interface SelectConfig {
|
||||
const placeholder: Ref = inject('placeholder')
|
||||
|
||||
const placeholderText = computed(() => {
|
||||
if (placeholder.value.placeholderShow) {
|
||||
if (placeholder?.value?.placeholderShow) {
|
||||
return props.config.placeholder
|
||||
}
|
||||
return ' '
|
||||
@ -26,7 +27,8 @@ const props = defineProps({
|
||||
defaultNumValueEnd: '',
|
||||
defaultNumValueStart: '',
|
||||
numValueEnd: '',
|
||||
numValueStart: ''
|
||||
numValueStart: '',
|
||||
defaultValueCheck: false
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -38,6 +40,11 @@ const props = defineProps({
|
||||
|
||||
const { config } = toRefs(props)
|
||||
const setParams = () => {
|
||||
if (!config.value.defaultValueCheck) {
|
||||
config.value.numValueEnd = undefined
|
||||
config.value.numValueStart = undefined
|
||||
return
|
||||
}
|
||||
const { defaultNumValueEnd, defaultNumValueStart } = config.value
|
||||
config.value.numValueEnd = defaultNumValueEnd
|
||||
config.value.numValueStart = defaultNumValueStart
|
||||
|
||||
@ -36,7 +36,7 @@ const cancelClick = () => {
|
||||
const confirmClick = () => {
|
||||
const { isError, arr } = setCascadeArrBack()
|
||||
if (isError) {
|
||||
ElMessage.error('查询条件或字段不能为空!')
|
||||
ElMessage.error(t('v_query.cannot_be_empty'))
|
||||
return
|
||||
}
|
||||
emits('saveCascade', arr)
|
||||
@ -141,7 +141,7 @@ const addCascadeItem = item => {
|
||||
item.push({
|
||||
datasetId: '',
|
||||
fieldId: '',
|
||||
placeholder: item.length ? '' : '第一级无需配置被级联字段',
|
||||
placeholder: item.length ? '' : t('v_query.the_first_level'),
|
||||
id: guid()
|
||||
})
|
||||
}
|
||||
@ -158,7 +158,7 @@ const setPlaceholder = () => {
|
||||
item.datasetId &&
|
||||
item.datasetId.split('--')[0] === ele[idx - 1].datasetId.split('--')[0]
|
||||
) {
|
||||
item.placeholder = '与上一级使用同一个数据集,无需配置被级联字段'
|
||||
item.placeholder = t('v_query.configure_cascaded_fields')
|
||||
item.fieldId = ''
|
||||
}
|
||||
})
|
||||
@ -168,7 +168,7 @@ const setPlaceholder = () => {
|
||||
const deleteCascade = (idx, item) => {
|
||||
item.splice(idx, 1)
|
||||
item[0].fieldId = ''
|
||||
item[0].placeholder = '第一级无需配置被级联字段'
|
||||
item[0].placeholder = t('v_query.the_first_level')
|
||||
setPlaceholder()
|
||||
}
|
||||
|
||||
@ -182,7 +182,14 @@ const addCascadeBlock = () => {
|
||||
cascadeList.value.push(arr)
|
||||
}
|
||||
|
||||
const indexCascade = ' 一二三四五'
|
||||
const indexCascade = [
|
||||
' ',
|
||||
t('report.week_mon'),
|
||||
t('report.week_tue'),
|
||||
t('report.week_wed'),
|
||||
t('report.week_thu'),
|
||||
t('report.week_fri')
|
||||
]
|
||||
|
||||
defineExpose({
|
||||
init
|
||||
@ -201,21 +208,22 @@ defineExpose({
|
||||
>
|
||||
<template #title>
|
||||
<div class="title">
|
||||
查询条件级联配置<span class="tip">(仅上级能级联下级,不可反向级联)</span>
|
||||
{{ t('v_query.condition_cascade_configuration')
|
||||
}}<span class="tip">{{ t('v_query.not_reverse_cascade') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="content">
|
||||
<el-icon style="font-size: 16px">
|
||||
<Icon name="icon_info_colorful"><icon_info_colorful class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
基于当前查询组件的查询条件,如果需要进行级联配置,需要满足以下条件:<br />
|
||||
1. 展示类型:文本下拉组件和数字下拉组件;2. 选项值来源:选择数据集<br />
|
||||
{{ t('v_query.must_be_met') }}<br />
|
||||
{{ t('v_query.select_data_set') }}<br />
|
||||
</div>
|
||||
<el-button text @click="addCascadeBlock">
|
||||
<template #icon>
|
||||
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
||||
</template>
|
||||
添加级联配置
|
||||
{{ t('v_query.add_cascade_configuration') }}
|
||||
</el-button>
|
||||
<div class="cascade-content" v-for="(item, index) in cascadeList" :key="index">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||
@ -223,7 +231,7 @@ defineExpose({
|
||||
<template #icon>
|
||||
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
||||
</template>
|
||||
添加级联条件
|
||||
{{ t('v_query.add_cascade_condition') }}
|
||||
</el-button>
|
||||
<el-button @click="deleteCascadeBlock(index)" class="cascade-delete-block" text>
|
||||
<template #icon>
|
||||
@ -234,13 +242,13 @@ defineExpose({
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="cascade-item">
|
||||
<div class="label">查询条件层级</div>
|
||||
<div class="item-name">请选择查询条件</div>
|
||||
<div class="label">{{ t('v_query.query_condition_level') }}</div>
|
||||
<div class="item-name">{{ t('v_query.select_query_condition') }}</div>
|
||||
<div class="cascade-icon"></div>
|
||||
<div class="item-field">请选择被级联字段</div>
|
||||
<div class="item-field">{{ t('v_query.select_cascaded_field') }}</div>
|
||||
</div>
|
||||
<div class="cascade-item" v-for="(ele, idx) in item" :key="ele.id">
|
||||
<div class="label">第{{ indexCascade[idx + 1] }}级</div>
|
||||
<div class="label">{{ t('v_query.level_1', { msg: indexCascade[idx + 1] }) }}</div>
|
||||
<div class="item-name">
|
||||
<el-select
|
||||
@visible-change="val => visibleChange(val, index, idx)"
|
||||
|
||||
@ -307,11 +307,11 @@ const showDatasetError = computed(() => {
|
||||
})
|
||||
const typeList = [
|
||||
{
|
||||
label: '重命名',
|
||||
label: t('data_fill.rename'),
|
||||
command: 'rename'
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
label: t('data_fill.delete'),
|
||||
command: 'del'
|
||||
}
|
||||
]
|
||||
@ -684,13 +684,13 @@ const setParameters = field => {
|
||||
Object.values(field?.fields || {})
|
||||
.flat()
|
||||
.filter(ele => fieldArr.includes(ele.id) && !!ele.variableName)
|
||||
.concat(curComponent.value.parameters.filter(ele => fieldArr.includes(ele.id)))
|
||||
)
|
||||
nextTick(() => {
|
||||
if (isTimeParameter.value) {
|
||||
const timeParameter = curComponent.value.parameters.find(ele => ele.deType === 1)
|
||||
curComponent.value.timeGranularity =
|
||||
typeTimeMap[
|
||||
curComponent.value.parameters[0].type[1] || curComponent.value.parameters[0].type[0]
|
||||
]
|
||||
typeTimeMap[timeParameter.type[1] || timeParameter.type[0]]
|
||||
curComponent.value.displayType = '1'
|
||||
}
|
||||
|
||||
@ -831,19 +831,19 @@ const notTimeRangeType = computed(() => {
|
||||
|
||||
const timeList = [
|
||||
{
|
||||
label: '年',
|
||||
label: t('dynamic_time.year'),
|
||||
value: 'year'
|
||||
},
|
||||
{
|
||||
label: '年月',
|
||||
label: t('chart.y_M'),
|
||||
value: 'month'
|
||||
},
|
||||
{
|
||||
label: '年月日',
|
||||
label: t('chart.y_M_d'),
|
||||
value: 'date'
|
||||
},
|
||||
{
|
||||
label: '年月日时分秒',
|
||||
label: t('chart.y_M_d_H_m_s'),
|
||||
value: 'datetime'
|
||||
}
|
||||
]
|
||||
@ -924,17 +924,14 @@ const confirmIdChange = () => {
|
||||
const handleDatasetChange = () => {
|
||||
if (!!newDatasetId && !!oldDatasetId) {
|
||||
curComponent.value.dataset.id = oldDatasetId
|
||||
ElMessageBox.confirm(
|
||||
'数据集的修改,会导致级联配置失效,因此对应的级联关系将被清除,确定修改吗?',
|
||||
{
|
||||
confirmButtonType: 'primary',
|
||||
type: 'warning',
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
autofocus: false,
|
||||
showClose: false
|
||||
}
|
||||
).then(() => {
|
||||
ElMessageBox.confirm(t('v_query.to_modify_it'), {
|
||||
confirmButtonType: 'primary',
|
||||
type: 'warning',
|
||||
confirmButtonText: t('commons.confirm'),
|
||||
cancelButtonText: t('commons.cancel'),
|
||||
autofocus: false,
|
||||
showClose: false
|
||||
}).then(() => {
|
||||
confirmIdChange()
|
||||
})
|
||||
return
|
||||
@ -1115,7 +1112,14 @@ const clearCascadeArrDataset = id => {
|
||||
cascadeArr = cascadeArr.filter(ele => !!ele.length)
|
||||
}
|
||||
|
||||
const indexCascade = ' 一二三四五'
|
||||
const indexCascade = [
|
||||
' ',
|
||||
t('report.week_mon'),
|
||||
t('report.week_tue'),
|
||||
t('report.week_wed'),
|
||||
t('report.week_thu'),
|
||||
t('report.week_fri')
|
||||
]
|
||||
|
||||
const validateConditionType = ({
|
||||
defaultConditionValueF,
|
||||
@ -1146,11 +1150,31 @@ const validate = () => {
|
||||
return conditions.value.some(ele => {
|
||||
if (ele.auto) return false
|
||||
if (!ele.checkedFields?.length || ele.checkedFields.some(itx => !ele.checkedFieldsMap[itx])) {
|
||||
ElMessage.error('请先勾选需要联动的图表及字段')
|
||||
ElMessage.error(t('v_query.be_linked_first'))
|
||||
return true
|
||||
}
|
||||
|
||||
if (ele.displayType === '22' && ele.defaultValueCheck) {
|
||||
ele.numValueEnd = ele.defaultNumValueEnd
|
||||
ele.numValueStart = ele.defaultNumValueStart
|
||||
if (
|
||||
(ele.defaultNumValueEnd !== 0 && !ele.defaultNumValueEnd) ||
|
||||
(ele.defaultNumValueStart !== 0 && !ele.defaultNumValueStart)
|
||||
) {
|
||||
ElMessage.error(t('v_query.cannot_be_empty_de'))
|
||||
return true
|
||||
}
|
||||
if (
|
||||
!isNaN(ele.defaultNumValueEnd) &&
|
||||
!isNaN(ele.defaultNumValueStart) &&
|
||||
ele.defaultNumValueEnd < ele.defaultNumValueStart
|
||||
) {
|
||||
ElMessage.error(t('v_query.the_minimum_value'))
|
||||
return true
|
||||
}
|
||||
}
|
||||
let displayTypeField = null
|
||||
let errorTips = '所选字段类型不一致,无法进行查询配置'
|
||||
let errorTips = t('v_query.cannot_be_performed')
|
||||
let hasParameterTimeArrType = 0
|
||||
let hasParameterNumArrType = 0
|
||||
if (
|
||||
@ -1180,7 +1204,7 @@ const validate = () => {
|
||||
}
|
||||
|
||||
if (ele.checkedFieldsMapArrNum?.[id]?.length === 1 && ele.displayType === '22') {
|
||||
errorTips = '数值参数配置必须配置最大值和最小值'
|
||||
errorTips = t('v_query.numerical_parameter_configuration')
|
||||
return true
|
||||
}
|
||||
|
||||
@ -1209,7 +1233,7 @@ const validate = () => {
|
||||
}
|
||||
|
||||
if (ele.checkedFieldsMapArr?.[id]?.length === 1 && ele.displayType === '7') {
|
||||
errorTips = '时间参数配置必须配置开始时间和结束时间'
|
||||
errorTips = t('v_query.and_end_time')
|
||||
return true
|
||||
}
|
||||
|
||||
@ -1228,12 +1252,12 @@ const validate = () => {
|
||||
return false
|
||||
}
|
||||
if (displayTypeField.type?.length !== field.type?.length) {
|
||||
errorTips = '时间格式不一致'
|
||||
errorTips = t('v_query.format_is_inconsistent')
|
||||
return true
|
||||
}
|
||||
for (let index = 0; index < displayTypeField.type.length; index++) {
|
||||
if (displayTypeField.type[index] !== field.type[index]) {
|
||||
errorTips = '时间格式不一致'
|
||||
errorTips = t('v_query.format_is_inconsistent')
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -1250,13 +1274,13 @@ const validate = () => {
|
||||
setParams(ele)
|
||||
const result = validateConditionType(ele)
|
||||
if (result) {
|
||||
ElMessage.error('查询条件为必填项,默认值不能为空')
|
||||
ElMessage.error(t('v_query.cannot_be_empty_de'))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
if (!ele.defaultValueCheck) {
|
||||
ElMessage.error('查询条件为必填项,默认值不能为空')
|
||||
ElMessage.error(t('v_query.cannot_be_empty_de'))
|
||||
return true
|
||||
}
|
||||
|
||||
@ -1265,7 +1289,7 @@ const validate = () => {
|
||||
(ele.defaultNumValueEnd !== 0 && !ele.defaultNumValueEnd) ||
|
||||
(ele.defaultNumValueStart !== 0 && !ele.defaultNumValueStart)
|
||||
) {
|
||||
ElMessage.error('查询条件为必填项,默认值不能为空')
|
||||
ElMessage.error(t('v_query.cannot_be_empty_de'))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -1275,7 +1299,7 @@ const validate = () => {
|
||||
(Array.isArray(ele.defaultValue) && !ele.defaultValue.length) ||
|
||||
(ele.defaultValue !== 0 && !ele.defaultValue)
|
||||
) {
|
||||
ElMessage.error('查询条件为必填项,默认值不能为空')
|
||||
ElMessage.error(t('v_query.cannot_be_empty_de'))
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -1295,7 +1319,7 @@ const validate = () => {
|
||||
if (!ele.defaultValueCheck) return false
|
||||
if (ele.timeType === 'fixed') {
|
||||
if (!ele.defaultValue) {
|
||||
ElMessage.error('默认时间不能为空!')
|
||||
ElMessage.error(t('v_query.cannot_be_empty_time'))
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -1306,7 +1330,7 @@ const validate = () => {
|
||||
if (ele.timeType === 'fixed') {
|
||||
const [s, e] = ele.defaultValue || []
|
||||
if (!s || !e) {
|
||||
ElMessage.error('默认时间不能为空!')
|
||||
ElMessage.error(t('v_query.cannot_be_empty_time'))
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -1353,7 +1377,7 @@ const validate = () => {
|
||||
;[startTime, endTime] = getCustomRange(relativeToCurrentRange)
|
||||
}
|
||||
if (+startTime > +endTime) {
|
||||
ElMessage.error('结束时间必须大于开始时间!')
|
||||
ElMessage.error(t('v_query.the_start_time'))
|
||||
return true
|
||||
}
|
||||
if (!ele.setTimeRange) return false
|
||||
@ -1368,7 +1392,7 @@ const validate = () => {
|
||||
: +endTime
|
||||
)
|
||||
) {
|
||||
ElMessage.error('默认值超出日期筛选范围内,请重新设置!')
|
||||
ElMessage.error(t('v_query.range_please_reset'))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -1383,12 +1407,14 @@ const validate = () => {
|
||||
ele.optionValueSource === 2 &&
|
||||
!ele.valueSource?.filter(ele => !!ele).length
|
||||
) {
|
||||
ElMessage.error('手工输入-选项值不能为空')
|
||||
ElMessage.error(t('v_query.cannot_be_empty_input'))
|
||||
return true
|
||||
}
|
||||
|
||||
if (!['9', '22'].includes(ele.displayType) && ele.optionValueSource === 1 && !ele.field.id) {
|
||||
ElMessage.error(!ele.dataset?.id ? '请选择数据集及选项值字段' : '请选择数据集的选项值字段')
|
||||
ElMessage.error(
|
||||
!ele.dataset?.id ? t('v_query.option_value_field') : t('v_query.the_data_set')
|
||||
)
|
||||
return true
|
||||
}
|
||||
})
|
||||
@ -1455,7 +1481,7 @@ const confirmValueSource = () => {
|
||||
return false
|
||||
})
|
||||
) {
|
||||
ElMessage.error('手工输入-选项值不能为空')
|
||||
ElMessage.error(t('v_query.cannot_be_empty_input'))
|
||||
return
|
||||
}
|
||||
|
||||
@ -1728,10 +1754,9 @@ const startTreeDesign = () => {
|
||||
const [comId] = curComponent.value.checkedFields
|
||||
const componentObj = fields.value.find(ele => ele.componentId === comId)
|
||||
treeDialog.value.init(
|
||||
(curComponent.value.optionValueSource === 0
|
||||
? componentObj?.fields?.dimensionList
|
||||
: curComponent.value.dataset?.fields
|
||||
).filter(ele => ele.deType === +curComponent.value.field.deType),
|
||||
componentObj?.fields?.dimensionList.filter(
|
||||
ele => ele.deType === +curComponent.value.field.deType
|
||||
),
|
||||
curComponent.value.treeFieldList
|
||||
)
|
||||
}
|
||||
@ -1776,11 +1801,11 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'year':
|
||||
list = [
|
||||
{
|
||||
label: '今年',
|
||||
label: t('dynamic_year.current'),
|
||||
value: 'thisYear'
|
||||
},
|
||||
{
|
||||
label: '去年',
|
||||
label: t('dynamic_year.last'),
|
||||
value: 'lastYear'
|
||||
}
|
||||
]
|
||||
@ -1788,11 +1813,11 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'month':
|
||||
list = [
|
||||
{
|
||||
label: '本月',
|
||||
label: t('cron.this_month'),
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: '上月',
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
}
|
||||
]
|
||||
@ -1800,19 +1825,19 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'date':
|
||||
list = [
|
||||
{
|
||||
label: '今天',
|
||||
label: t('dynamic_time.today'),
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
label: t('dynamic_time.yesterday'),
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '月初',
|
||||
label: t('dynamic_time.firstOfMonth'),
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初',
|
||||
label: t('dynamic_time.firstOfYear'),
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
]
|
||||
@ -1820,19 +1845,19 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'datetime':
|
||||
list = [
|
||||
{
|
||||
label: '今天',
|
||||
label: t('dynamic_time.today'),
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
label: t('dynamic_time.yesterday'),
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '月初',
|
||||
label: t('dynamic_time.firstOfMonth'),
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初',
|
||||
label: t('dynamic_time.firstOfYear'),
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
]
|
||||
@ -1845,7 +1870,7 @@ const relativeToCurrentList = computed(() => {
|
||||
return [
|
||||
...list,
|
||||
{
|
||||
label: '自定义',
|
||||
label: t('dynamic_time.custom'),
|
||||
value: 'custom'
|
||||
}
|
||||
]
|
||||
@ -1858,11 +1883,11 @@ const relativeToCurrentListRange = computed(() => {
|
||||
case 'yearrange':
|
||||
list = [
|
||||
{
|
||||
label: '今年',
|
||||
label: t('dynamic_year.current'),
|
||||
value: 'thisYear'
|
||||
},
|
||||
{
|
||||
label: '去年',
|
||||
label: t('dynamic_year.last'),
|
||||
value: 'lastYear'
|
||||
}
|
||||
]
|
||||
@ -1870,23 +1895,23 @@ const relativeToCurrentListRange = computed(() => {
|
||||
case 'monthrange':
|
||||
list = [
|
||||
{
|
||||
label: '本月',
|
||||
label: t('cron.this_month'),
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: '上月',
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
label: '最近 3 个 月',
|
||||
label: t('v_query.last_3_months'),
|
||||
value: 'LastThreeMonths'
|
||||
},
|
||||
{
|
||||
label: '最近 6 个 月',
|
||||
label: t('v_query.last_6_months'),
|
||||
value: 'LastSixMonths'
|
||||
},
|
||||
{
|
||||
label: '最近 12 个 月',
|
||||
label: t('v_query.last_12_months'),
|
||||
value: 'LastTwelveMonths'
|
||||
}
|
||||
]
|
||||
@ -1895,23 +1920,23 @@ const relativeToCurrentListRange = computed(() => {
|
||||
case 'datetimerange':
|
||||
list = [
|
||||
{
|
||||
label: '今天',
|
||||
label: t('dynamic_time.today'),
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
label: t('dynamic_time.yesterday'),
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '最近 3 天',
|
||||
label: t('v_query.last_3_days'),
|
||||
value: 'LastThreeDays'
|
||||
},
|
||||
{
|
||||
label: '月初至今',
|
||||
label: t('v_query.month_to_date'),
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初至今',
|
||||
label: t('v_query.year_to_date'),
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
]
|
||||
@ -1924,7 +1949,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
return [
|
||||
...list,
|
||||
{
|
||||
label: '自定义',
|
||||
label: t('dynamic_time.custom'),
|
||||
value: 'custom'
|
||||
}
|
||||
]
|
||||
@ -2018,7 +2043,7 @@ const dfs = arr => {
|
||||
|
||||
const renameInputBlur = () => {
|
||||
if (activeConditionForRename.name.trim() === '') {
|
||||
ElMessage.error('字段名称不能为空')
|
||||
ElMessage.error(t('v_query.cannot_be_empty_name'))
|
||||
renameInput.value[0]?.focus()
|
||||
return
|
||||
}
|
||||
@ -2058,7 +2083,7 @@ defineExpose({
|
||||
class="query-condition-configuration"
|
||||
v-model="dialogVisible"
|
||||
width="1200px"
|
||||
title="查询条件设置"
|
||||
:title="t('v_query.query_condition_setting')"
|
||||
@click.stop
|
||||
:before-close="handleBeforeClose"
|
||||
@mousedown.stop
|
||||
@ -2067,7 +2092,7 @@ defineExpose({
|
||||
<div class="container" @click="handleDialogClick">
|
||||
<div class="query-condition-list">
|
||||
<div class="title">
|
||||
查询条件
|
||||
{{ t('v_query.query_condition') }}
|
||||
<el-icon @click="addQueryCriteriaAndSelect">
|
||||
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
@ -2127,17 +2152,17 @@ defineExpose({
|
||||
<div v-if="!!curComponent" class="chart-field" :class="curComponent.auto && 'hidden'">
|
||||
<div class="mask" v-if="curComponent.auto"></div>
|
||||
<div class="title flex-align-center">
|
||||
选择关联图表及字段
|
||||
{{ t('v_query.chart_and_field') }}
|
||||
<el-radio-group class="ml-4 larger-radio" v-model="curComponent.auto">
|
||||
<el-radio :disabled="!curComponent.auto" :label="true">
|
||||
<div class="flex-align-center">
|
||||
自动
|
||||
{{ t('chart.margin_model_auto') }}
|
||||
<el-tooltip effect="dark" placement="top">
|
||||
<template #content>
|
||||
<div>
|
||||
注意:自动模式支持同数据集自动关联字段,可切换到
|
||||
{{ t('v_query.be_switched_to') }}
|
||||
<br />
|
||||
自定义模式。切换到自定义模式后无法再切换为自动!
|
||||
{{ t('v_query.to_automatic_again') }}
|
||||
</div>
|
||||
</template>
|
||||
<el-icon style="margin-left: 4px; color: #646a73">
|
||||
@ -2225,9 +2250,13 @@ defineExpose({
|
||||
</template>
|
||||
<template #header>
|
||||
<el-tabs stretch class="params-select--header" v-model="field.activelist">
|
||||
<el-tab-pane disabled label="维度" name="dimensionList"></el-tab-pane>
|
||||
<el-tab-pane disabled label="指标" name="quotaList"></el-tab-pane>
|
||||
<el-tab-pane label="参数" name="parameterList"></el-tab-pane>
|
||||
<el-tab-pane
|
||||
disabled
|
||||
:label="t('chart.dimension')"
|
||||
name="dimensionList"
|
||||
></el-tab-pane>
|
||||
<el-tab-pane disabled :label="t('chart.quota')" name="quotaList"></el-tab-pane>
|
||||
<el-tab-pane :label="t('dataset.param')" name="parameterList"></el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
<el-option
|
||||
@ -2260,9 +2289,9 @@ defineExpose({
|
||||
>
|
||||
{{
|
||||
curComponent.checkedFieldsMapStart[field.componentId] === ele.id
|
||||
? '开始时间'
|
||||
? t('dataset.start_time')
|
||||
: curComponent.checkedFieldsMapEnd[field.componentId] === ele.id
|
||||
? '结束时间'
|
||||
? t('dataset.end_time')
|
||||
: ''
|
||||
}}
|
||||
<el-icon>
|
||||
@ -2322,9 +2351,13 @@ defineExpose({
|
||||
</template>
|
||||
<template #header>
|
||||
<el-tabs stretch class="params-select--header" v-model="field.activelist">
|
||||
<el-tab-pane disabled label="维度" name="dimensionList"></el-tab-pane>
|
||||
<el-tab-pane disabled label="指标" name="quotaList"></el-tab-pane>
|
||||
<el-tab-pane label="参数" name="parameterList"></el-tab-pane>
|
||||
<el-tab-pane
|
||||
disabled
|
||||
:label="t('chart.dimension')"
|
||||
name="dimensionList"
|
||||
></el-tab-pane>
|
||||
<el-tab-pane disabled :label="t('chart.quota')" name="quotaList"></el-tab-pane>
|
||||
<el-tab-pane :label="t('dataset.param')" name="parameterList"></el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
<el-option
|
||||
@ -2357,9 +2390,9 @@ defineExpose({
|
||||
>
|
||||
{{
|
||||
curComponent.checkedFieldsMapStartNum[field.componentId] === ele.id
|
||||
? '最小值'
|
||||
? t('chart.min')
|
||||
: curComponent.checkedFieldsMapEndNum[field.componentId] === ele.id
|
||||
? '最大值'
|
||||
? t('chart.max')
|
||||
: ''
|
||||
}}
|
||||
<el-icon>
|
||||
@ -2408,15 +2441,15 @@ defineExpose({
|
||||
</template>
|
||||
<template #header>
|
||||
<el-tabs stretch class="params-select--header" v-model="field.activelist">
|
||||
<el-tab-pane label="维度" name="dimensionList"></el-tab-pane>
|
||||
<el-tab-pane :label="t('chart.dimension')" name="dimensionList"></el-tab-pane>
|
||||
<el-tab-pane
|
||||
:disabled="curComponent.displayType === '9'"
|
||||
label="指标"
|
||||
:label="t('chart.quota')"
|
||||
name="quotaList"
|
||||
></el-tab-pane>
|
||||
<el-tab-pane
|
||||
v-if="field.hasParameter"
|
||||
label="参数"
|
||||
:label="t('dataset.param')"
|
||||
:disabled="curComponent.displayType === '9'"
|
||||
name="parameterList"
|
||||
></el-tab-pane>
|
||||
@ -2435,7 +2468,7 @@ defineExpose({
|
||||
>
|
||||
<div
|
||||
class="flex-align-center icon"
|
||||
:title="ele.desensitized ? '脱敏字段,不能被设置为查询条件' : ''"
|
||||
:title="ele.desensitized ? t('v_query.as_query_conditions') : ''"
|
||||
>
|
||||
<el-icon>
|
||||
<Icon :className="`field-icon-${fieldType[ele.deType]}`"
|
||||
@ -2463,7 +2496,7 @@ defineExpose({
|
||||
"
|
||||
class="range-time_setting"
|
||||
>
|
||||
{{ isNumParameter ? '数值' : '时间' }}
|
||||
{{ isNumParameter ? t('chart.value_formatter_value') : t('dataset.time') }}
|
||||
<el-icon>
|
||||
<Icon>
|
||||
<icon_edit_outlined class="svg-icon"></icon_edit_outlined>
|
||||
@ -2478,14 +2511,18 @@ defineExpose({
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!!curComponent" class="condition-configuration">
|
||||
<div
|
||||
v-if="!!curComponent"
|
||||
class="condition-configuration"
|
||||
:class="curComponent.auto && 'condition-configuration_hide'"
|
||||
>
|
||||
<div class="mask condition" v-if="curComponent.auto"></div>
|
||||
<div class="title flex-align-center">
|
||||
查询条件配置
|
||||
{{ t('v_query.query_condition_configuration') }}
|
||||
<el-checkbox
|
||||
:disabled="curComponent.auto"
|
||||
v-model="curComponent.required"
|
||||
label="必填项"
|
||||
:label="t('v_query.required_items')"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
@ -2493,7 +2530,7 @@ defineExpose({
|
||||
class="configuration-list"
|
||||
>
|
||||
<div class="list-item">
|
||||
<div class="label">展示类型</div>
|
||||
<div class="label">{{ t('v_query.display_type') }}</div>
|
||||
<div class="value">
|
||||
<el-select
|
||||
@focus="handleDialogClick"
|
||||
@ -2502,12 +2539,12 @@ defineExpose({
|
||||
>
|
||||
<el-option
|
||||
:disabled="!['0', '8', '9'].includes(curComponent.displayType)"
|
||||
label="文本下拉"
|
||||
:label="t('v_query.text_drop_down')"
|
||||
value="0"
|
||||
/>
|
||||
<el-option
|
||||
:disabled="!['0', '8', '9'].includes(curComponent.displayType)"
|
||||
label="文本搜索"
|
||||
:label="t('v_query.text_search')"
|
||||
value="8"
|
||||
/>
|
||||
<el-option
|
||||
@ -2515,26 +2552,26 @@ defineExpose({
|
||||
!['0', '8', '9'].includes(curComponent.displayType) ||
|
||||
!!curComponent.parameters.length
|
||||
"
|
||||
label="下拉树"
|
||||
:label="t('v_query.drop_down_tree')"
|
||||
value="9"
|
||||
/>
|
||||
|
||||
<template v-if="['2', '22'].includes(curComponent.displayType)">
|
||||
<el-option
|
||||
:disabled="!['2', '22'].includes(curComponent.displayType) || notNumRange"
|
||||
label="数字下拉"
|
||||
:label="t('v_query.number_drop_down')"
|
||||
value="2"
|
||||
/>
|
||||
<el-option
|
||||
:disabled="!['2', '22'].includes(curComponent.displayType) || canNotNumRange"
|
||||
label="数值区间"
|
||||
:label="t('v_query.number_range')"
|
||||
value="22"
|
||||
/>
|
||||
</template>
|
||||
<el-option
|
||||
v-else
|
||||
:disabled="curComponent.displayType !== '5'"
|
||||
label="数字下拉"
|
||||
:label="t('v_query.number_drop_down')"
|
||||
value="5"
|
||||
/>
|
||||
<el-option
|
||||
@ -2542,7 +2579,7 @@ defineExpose({
|
||||
!['1', '7'].includes(curComponent.displayType) ||
|
||||
(isTimeParameter && notTimeRange)
|
||||
"
|
||||
label="时间"
|
||||
:label="t('dataset.time')"
|
||||
value="1"
|
||||
/>
|
||||
<el-option
|
||||
@ -2550,24 +2587,24 @@ defineExpose({
|
||||
!['1', '7'].includes(curComponent.displayType) ||
|
||||
(isTimeParameter && !notTimeRange)
|
||||
"
|
||||
label="时间范围"
|
||||
:label="t('common.component.dateRange')"
|
||||
value="7"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-item" v-if="curComponent.displayType === '9'">
|
||||
<div class="label">选项值数量</div>
|
||||
<div class="label">{{ t('v_query.of_option_values') }}</div>
|
||||
<div class="value">
|
||||
<el-radio-group class="larger-radio" v-model="curComponent.resultMode">
|
||||
<el-radio :label="0">默认</el-radio>
|
||||
<el-radio :label="1">全部</el-radio>
|
||||
<el-radio :label="0">{{ t('login.default_login') }}</el-radio>
|
||||
<el-radio :label="1">{{ t('chart.result_mode_all') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-item" v-if="curComponent.displayType === '9'">
|
||||
<div class="label" style="width: 135px; height: 26px; line-height: 26px">
|
||||
下拉树结构设计
|
||||
{{ t('v_query.tree_structure_design') }}
|
||||
<el-button
|
||||
v-if="curComponent.treeFieldList && !!curComponent.treeFieldList.length"
|
||||
text
|
||||
@ -2585,7 +2622,9 @@ defineExpose({
|
||||
:key="ele.id"
|
||||
class="tree-field"
|
||||
>
|
||||
<span class="level-index">层级{{ indexCascade[index + 1] }}</span>
|
||||
<span class="level-index"
|
||||
>{{ t('visualization.level') }}{{ indexCascade[index + 1] }}</span
|
||||
>
|
||||
<span class="field-type"
|
||||
><el-icon>
|
||||
<Icon :className="`field-icon-${fieldType[ele.deType]}`"
|
||||
@ -2603,31 +2642,31 @@ defineExpose({
|
||||
<template #icon>
|
||||
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
||||
</template>
|
||||
点击进行树结构设计
|
||||
{{ t('v_query.the_tree_structure') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<TreeFieldDialog ref="treeDialog" @save-tree="saveTree"></TreeFieldDialog>
|
||||
</div>
|
||||
<div class="list-item" v-if="['1', '7'].includes(curComponent.displayType)">
|
||||
<div class="label">时间粒度</div>
|
||||
<div class="label">{{ t('v_query.time_granularity') }}</div>
|
||||
<div class="value">
|
||||
<template v-if="curComponent.displayType === '7' && !isTimeParameter">
|
||||
<el-select
|
||||
@change="timeGranularityMultipleChange"
|
||||
placeholder="请选择时间粒度"
|
||||
:placeholder="t('v_query.the_time_granularity')"
|
||||
@focus="handleDialogClick"
|
||||
v-model="curComponent.timeGranularityMultiple"
|
||||
>
|
||||
<el-option label="年" value="yearrange" />
|
||||
<el-option label="年月" value="monthrange" />
|
||||
<el-option label="年月日" value="daterange" />
|
||||
<el-option label="年月日时分秒" value="datetimerange" />
|
||||
<el-option :label="t('chart.y')" value="yearrange" />
|
||||
<el-option :label="t('chart.y_M')" value="monthrange" />
|
||||
<el-option :label="t('chart.y_M_d')" value="daterange" />
|
||||
<el-option :label="t('chart.y_M_d_H_m_s')" value="datetimerange" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-select
|
||||
@change="timeGranularityChange"
|
||||
placeholder="请选择时间粒度"
|
||||
:placeholder="t('v_query.the_time_granularity')"
|
||||
v-model="curComponent.timeGranularity"
|
||||
>
|
||||
<el-option
|
||||
@ -2644,7 +2683,7 @@ defineExpose({
|
||||
class="list-item top-item"
|
||||
v-if="!['1', '7', '8', '9', '22'].includes(curComponent.displayType)"
|
||||
>
|
||||
<div class="label">选项值来源</div>
|
||||
<div class="label">{{ t('v_query.option_value_source') }}</div>
|
||||
<div class="value">
|
||||
<div class="value">
|
||||
<el-radio-group
|
||||
@ -2656,7 +2695,7 @@ defineExpose({
|
||||
t('chart.margin_model_auto')
|
||||
}}</el-radio>
|
||||
<el-radio :label="1">{{ t('chart.select_dataset') }}</el-radio>
|
||||
<el-radio :label="2">手动输入</el-radio>
|
||||
<el-radio :label="2">{{ t('v_query.manual_input') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<template v-if="curComponent.optionValueSource === 1">
|
||||
@ -2665,7 +2704,7 @@ defineExpose({
|
||||
:teleported="false"
|
||||
v-model="curComponent.dataset.id"
|
||||
:data="datasetTree"
|
||||
placeholder="请选择数据集"
|
||||
:placeholder="t('copilot.pls_choose_dataset')"
|
||||
@change="handleDatasetChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:props="dsSelectProps"
|
||||
@ -2693,10 +2732,10 @@ defineExpose({
|
||||
</el-tree-select>
|
||||
</div>
|
||||
<div class="value">
|
||||
<span class="label">查询字段</span>
|
||||
<span class="label">{{ t('v_query.query_field') }}</span>
|
||||
<el-select
|
||||
@change="handleFieldChange"
|
||||
placeholder="查询字段"
|
||||
:placeholder="t('v_query.query_field')"
|
||||
class="search-field"
|
||||
v-model="curComponent.field.id"
|
||||
>
|
||||
@ -2735,7 +2774,7 @@ defineExpose({
|
||||
>
|
||||
<div
|
||||
class="flex-align-center icon"
|
||||
:title="ele.desensitized ? '脱敏字段,不能被设置为查询条件' : ''"
|
||||
:title="ele.desensitized ? t('v_query.as_query_conditions') : ''"
|
||||
>
|
||||
<el-icon>
|
||||
<Icon :className="`field-icon-${fieldType[ele.deType]}`"
|
||||
@ -2754,9 +2793,9 @@ defineExpose({
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="value">
|
||||
<span class="label">显示字段</span>
|
||||
<span class="label">{{ t('v_query.display_field') }}</span>
|
||||
<el-select
|
||||
placeholder="显示字段"
|
||||
:placeholder="t('v_query.display_field')"
|
||||
class="search-field"
|
||||
v-model="curComponent.displayId"
|
||||
>
|
||||
@ -2795,7 +2834,7 @@ defineExpose({
|
||||
>
|
||||
<div
|
||||
class="flex-align-center icon"
|
||||
:title="ele.desensitized ? '脱敏字段,不能被设置为查询条件' : ''"
|
||||
:title="ele.desensitized ? t('v_query.as_query_conditions') : ''"
|
||||
>
|
||||
<el-icon>
|
||||
<Icon :className="`field-icon-${fieldType[ele.deType]}`"
|
||||
@ -2814,10 +2853,10 @@ defineExpose({
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="value">
|
||||
<span class="label">排序字段</span>
|
||||
<span class="label">{{ t('chart.total_sort_field') }}</span>
|
||||
<el-select
|
||||
clearable
|
||||
placeholder="请选择排序字段"
|
||||
:placeholder="t('v_query.the_sorting_field')"
|
||||
v-model="curComponent.sortId"
|
||||
class="sort-field"
|
||||
@change="handleFieldChange"
|
||||
@ -2850,7 +2889,7 @@ defineExpose({
|
||||
>
|
||||
<div
|
||||
class="flex-align-center icon"
|
||||
:title="ele.desensitized ? '脱敏字段,不能被设置为查询条件' : ''"
|
||||
:title="ele.desensitized ? t('v_query.as_query_conditions') : ''"
|
||||
>
|
||||
<el-icon>
|
||||
<Icon
|
||||
@ -2872,8 +2911,8 @@ defineExpose({
|
||||
v-model="curComponent.sort"
|
||||
@change="handleFieldChange"
|
||||
>
|
||||
<el-option label="升序" value="asc" />
|
||||
<el-option label="降序" value="desc" />
|
||||
<el-option :label="t('chart.asc')" value="asc" />
|
||||
<el-option :label="t('chart.desc')" value="desc" />
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
@ -2898,7 +2937,7 @@ defineExpose({
|
||||
<div class="manual-input-container">
|
||||
<div class="title">{{ t('auth.manual_input') }}</div>
|
||||
<div class="select-value">
|
||||
<span> 选项值 </span>
|
||||
<span> {{ t('data_fill.form.option_value') }} </span>
|
||||
<div :key="index" v-for="(_, index) in valueSource" class="select-item">
|
||||
<el-input
|
||||
maxlength="20"
|
||||
@ -2933,7 +2972,7 @@ defineExpose({
|
||||
><icon_add_outlined class="svg-icon"
|
||||
/></Icon>
|
||||
</template>
|
||||
添加选项值
|
||||
{{ t('data_fill.form.add_option') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="manual-footer flex-align-center">
|
||||
@ -2945,36 +2984,39 @@ defineExpose({
|
||||
</div>
|
||||
</el-popover>
|
||||
<div v-if="!!curComponent.valueSource.length" class="config-flag flex-align-center">
|
||||
已配置
|
||||
{{ t('v_query.configured') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="label" style="margin-top: 10.5px">选项值数量</div>
|
||||
<div class="label" style="margin-top: 10.5px">{{ t('v_query.of_option_values') }}</div>
|
||||
<div class="value" style="margin-top: 10.5px">
|
||||
<el-radio-group class="larger-radio" v-model="curComponent.resultMode">
|
||||
<el-radio :label="0">默认</el-radio>
|
||||
<el-radio :label="1">全部</el-radio>
|
||||
<el-radio :label="0">{{ t('chart.default') }}</el-radio>
|
||||
<el-radio :label="1">{{ t('data_set.all') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-item top-item" v-if="curComponent.displayType === '8'">
|
||||
<div class="label">条件类型</div>
|
||||
<div class="label">{{ t('v_query.condition_type') }}</div>
|
||||
<div class="value">
|
||||
<div class="value">
|
||||
<el-radio-group class="larger-radio" v-model="curComponent.conditionType">
|
||||
<el-radio :label="0">单条件</el-radio>
|
||||
<el-radio :label="1" :disabled="!!curComponent.parameters.length"
|
||||
>与条件</el-radio
|
||||
>
|
||||
<el-radio :label="2" :disabled="!!curComponent.parameters.length"
|
||||
>或条件</el-radio
|
||||
>
|
||||
<el-radio :label="0">{{ t('v_query.single_condition') }}</el-radio>
|
||||
<el-radio :label="1" :disabled="!!curComponent.parameters.length">{{
|
||||
t('v_query.with_condition')
|
||||
}}</el-radio>
|
||||
<el-radio :label="2" :disabled="!!curComponent.parameters.length">{{
|
||||
t('v_query.or_condition')
|
||||
}}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-bottom: 10.5px" v-if="curComponent.displayType === '8'">
|
||||
<el-checkbox v-model="curComponent.hideConditionSwitching" label="隐藏条件切换" />
|
||||
<el-checkbox
|
||||
v-model="curComponent.hideConditionSwitching"
|
||||
:label="t('v_query.hide_condition_switch')"
|
||||
/>
|
||||
</div>
|
||||
<condition-default-configuration
|
||||
ref="defaultConfigurationRef"
|
||||
@ -2983,19 +3025,21 @@ defineExpose({
|
||||
></condition-default-configuration>
|
||||
</div>
|
||||
<div v-if="showTypeError && showConfiguration" class="empty">
|
||||
<empty-background description="所选字段类型不一致,无法进行查询配置" img-type="error" />
|
||||
<empty-background :description="t('v_query.cannot_be_performed')" img-type="error" />
|
||||
</div>
|
||||
<div v-else-if="showDatasetError && showConfiguration" class="empty">
|
||||
<empty-background description="图表所使用的数据集不同, 无法展示配置项" img-type="error" />
|
||||
<empty-background :description="t('v_query.cannot_be_displayed')" img-type="error" />
|
||||
</div>
|
||||
<div v-else-if="!showConfiguration" class="empty">
|
||||
<empty-background description="请先勾选需要联动的图表及字段" img-type="noneWhite" />
|
||||
<empty-background :description="t('v_query.be_linked_first')" img-type="noneWhite" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button class="query-cascade" @click="openCascadeDialog">查询组件级联配置</el-button>
|
||||
<el-button class="query-cascade" @click="openCascadeDialog">{{
|
||||
t('v_query.component_cascade_configuration')
|
||||
}}</el-button>
|
||||
<el-button @click="cancelClick">{{ t('chart.cancel') }} </el-button>
|
||||
<el-button @click="confirmClick" type="primary">{{ t('chart.confirm') }} </el-button>
|
||||
</div>
|
||||
@ -3003,32 +3047,32 @@ defineExpose({
|
||||
</el-dialog>
|
||||
<el-dialog :title="timeName" v-model="timeDialogShow" width="420px">
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="时间类型" class="form-item" prop="name">
|
||||
<el-form-item :label="t('v_query.time_type')" class="form-item" prop="name">
|
||||
<el-radio-group v-model="timeParameterType">
|
||||
<el-radio :label="0">时间</el-radio>
|
||||
<el-radio :label="1">开始时间</el-radio>
|
||||
<el-radio :label="2">结束时间</el-radio>
|
||||
<el-radio :label="0">{{ t('data_set.time') }}</el-radio>
|
||||
<el-radio :label="1">{{ t('datasource.start_time') }}</el-radio>
|
||||
<el-radio :label="2">{{ t('datasource.end_time') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button secondary @click="timeDialogShow = false">取消</el-button>
|
||||
<el-button type="primary" @click="timeTypeChange">确认</el-button>
|
||||
<el-button secondary @click="timeDialogShow = false">{{ t('chart.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="timeTypeChange">{{ t('chart.confirm') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog :title="numName" v-model="numDialogShow" width="420px">
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="类型" class="form-item" prop="name">
|
||||
<el-form-item :label="t('chart.map_line_type')" class="form-item" prop="name">
|
||||
<el-radio-group v-model="numParameterType">
|
||||
<el-radio :label="0">数值</el-radio>
|
||||
<el-radio :label="1">最小值</el-radio>
|
||||
<el-radio :label="2">最大值</el-radio>
|
||||
<el-radio :label="0">{{ t('chart.value_formatter_value') }}</el-radio>
|
||||
<el-radio :label="1">{{ t('chart.min') }}</el-radio>
|
||||
<el-radio :label="2">{{ t('chart.max') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button secondary @click="numDialogShow = false">取消</el-button>
|
||||
<el-button type="primary" @click="numTypeChange">确认</el-button>
|
||||
<el-button secondary @click="numDialogShow = false">{{ t('dataset.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="numTypeChange">{{ t('dataset.confirm') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<CascadeDialog @saveCascade="saveCascade" ref="cascadeDialog"></CascadeDialog>
|
||||
@ -3274,6 +3318,10 @@ defineExpose({
|
||||
width: 467px;
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
|
||||
&.condition-configuration_hide {
|
||||
overflow: hidden;
|
||||
}
|
||||
.mask {
|
||||
left: -1px;
|
||||
width: calc(100% + 2px);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { toRefs, computed, PropType } from 'vue'
|
||||
import { type TimeRange } from './time-format'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import DynamicTime from './DynamicTimeFiltering.vue'
|
||||
import DynamicTimeRange from './DynamicTimeRangeFiltering.vue'
|
||||
const props = defineProps({
|
||||
@ -27,21 +28,23 @@ const props = defineProps({
|
||||
default: 'yearrange'
|
||||
}
|
||||
})
|
||||
|
||||
const { t } = useI18n()
|
||||
const intervalTypeList = [
|
||||
{
|
||||
label: '无',
|
||||
label: t('chart.line_symbol_none'),
|
||||
value: 'none'
|
||||
},
|
||||
{
|
||||
label: '开始于',
|
||||
label: t('v_query.start_at'),
|
||||
value: 'start'
|
||||
},
|
||||
{
|
||||
label: '结束于',
|
||||
label: t('v_query.end_at'),
|
||||
value: 'end'
|
||||
},
|
||||
{
|
||||
label: '时间区间',
|
||||
label: t('v_query.time_interval'),
|
||||
value: 'timeInterval'
|
||||
}
|
||||
]
|
||||
@ -60,11 +63,11 @@ const filterTypeCom = computed(() => {
|
||||
|
||||
const aroundList = [
|
||||
{
|
||||
label: '前',
|
||||
label: t('dynamic_time.before'),
|
||||
value: 'f'
|
||||
},
|
||||
{
|
||||
label: '后',
|
||||
label: t('dynamic_time.after'),
|
||||
value: 'b'
|
||||
}
|
||||
]
|
||||
@ -76,15 +79,15 @@ const relativeToCurrentTypeList = computed(() => {
|
||||
) + 1
|
||||
return [
|
||||
{
|
||||
label: '年',
|
||||
label: t('dynamic_time.year'),
|
||||
value: 'year'
|
||||
},
|
||||
{
|
||||
label: '月',
|
||||
label: t('dynamic_time.month'),
|
||||
value: 'month'
|
||||
},
|
||||
{
|
||||
label: '日',
|
||||
label: t('dynamic_time.date'),
|
||||
value: 'day'
|
||||
}
|
||||
].slice(0, index)
|
||||
@ -100,11 +103,11 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'yearrange':
|
||||
list = [
|
||||
{
|
||||
label: '今年',
|
||||
label: t('dynamic_year.current'),
|
||||
value: 'thisYear'
|
||||
},
|
||||
{
|
||||
label: '去年',
|
||||
label: t('dynamic_year.last'),
|
||||
value: 'lastYear'
|
||||
}
|
||||
]
|
||||
@ -112,11 +115,11 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'monthrange':
|
||||
list = [
|
||||
{
|
||||
label: '本月',
|
||||
label: t('cron.this_month'),
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: '上月',
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
}
|
||||
]
|
||||
@ -124,19 +127,19 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'daterange':
|
||||
list = [
|
||||
{
|
||||
label: '今天',
|
||||
label: t('dynamic_time.today'),
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
label: t('dynamic_time.yesterday'),
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '月初',
|
||||
label: t('dynamic_time.firstOfMonth'),
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初',
|
||||
label: t('dynamic_time.firstOfYear'),
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
]
|
||||
@ -144,19 +147,19 @@ const relativeToCurrentList = computed(() => {
|
||||
case 'datetimerange':
|
||||
list = [
|
||||
{
|
||||
label: '今天',
|
||||
label: t('dynamic_time.today'),
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
label: t('dynamic_time.yesterday'),
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '月初',
|
||||
label: t('dynamic_time.firstOfMonth'),
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初',
|
||||
label: t('dynamic_time.firstOfYear'),
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
]
|
||||
@ -169,7 +172,7 @@ const relativeToCurrentList = computed(() => {
|
||||
return [
|
||||
...list,
|
||||
{
|
||||
label: '自定义',
|
||||
label: t('dynamic_time.custom'),
|
||||
value: 'custom'
|
||||
}
|
||||
]
|
||||
@ -182,11 +185,11 @@ const relativeToCurrentListRange = computed(() => {
|
||||
case 'yearrange':
|
||||
list = [
|
||||
{
|
||||
label: '今年',
|
||||
label: t('dynamic_year.current'),
|
||||
value: 'thisYear'
|
||||
},
|
||||
{
|
||||
label: '去年',
|
||||
label: t('dynamic_year.last'),
|
||||
value: 'lastYear'
|
||||
}
|
||||
]
|
||||
@ -194,23 +197,23 @@ const relativeToCurrentListRange = computed(() => {
|
||||
case 'monthrange':
|
||||
list = [
|
||||
{
|
||||
label: '本月',
|
||||
label: t('cron.this_month'),
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: '上月',
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
label: '最近 3 个 月',
|
||||
label: t('v_query.last_3_months'),
|
||||
value: 'LastThreeMonths'
|
||||
},
|
||||
{
|
||||
label: '最近 6 个 月',
|
||||
label: t('v_query.last_6_months'),
|
||||
value: 'LastSixMonths'
|
||||
},
|
||||
{
|
||||
label: '最近 12 个 月',
|
||||
label: t('v_query.last_12_months'),
|
||||
value: 'LastTwelveMonths'
|
||||
}
|
||||
]
|
||||
@ -219,23 +222,23 @@ const relativeToCurrentListRange = computed(() => {
|
||||
case 'datetimerange':
|
||||
list = [
|
||||
{
|
||||
label: '今天',
|
||||
label: t('dynamic_time.today'),
|
||||
value: 'today'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
label: t('dynamic_time.yesterday'),
|
||||
value: 'yesterday'
|
||||
},
|
||||
{
|
||||
label: '最近 3 天',
|
||||
label: t('v_query.last_3_days'),
|
||||
value: 'LastThreeDays'
|
||||
},
|
||||
{
|
||||
label: '月初至今',
|
||||
label: t('v_query.month_to_date'),
|
||||
value: 'monthBeginning'
|
||||
},
|
||||
{
|
||||
label: '年初至今',
|
||||
label: t('v_query.year_to_date'),
|
||||
value: 'yearBeginning'
|
||||
}
|
||||
]
|
||||
@ -248,7 +251,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
return [
|
||||
...list,
|
||||
{
|
||||
label: '自定义',
|
||||
label: t('dynamic_time.custom'),
|
||||
value: 'custom'
|
||||
}
|
||||
]
|
||||
@ -257,9 +260,9 @@ const relativeToCurrentListRange = computed(() => {
|
||||
|
||||
<template>
|
||||
<div class="set-time-filtering-range">
|
||||
<div class="title">设置时间筛选范围</div>
|
||||
<div class="title">{{ t('v_query.time_filter_range') }}</div>
|
||||
<div class="list-item">
|
||||
<div class="label">区间类型</div>
|
||||
<div class="label">{{ t('v_query.interval_type') }}</div>
|
||||
<div class="setting-content">
|
||||
<div class="setting">
|
||||
<el-radio-group v-model="timeRange.intervalType">
|
||||
@ -275,13 +278,13 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting-content">
|
||||
<div class="setting">
|
||||
<el-radio-group v-model="timeRange.regularOrTrends">
|
||||
<el-radio label="fixed">固定时间</el-radio>
|
||||
<el-radio label="dynamic">动态时间</el-radio>
|
||||
<el-radio label="fixed">{{ t('dynamic_time.fix') }}</el-radio>
|
||||
<el-radio label="dynamic">{{ t('dynamic_time.dynamic') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<template v-if="dynamicTime && timeRange.intervalType !== 'timeInterval'">
|
||||
<div class="setting" v-if="timeRange.intervalType !== 'timeInterval'">
|
||||
<div class="setting-label">相对当前</div>
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select v-model="timeRange.relativeToCurrent">
|
||||
<el-option
|
||||
@ -317,7 +320,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
</template>
|
||||
<template v-else-if="dynamicTime && timeRange.intervalType === 'timeInterval'">
|
||||
<div class="setting">
|
||||
<div class="setting-label">相对当前</div>
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select v-model="timeRange.relativeToCurrentRange">
|
||||
<el-option
|
||||
@ -337,7 +340,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
'is-year-month-range'
|
||||
"
|
||||
>
|
||||
<div class="setting-label">开始时间</div>
|
||||
<div class="setting-label">{{ t('datasource.start_time') }}</div>
|
||||
<div class="setting-input range">
|
||||
<el-input-number
|
||||
step-strictly
|
||||
@ -370,7 +373,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
'is-year-month-range'
|
||||
"
|
||||
>
|
||||
<div class="setting-label">结束时间</div>
|
||||
<div class="setting-label">{{ t('datasource.end_time') }}</div>
|
||||
<div class="setting-input range">
|
||||
<el-input-number
|
||||
v-model="timeRange.timeNumRange"
|
||||
@ -400,7 +403,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
</template>
|
||||
</div>
|
||||
<div class="parameters" :class="dynamicTime && 'setting'">
|
||||
<div class="setting-label" v-if="dynamicTime">预览</div>
|
||||
<div class="setting-label" v-if="dynamicTime">{{ t('template_manage.preview') }}</div>
|
||||
<div :class="dynamicTime ? 'setting-value' : 'w100'">
|
||||
<component
|
||||
:config="timeRange"
|
||||
@ -413,10 +416,10 @@ const relativeToCurrentListRange = computed(() => {
|
||||
</div>
|
||||
<div class="list-item">
|
||||
<div class="label">
|
||||
<el-checkbox v-model="timeRange.dynamicWindow" label="动态查询时间窗口" />
|
||||
<el-checkbox v-model="timeRange.dynamicWindow" :label="t('v_query.query_time_window')" />
|
||||
</div>
|
||||
<div v-if="timeRange.dynamicWindow" class="setting-content maximum-single-query">
|
||||
单次查询最多
|
||||
{{ t('v_query.maximum_single_query') }}
|
||||
<el-input-number
|
||||
v-model="timeRange.maximumSingleQuery"
|
||||
:min="1"
|
||||
|
||||
@ -15,6 +15,7 @@ import {
|
||||
import { enumValueObj, type EnumValue, getEnumValue } from '@/api/dataset'
|
||||
import { cloneDeep, debounce } from 'lodash-es'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
|
||||
interface SelectConfig {
|
||||
selectValue: any
|
||||
@ -46,6 +47,8 @@ interface SelectConfig {
|
||||
}[]
|
||||
}
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
config: {
|
||||
type: Object as PropType<SelectConfig>,
|
||||
@ -83,7 +86,7 @@ const cascadeList = inject('cascade-list', Function, true)
|
||||
const setCascadeDefault = inject('set-cascade-default', Function, true)
|
||||
|
||||
const placeholderText = computed(() => {
|
||||
if (placeholder.value.placeholderShow) {
|
||||
if (placeholder?.value?.placeholderShow) {
|
||||
return ['', undefined].includes(props.config.placeholder) ? ' ' : props.config.placeholder
|
||||
}
|
||||
return ' '
|
||||
@ -367,7 +370,7 @@ const setEmptyData = () => {
|
||||
const [s] = options.value
|
||||
if (showEmpty) {
|
||||
if (s?.value !== '_empty_$') {
|
||||
options.value = [{ label: '空数据', value: '_empty_$' }, ...options.value]
|
||||
options.value = [{ label: t('v_query.empty_data'), value: '_empty_$' }, ...options.value]
|
||||
}
|
||||
} else {
|
||||
if (s?.value === '_empty_$') {
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
import { toRefs, onBeforeMount, type PropType, type Ref, inject, computed, nextTick } from 'vue'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
interface SelectConfig {
|
||||
id: string
|
||||
conditionValueOperatorF: string
|
||||
@ -17,9 +18,10 @@ interface SelectConfig {
|
||||
conditionType: number
|
||||
}
|
||||
const placeholder: Ref = inject('placeholder')
|
||||
const { t } = useI18n()
|
||||
|
||||
const placeholderText = computed(() => {
|
||||
if (placeholder.value.placeholderShow) {
|
||||
if (placeholder?.value?.placeholderShow) {
|
||||
return props.config.placeholder
|
||||
}
|
||||
return ' '
|
||||
@ -27,11 +29,11 @@ const placeholderText = computed(() => {
|
||||
|
||||
const operators = [
|
||||
{
|
||||
label: '精确匹配',
|
||||
label: t('v_query.exact_match'),
|
||||
value: 'eq'
|
||||
},
|
||||
{
|
||||
label: '模糊匹配',
|
||||
label: t('v_query.fuzzy_match'),
|
||||
value: 'like'
|
||||
}
|
||||
]
|
||||
@ -120,7 +122,9 @@ const lineWidth = computed(() => {
|
||||
<div :style="lineWidth" class="bottom-line"></div>
|
||||
</div>
|
||||
<div class="condition-type" v-if="[1, 2].includes(config.conditionType)">
|
||||
<sapn class="condition-type-tip">{{ config.conditionType === 1 ? '与' : '或' }}</sapn>
|
||||
<sapn class="condition-type-tip">{{
|
||||
config.conditionType === 1 ? t('chart.and') : t('chart.or')
|
||||
}}</sapn>
|
||||
<el-select
|
||||
v-if="!config.hideConditionSwitching"
|
||||
class="condition-value-select"
|
||||
|
||||
@ -5,6 +5,7 @@ import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import type { ManipulateType } from 'dayjs'
|
||||
import { type TimeRange } from './time-format'
|
||||
import dayjs from 'dayjs'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { useShortcuts } from './shortcuts'
|
||||
import { getThisStart, getLastStart, getAround } from './time-format-dayjs'
|
||||
import VanPopup from 'vant/es/popup'
|
||||
@ -28,6 +29,7 @@ interface SelectConfig {
|
||||
placeholder: string
|
||||
setTimeRange: boolean
|
||||
}
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
config: {
|
||||
@ -65,7 +67,7 @@ const props = defineProps({
|
||||
})
|
||||
const placeholder: Ref = inject('placeholder')
|
||||
const placeholderText = computed(() => {
|
||||
if (placeholder.value.placeholderShow) {
|
||||
if (placeholder?.value?.placeholderShow) {
|
||||
return props.config.placeholder
|
||||
}
|
||||
return ' '
|
||||
@ -453,9 +455,9 @@ const formatDate = computed(() => {
|
||||
@confirm="onConfirm"
|
||||
@cancel="onCancel"
|
||||
v-if="showTimePick"
|
||||
title="时间选择"
|
||||
:tabs="['选择日期', '选择时间']"
|
||||
next-step-text="下一步"
|
||||
:title="t('v_query.time_selection')"
|
||||
:tabs="[t('dataset.select_date'), t('dataset.select_time')]"
|
||||
:next-step-text="t('sync_datasource.next')"
|
||||
>
|
||||
<van-date-picker
|
||||
:min-date="minDate"
|
||||
@ -466,7 +468,7 @@ const formatDate = computed(() => {
|
||||
<van-time-picker :columns-type="['hour', 'minute', 'second']" v-model="currentTime" />
|
||||
</van-picker-group>
|
||||
<van-date-picker
|
||||
title="选择日期"
|
||||
:title="t('dataset.select_date')"
|
||||
:columns-type="columnsType"
|
||||
@confirm="onConfirm"
|
||||
@cancel="onCancel"
|
||||
|
||||
@ -58,7 +58,7 @@ const props = defineProps({
|
||||
|
||||
const placeholder: Ref = inject('placeholder')
|
||||
const placeholderText = computed(() => {
|
||||
if (placeholder.value.placeholderShow) {
|
||||
if (placeholder?.value?.placeholderShow) {
|
||||
return ['', undefined].includes(props.config.placeholder) ? ' ' : props.config.placeholder
|
||||
}
|
||||
return ' '
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg'
|
||||
import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg'
|
||||
import { guid } from '@/views/visualized/data/dataset/form/util.js'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { ref, shallowRef, computed } from 'vue'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
@ -10,10 +11,12 @@ const dialogVisible = ref(false)
|
||||
const treeList = ref([])
|
||||
const datasetMap = shallowRef([])
|
||||
const emits = defineEmits(['saveTree'])
|
||||
|
||||
const { t } = useI18n()
|
||||
const addCascadeItem = () => {
|
||||
treeList.value.push({
|
||||
field: null,
|
||||
field: {
|
||||
id: ''
|
||||
},
|
||||
id: guid()
|
||||
})
|
||||
}
|
||||
@ -50,13 +53,20 @@ const setCascadeArrBack = () => {
|
||||
const confirmClick = () => {
|
||||
const { isError, arr } = setCascadeArrBack()
|
||||
if (isError) {
|
||||
ElMessage.error('层级字段不能为空,请选择字段!')
|
||||
ElMessage.error(t('v_query.select_a_field'))
|
||||
return
|
||||
}
|
||||
emits('saveTree', arr)
|
||||
handleBeforeClose()
|
||||
}
|
||||
const indexCascade = ' 一二三四五'
|
||||
const indexCascade = [
|
||||
' ',
|
||||
t('report.week_mon'),
|
||||
t('report.week_tue'),
|
||||
t('report.week_wed'),
|
||||
t('report.week_thu'),
|
||||
t('report.week_fri')
|
||||
]
|
||||
|
||||
const deleteCascade = idx => {
|
||||
treeList.value.splice(idx, 1)
|
||||
@ -75,7 +85,7 @@ defineExpose({
|
||||
:before-close="handleBeforeClose"
|
||||
@mousedown.stop
|
||||
@mousedup.stop
|
||||
title="下拉树结构设计"
|
||||
:title="t('v_query.tree_structure_design')"
|
||||
>
|
||||
<div class="cascade-content">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||
@ -83,15 +93,15 @@ defineExpose({
|
||||
<template #icon>
|
||||
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
||||
</template>
|
||||
添加层级
|
||||
{{ t('v_query.add_level') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="cascade-item">
|
||||
<div class="label">层级</div>
|
||||
<div class="item-name">下拉树查询字段</div>
|
||||
<div class="label">{{ t('visualization.level') }}</div>
|
||||
<div class="item-name">{{ t('v_query.tree_query_field') }}</div>
|
||||
</div>
|
||||
<div class="cascade-item" v-for="(ele, idx) in treeList" :key="ele.id">
|
||||
<div class="label">层级{{ indexCascade[idx + 1] }}</div>
|
||||
<div class="label">{{ t('visualization.level') }}{{ indexCascade[idx + 1] }}</div>
|
||||
<div class="item-name">
|
||||
<el-select
|
||||
:disabled="idx === 0 && ele.field"
|
||||
@ -119,8 +129,8 @@ defineExpose({
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button secondary @click="cancelClick">取消</el-button>
|
||||
<el-button type="primary" @click="confirmClick"> 确定 </el-button>
|
||||
<el-button secondary @click="cancelClick">{{ t('common.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirmClick"> {{ t('pblink.sure_bt') }} </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import type { ComponentInfo } from '@/api/chart'
|
||||
import { guid } from '@/views/visualized/data/dataset/form/util.js'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
const { t } = useI18n()
|
||||
|
||||
const infoFormat = (obj: ComponentInfo) => {
|
||||
const { id, name, deType, type, datasetId } = obj
|
||||
@ -67,7 +69,7 @@ const infoFormat = (obj: ComponentInfo) => {
|
||||
const addQueryCriteriaConfig = () => {
|
||||
const componentInfo: ComponentInfo = {
|
||||
id: '',
|
||||
name: '未命名',
|
||||
name: t('v_query.unnamed'),
|
||||
deType: 0,
|
||||
type: 'VARCHAR',
|
||||
datasetId: ''
|
||||
|
||||
@ -181,8 +181,12 @@ const getResultNum = (
|
||||
numValueEnd,
|
||||
numValueStart,
|
||||
defaultNumValueStart,
|
||||
defaultValueCheck,
|
||||
firstLoad
|
||||
) => {
|
||||
if (firstLoad && !defaultValueCheck) {
|
||||
return []
|
||||
}
|
||||
const valueS = firstLoad ? defaultNumValueStart : numValueStart
|
||||
const valueE = firstLoad ? defaultNumValueEnd : numValueEnd
|
||||
return [valueS ?? '', valueE ?? ''].filter(ele => ele !== '')
|
||||
@ -246,242 +250,238 @@ const duplicateRemoval = arr => {
|
||||
export const searchQuery = (queryComponentList, filter, curComponentId, firstLoad) => {
|
||||
queryComponentList.forEach(ele => {
|
||||
if (!!ele.propValue?.length) {
|
||||
ele.propValue
|
||||
.filter(itx => itx.visible)
|
||||
.forEach(item => {
|
||||
ele.propValue.forEach(item => {
|
||||
if (item.checkedFields.includes(curComponentId) && item.checkedFieldsMap[curComponentId]) {
|
||||
let selectValue
|
||||
const {
|
||||
selectValue: value,
|
||||
timeGranularityMultiple,
|
||||
defaultNumValueEnd,
|
||||
numValueEnd,
|
||||
numValueStart,
|
||||
defaultNumValueStart,
|
||||
conditionType = 0,
|
||||
treeFieldList = [],
|
||||
defaultConditionValueOperatorF = 'eq',
|
||||
defaultConditionValueF = '',
|
||||
defaultConditionValueOperatorS = 'like',
|
||||
defaultConditionValueS = '',
|
||||
conditionValueOperatorF = 'eq',
|
||||
conditionValueF = '',
|
||||
conditionValueOperatorS = 'like',
|
||||
conditionValueS = '',
|
||||
defaultValueCheck,
|
||||
timeType = 'fixed',
|
||||
defaultValue,
|
||||
optionValueSource,
|
||||
defaultMapValue,
|
||||
mapValue,
|
||||
parameters = [],
|
||||
timeGranularity = 'date',
|
||||
displayType,
|
||||
displayId,
|
||||
multiple
|
||||
} = item
|
||||
|
||||
const isTree = +displayType === 9
|
||||
|
||||
if (
|
||||
item.checkedFields.includes(curComponentId) &&
|
||||
item.checkedFieldsMap[curComponentId]
|
||||
timeType === 'dynamic' &&
|
||||
[1, 7].includes(+displayType) &&
|
||||
firstLoad &&
|
||||
defaultValueCheck
|
||||
) {
|
||||
let selectValue
|
||||
const {
|
||||
selectValue: value,
|
||||
timeGranularityMultiple,
|
||||
if (+displayType === 1) {
|
||||
selectValue = getDynamicRange(item)
|
||||
item.defaultValue = new Date(selectValue[0])
|
||||
item.selectValue = new Date(selectValue[0])
|
||||
} else {
|
||||
const {
|
||||
timeNum,
|
||||
relativeToCurrentType,
|
||||
around,
|
||||
relativeToCurrentRange,
|
||||
arbitraryTime,
|
||||
timeGranularity,
|
||||
timeNumRange,
|
||||
relativeToCurrentTypeRange,
|
||||
aroundRange,
|
||||
timeGranularityMultiple,
|
||||
arbitraryTimeRange
|
||||
} = item
|
||||
|
||||
let startTime = getCustomTime(
|
||||
timeNum,
|
||||
relativeToCurrentType,
|
||||
timeGranularity,
|
||||
around,
|
||||
arbitraryTime,
|
||||
timeGranularityMultiple,
|
||||
'start-panel'
|
||||
)
|
||||
let endTime = getCustomTime(
|
||||
timeNumRange,
|
||||
relativeToCurrentTypeRange,
|
||||
timeGranularity,
|
||||
aroundRange,
|
||||
arbitraryTimeRange,
|
||||
timeGranularityMultiple,
|
||||
'end-panel'
|
||||
)
|
||||
|
||||
if (!!relativeToCurrentRange && relativeToCurrentRange !== 'custom') {
|
||||
;[startTime, endTime] = getCustomRange(relativeToCurrentRange)
|
||||
}
|
||||
item.defaultValue = [startTime, endTime]
|
||||
item.selectValue = [startTime, endTime]
|
||||
selectValue = [startTime, endTime]
|
||||
}
|
||||
} else if (displayType === '8') {
|
||||
selectValue = getResult(
|
||||
conditionType,
|
||||
defaultConditionValueF,
|
||||
defaultConditionValueS,
|
||||
conditionValueF,
|
||||
conditionValueS,
|
||||
firstLoad
|
||||
)
|
||||
} else if (displayType === '22') {
|
||||
selectValue = getResultNum(
|
||||
defaultNumValueEnd,
|
||||
numValueEnd,
|
||||
numValueStart,
|
||||
defaultNumValueStart,
|
||||
conditionType = 0,
|
||||
treeFieldList = [],
|
||||
defaultConditionValueOperatorF = 'eq',
|
||||
defaultConditionValueF = '',
|
||||
defaultConditionValueOperatorS = 'like',
|
||||
defaultConditionValueS = '',
|
||||
conditionValueOperatorF = 'eq',
|
||||
conditionValueF = '',
|
||||
conditionValueOperatorS = 'like',
|
||||
conditionValueS = '',
|
||||
defaultValueCheck,
|
||||
timeType = 'fixed',
|
||||
firstLoad
|
||||
)
|
||||
} else {
|
||||
selectValue = getValueByDefaultValueCheckOrFirstLoad(
|
||||
defaultValueCheck,
|
||||
defaultValue,
|
||||
optionValueSource,
|
||||
value,
|
||||
firstLoad,
|
||||
multiple,
|
||||
defaultMapValue,
|
||||
optionValueSource,
|
||||
mapValue,
|
||||
parameters = [],
|
||||
timeGranularity = 'date',
|
||||
displayType,
|
||||
displayId,
|
||||
multiple
|
||||
} = item
|
||||
displayId
|
||||
)
|
||||
}
|
||||
if (
|
||||
!!selectValue?.length ||
|
||||
['[object Number]', '[object Date]'].includes(
|
||||
Object.prototype.toString.call(selectValue)
|
||||
) ||
|
||||
displayType === '8'
|
||||
) {
|
||||
let result = forMatterValue(
|
||||
+displayType,
|
||||
selectValue,
|
||||
timeGranularity,
|
||||
timeGranularityMultiple
|
||||
)
|
||||
const operator = getOperator(
|
||||
displayType,
|
||||
multiple,
|
||||
conditionType,
|
||||
defaultConditionValueOperatorF,
|
||||
defaultConditionValueF,
|
||||
defaultConditionValueOperatorS,
|
||||
defaultConditionValueS,
|
||||
conditionValueOperatorF,
|
||||
conditionValueF,
|
||||
conditionValueOperatorS,
|
||||
conditionValueS,
|
||||
firstLoad
|
||||
)
|
||||
if (result?.length) {
|
||||
const fieldId = isTree
|
||||
? getFieldId(treeFieldList, result)
|
||||
: item.checkedFieldsMap[curComponentId]
|
||||
let parametersFilter = duplicateRemoval(
|
||||
parameters.reduce((pre, next) => {
|
||||
if (next.id === fieldId && !pre.length) {
|
||||
pre.push(next)
|
||||
}
|
||||
return pre
|
||||
}, [])
|
||||
)
|
||||
|
||||
const isTree = +displayType === 9
|
||||
|
||||
if (
|
||||
timeType === 'dynamic' &&
|
||||
[1, 7].includes(+displayType) &&
|
||||
firstLoad &&
|
||||
defaultValueCheck
|
||||
) {
|
||||
if (+displayType === 1) {
|
||||
selectValue = getDynamicRange(item)
|
||||
item.defaultValue = new Date(selectValue[0])
|
||||
item.selectValue = new Date(selectValue[0])
|
||||
} else {
|
||||
const {
|
||||
timeNum,
|
||||
relativeToCurrentType,
|
||||
around,
|
||||
relativeToCurrentRange,
|
||||
arbitraryTime,
|
||||
timeGranularity,
|
||||
timeNumRange,
|
||||
relativeToCurrentTypeRange,
|
||||
aroundRange,
|
||||
timeGranularityMultiple,
|
||||
arbitraryTimeRange
|
||||
} = item
|
||||
|
||||
let startTime = getCustomTime(
|
||||
timeNum,
|
||||
relativeToCurrentType,
|
||||
timeGranularity,
|
||||
around,
|
||||
arbitraryTime,
|
||||
timeGranularityMultiple,
|
||||
'start-panel'
|
||||
if (item.checkedFieldsMapArr?.[curComponentId]?.length) {
|
||||
const endTimeFieldId = item.checkedFieldsMapArr?.[curComponentId].find(
|
||||
element => element !== fieldId
|
||||
)
|
||||
let endTime = getCustomTime(
|
||||
timeNumRange,
|
||||
relativeToCurrentTypeRange,
|
||||
timeGranularity,
|
||||
aroundRange,
|
||||
arbitraryTimeRange,
|
||||
timeGranularityMultiple,
|
||||
'end-panel'
|
||||
const resultEnd = Array(2).fill(
|
||||
endTimeFieldId === item.checkedFieldsMapEnd[curComponentId]
|
||||
? result[1]
|
||||
: result[0]
|
||||
)
|
||||
result = Array(2).fill(
|
||||
endTimeFieldId === item.checkedFieldsMapEnd[curComponentId]
|
||||
? result[0]
|
||||
: result[1]
|
||||
)
|
||||
parametersFilter = duplicateRemoval(
|
||||
item.parametersArr[curComponentId].filter(e => e.id === fieldId)
|
||||
)
|
||||
|
||||
if (!!relativeToCurrentRange && relativeToCurrentRange !== 'custom') {
|
||||
;[startTime, endTime] = getCustomRange(relativeToCurrentRange)
|
||||
}
|
||||
item.defaultValue = [startTime, endTime]
|
||||
item.selectValue = [startTime, endTime]
|
||||
selectValue = [startTime, endTime]
|
||||
}
|
||||
} else if (displayType === '8') {
|
||||
selectValue = getResult(
|
||||
conditionType,
|
||||
defaultConditionValueF,
|
||||
defaultConditionValueS,
|
||||
conditionValueF,
|
||||
conditionValueS,
|
||||
firstLoad
|
||||
)
|
||||
} else if (displayType === '22') {
|
||||
selectValue = getResultNum(
|
||||
defaultNumValueEnd,
|
||||
numValueEnd,
|
||||
numValueStart,
|
||||
defaultNumValueStart,
|
||||
firstLoad
|
||||
)
|
||||
} else {
|
||||
selectValue = getValueByDefaultValueCheckOrFirstLoad(
|
||||
defaultValueCheck,
|
||||
defaultValue,
|
||||
value,
|
||||
firstLoad,
|
||||
multiple,
|
||||
defaultMapValue,
|
||||
optionValueSource,
|
||||
mapValue,
|
||||
displayType,
|
||||
displayId
|
||||
)
|
||||
}
|
||||
if (
|
||||
!!selectValue?.length ||
|
||||
['[object Number]', '[object Date]'].includes(
|
||||
Object.prototype.toString.call(selectValue)
|
||||
) ||
|
||||
displayType === '8'
|
||||
) {
|
||||
let result = forMatterValue(
|
||||
+displayType,
|
||||
selectValue,
|
||||
timeGranularity,
|
||||
timeGranularityMultiple
|
||||
)
|
||||
const operator = getOperator(
|
||||
displayType,
|
||||
multiple,
|
||||
conditionType,
|
||||
defaultConditionValueOperatorF,
|
||||
defaultConditionValueF,
|
||||
defaultConditionValueOperatorS,
|
||||
defaultConditionValueS,
|
||||
conditionValueOperatorF,
|
||||
conditionValueF,
|
||||
conditionValueOperatorS,
|
||||
conditionValueS,
|
||||
firstLoad
|
||||
)
|
||||
if (result?.length) {
|
||||
const fieldId = isTree
|
||||
? getFieldId(treeFieldList, result)
|
||||
: item.checkedFieldsMap[curComponentId]
|
||||
let parametersFilter = duplicateRemoval(
|
||||
parameters.reduce((pre, next) => {
|
||||
if (next.id === fieldId && !pre.length) {
|
||||
pre.push(next)
|
||||
}
|
||||
return pre
|
||||
}, [])
|
||||
const parametersFilterEnd = duplicateRemoval(
|
||||
item.parametersArr[curComponentId].filter(e => e.id === endTimeFieldId)
|
||||
)
|
||||
|
||||
if (item.checkedFieldsMapArr?.[curComponentId]?.length) {
|
||||
const endTimeFieldId = item.checkedFieldsMapArr?.[curComponentId].find(
|
||||
element => element !== fieldId
|
||||
)
|
||||
const resultEnd = Array(2).fill(
|
||||
endTimeFieldId === item.checkedFieldsMapEnd[curComponentId]
|
||||
? result[1]
|
||||
: result[0]
|
||||
)
|
||||
result = Array(2).fill(
|
||||
endTimeFieldId === item.checkedFieldsMapEnd[curComponentId]
|
||||
? result[0]
|
||||
: result[1]
|
||||
)
|
||||
parametersFilter = duplicateRemoval(
|
||||
item.parametersArr[curComponentId].filter(e => e.id === fieldId)
|
||||
)
|
||||
|
||||
const parametersFilterEnd = duplicateRemoval(
|
||||
item.parametersArr[curComponentId].filter(e => e.id === endTimeFieldId)
|
||||
)
|
||||
filter.push({
|
||||
componentId: ele.id,
|
||||
fieldId: endTimeFieldId,
|
||||
operator,
|
||||
value: resultEnd,
|
||||
parameters: parametersFilterEnd,
|
||||
isTree
|
||||
})
|
||||
}
|
||||
|
||||
if (item.checkedFieldsMapArrNum?.[curComponentId]?.length) {
|
||||
const endTimeFieldId = item.checkedFieldsMapArrNum?.[curComponentId].find(
|
||||
element => element !== fieldId
|
||||
)
|
||||
const resultEnd = Array(2).fill(
|
||||
endTimeFieldId === item.checkedFieldsMapEndNum[curComponentId]
|
||||
? result[1]
|
||||
: result[0]
|
||||
)
|
||||
result = Array(2).fill(
|
||||
endTimeFieldId === item.checkedFieldsMapEndNum[curComponentId]
|
||||
? result[0]
|
||||
: result[1]
|
||||
)
|
||||
parametersFilter = duplicateRemoval(
|
||||
item.parametersArr[curComponentId].filter(e => e.id === fieldId)
|
||||
)
|
||||
|
||||
const parametersFilterEnd = duplicateRemoval(
|
||||
item.parametersArr[curComponentId].filter(e => e.id === endTimeFieldId)
|
||||
)
|
||||
filter.push({
|
||||
componentId: ele.id,
|
||||
fieldId: endTimeFieldId,
|
||||
operator,
|
||||
value: resultEnd,
|
||||
parameters: parametersFilterEnd,
|
||||
isTree
|
||||
})
|
||||
}
|
||||
|
||||
filter.push({
|
||||
componentId: ele.id,
|
||||
fieldId,
|
||||
fieldId: endTimeFieldId,
|
||||
operator,
|
||||
value: result,
|
||||
parameters: parametersFilter,
|
||||
value: resultEnd,
|
||||
parameters: parametersFilterEnd,
|
||||
isTree
|
||||
})
|
||||
}
|
||||
|
||||
if (item.checkedFieldsMapArrNum?.[curComponentId]?.length) {
|
||||
const endTimeFieldId = item.checkedFieldsMapArrNum?.[curComponentId].find(
|
||||
element => element !== fieldId
|
||||
)
|
||||
const resultEnd = Array(2).fill(
|
||||
endTimeFieldId === item.checkedFieldsMapEndNum[curComponentId]
|
||||
? result[1]
|
||||
: result[0]
|
||||
)
|
||||
result = Array(2).fill(
|
||||
endTimeFieldId === item.checkedFieldsMapEndNum[curComponentId]
|
||||
? result[0]
|
||||
: result[1]
|
||||
)
|
||||
parametersFilter = duplicateRemoval(
|
||||
item.parametersArr[curComponentId].filter(e => e.id === fieldId)
|
||||
)
|
||||
|
||||
const parametersFilterEnd = duplicateRemoval(
|
||||
item.parametersArr[curComponentId].filter(e => e.id === endTimeFieldId)
|
||||
)
|
||||
filter.push({
|
||||
componentId: ele.id,
|
||||
fieldId: endTimeFieldId,
|
||||
operator,
|
||||
value: resultEnd,
|
||||
parameters: parametersFilterEnd,
|
||||
isTree
|
||||
})
|
||||
}
|
||||
|
||||
filter.push({
|
||||
componentId: ele.id,
|
||||
fieldId,
|
||||
operator,
|
||||
value: result,
|
||||
parameters: parametersFilter,
|
||||
isTree
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ export default {
|
||||
add_component_hint: 'Click or drag the component on the left to add a field'
|
||||
},
|
||||
inputText: 'Please input',
|
||||
selectText: 'Please select',
|
||||
account: 'Account',
|
||||
email: 'Email',
|
||||
phone: 'Phone',
|
||||
@ -34,7 +35,9 @@ export default {
|
||||
save_success: 'Save success',
|
||||
roger_that: 'Roger that',
|
||||
delete_success: 'Delete success',
|
||||
no_auth_tips: 'Missing menu permissions, please contact the administrator'
|
||||
no_auth_tips: 'Missing menu permissions, please contact the administrator',
|
||||
filter: 'Filter',
|
||||
filter_condition: 'Filter Condition'
|
||||
},
|
||||
toolbox: {
|
||||
name: 'Toolbox',
|
||||
@ -99,7 +102,12 @@ export default {
|
||||
delete_catalog_hint: 'Are You Sure You Want to Delete This Category?',
|
||||
delete_catalog_tip: 'Deletion Is Irreversible. Do You Want to Continue?',
|
||||
illegal_name_hint: 'Illegal Name. Please Change!',
|
||||
exists_name_hint: 'This Name Already Exists in Template Management. Please Modify'
|
||||
exists_name_hint: 'This Name Already Exists in Template Management. Please Modify',
|
||||
get_download_link_hint:
|
||||
'Please contact the official template marketplace if you have not obtained the template download link.',
|
||||
search_result_count: 'The search results are {0} items.',
|
||||
template_center: 'Template Center',
|
||||
preview: 'Preview'
|
||||
},
|
||||
commons: {
|
||||
date: {
|
||||
@ -384,6 +392,7 @@ export default {
|
||||
last_edited_by: 'Last edited by',
|
||||
last_edit_time: 'last edit time',
|
||||
big_data_screen: 'Big data screen',
|
||||
big_screen: 'Big screen',
|
||||
dashboard: 'Dashboard',
|
||||
data_set: 'data set',
|
||||
data_source: 'data source',
|
||||
@ -411,7 +420,13 @@ export default {
|
||||
password_null_hint: 'Password cannot be empty. Please re-enter!',
|
||||
password_hint:
|
||||
'Password must be a 4-10 character string containing numbers, letters, and special characters [!@#$%^&*()_+]',
|
||||
max_ticket_count: 'Supports up to 5 Tickets creation'
|
||||
max_ticket_count: 'Supports up to 5 Tickets creation',
|
||||
last: 'Previous',
|
||||
next: 'Next',
|
||||
recommend: 'Recommended',
|
||||
recent: 'Recently Used',
|
||||
all_types: 'All Types',
|
||||
all_source: 'All Sources'
|
||||
},
|
||||
data_set: {
|
||||
ten_wan: '100000',
|
||||
@ -1077,5 +1092,323 @@ export default {
|
||||
switch_chart: 'Switch chart type',
|
||||
switch_table: 'Switch to detail table',
|
||||
download: 'Download'
|
||||
},
|
||||
sync_manage: {
|
||||
title: 'Sync Management',
|
||||
ds_search_placeholder: 'Search by name or description'
|
||||
},
|
||||
sync_datasource: {
|
||||
title: 'Data Connection Management',
|
||||
source_ds: 'Source',
|
||||
target_ds: 'Target',
|
||||
add_source_ds: 'Add',
|
||||
add_target_ds: 'Add',
|
||||
name: 'Name',
|
||||
desc: 'Description',
|
||||
type: 'Type',
|
||||
status: 'Status',
|
||||
create_time: 'Creation Time',
|
||||
update_time: 'Update Time',
|
||||
operation: 'Operation',
|
||||
edit: 'Edit',
|
||||
delete: 'Delete',
|
||||
confirm_batch_delete_target_ds: 'Are you sure you want to delete {0} target data sources?',
|
||||
confirm_batch_delete_source_ds: 'Are you sure you want to delete {0} source data sources?',
|
||||
recently_created: 'Recently Created',
|
||||
has_running_task_msg:
|
||||
'Once the running task is completed, synchronization will continue using the previous configuration. You need to manually resave the task',
|
||||
edit_datasource: 'Edit',
|
||||
add_datasource: 'Create New',
|
||||
config_info: 'Configuration Information',
|
||||
ds_type: 'Datasource Type',
|
||||
valid: 'Valid',
|
||||
invalid: 'Invalid',
|
||||
start_time: 'Start Time',
|
||||
end_time: 'End Time',
|
||||
ds_delete_confirm: 'Are you sure you want to delete this data source?',
|
||||
datasource: 'Data Source',
|
||||
select_folder: 'Please select a folder',
|
||||
sync_ds: 'Synchronize',
|
||||
sync_to_datasource: 'Sync to the prepared data source list',
|
||||
input_ds_name: 'Please enter the data source name',
|
||||
folder: 'Parent Folder',
|
||||
cancel: 'Cancel',
|
||||
save: 'Save',
|
||||
next: 'Next',
|
||||
prev: 'Previous',
|
||||
validate: 'Validate',
|
||||
validate_success: 'Validation Successful',
|
||||
select_type: 'Please select the data source type',
|
||||
extra_params: 'Additional JDBC connection string',
|
||||
remark: 'Remark',
|
||||
input_name: 'Please enter name',
|
||||
input_limit_2_25: '{0}-{1} characters',
|
||||
input_limit_2_50: '2-50 characters',
|
||||
input_limit_2_64: '2-64 characters',
|
||||
input_limit_1_64: '1-64 characters',
|
||||
data_source_configuration: 'Data source configuration',
|
||||
data_source_table: 'Data source table',
|
||||
auth_method: 'Authentication method',
|
||||
passwd: 'Username and password',
|
||||
kerbers_info:
|
||||
'Please ensure krb5.conf and Keytab Key are added to the path: /opt/dataease2.0/conf',
|
||||
client_principal: 'Client Principal',
|
||||
keytab_Key_path: 'Keytab Key Path',
|
||||
data_base: 'Database name',
|
||||
user_name: 'Username',
|
||||
password: 'Password',
|
||||
host: 'Host name/IP address',
|
||||
doris_host: 'Doris address',
|
||||
query_port: 'Query Port',
|
||||
http_port: 'HTTP Port',
|
||||
port: 'Port',
|
||||
datasource_url: 'Address',
|
||||
please_input_datasource_url: 'Please enter Elasticsearch address, e.g., http://es_host:es_port',
|
||||
please_input_data_base: 'Please enter database name',
|
||||
please_input_jdbc_url: 'Please enter JDBC connection',
|
||||
please_select_oracle_type: 'Select connection type',
|
||||
please_input_user_name: 'Please enter username',
|
||||
please_input_password: 'Please enter password',
|
||||
please_input_host: 'Please enter host',
|
||||
please_input_url: 'Please enter URL address',
|
||||
please_input_port: 'Please enter port',
|
||||
please_input_be_port: 'Please enter BE port',
|
||||
modify: 'Edit data source',
|
||||
validate_failed: 'Validation failed',
|
||||
oracle_connection_type: 'Service name/SID',
|
||||
oracle_sid: 'SID',
|
||||
oracle_service_name: 'Service name',
|
||||
get_schema: 'Get Schema',
|
||||
schema: 'Schema',
|
||||
charset: 'Character set',
|
||||
targetCharset: 'Target character set',
|
||||
please_choose_schema: 'Please select database Schema',
|
||||
please_choose_charset: 'Please select database character set',
|
||||
please_choose_targetCharset: 'Please select target character set',
|
||||
edit_datasource_msg:
|
||||
'Modifying data source information may cause datasets under this data source to become unavailable. Confirm modification?',
|
||||
repeat_datasource_msg: 'Duplicate data source information with the same configuration exists.',
|
||||
in_valid: 'Invalid data source',
|
||||
initial_pool_size: 'Initial connection count',
|
||||
min_pool_size: 'Minimum connection count',
|
||||
max_pool_size: 'Maximum connection count',
|
||||
max_idle_time: 'Maximum idle time (seconds)',
|
||||
bucket_num: 'Bucket count',
|
||||
replication_num: 'Replication count',
|
||||
please_input_bucket_num: 'Please enter bucket count',
|
||||
please_input_replication_num: 'Please enter replication count',
|
||||
acquire_increment: 'Increment',
|
||||
connect_timeout: 'Connection timeout (seconds)',
|
||||
please_input_initial_pool_size: 'Please enter initial connection count',
|
||||
please_input_min_pool_size: 'Please enter minimum connection count',
|
||||
please_input_max_pool_size: 'Please enter maximum connection count',
|
||||
please_input_max_idle_time: 'Please enter maximum idle time (seconds)',
|
||||
please_input_acquire_increment: 'Please enter increment',
|
||||
please_input_query_timeout: 'Please enter query timeout',
|
||||
please_input_connect_timeout: 'Please enter connection timeout (seconds)',
|
||||
no_less_then_0: 'Parameters in advanced settings cannot be less than zero',
|
||||
port_no_less_then_0: 'Port cannot be less than zero',
|
||||
priority: 'Advanced settings',
|
||||
jdbcUrl: 'JDBC connection',
|
||||
_ip_address: 'Please enter host name/IP address',
|
||||
display_name: 'Display name',
|
||||
connection_mode: 'Connection mode',
|
||||
please_select: 'Please select',
|
||||
query_timeout: 'Query timeout',
|
||||
description: 'Description',
|
||||
tips: 'Tips'
|
||||
},
|
||||
sync_summary: {
|
||||
summary: 'Summary',
|
||||
data_source_number: 'Number of data sources',
|
||||
task_number: 'Number of task',
|
||||
execution_count: 'Execution count',
|
||||
execution_results_in_the_past_7_days: 'Execution performance in the past 7 days',
|
||||
sync_status_distribution: 'Sync status distribution'
|
||||
},
|
||||
sync_task: {
|
||||
title: 'Task Management',
|
||||
task_list: 'Task List',
|
||||
log_list: 'Task Logs',
|
||||
add_task: 'Add Task',
|
||||
name: 'Name',
|
||||
desc: 'Description',
|
||||
status: 'Status',
|
||||
create_time: 'Creation Time',
|
||||
update_time: 'Update Time',
|
||||
operation: 'Operation',
|
||||
edit: 'Edit',
|
||||
delete: 'Delete',
|
||||
start: 'Enable',
|
||||
stop: 'Stop',
|
||||
terminated: 'Terminate',
|
||||
running_one: 'Execute Once',
|
||||
trigger_last_time: 'Last Time',
|
||||
trigger_next_time: 'Next Time',
|
||||
status_success: 'Success',
|
||||
status_running: 'Syncing',
|
||||
status_failed: 'Failed',
|
||||
status_stopped: 'Stopped',
|
||||
status_waiting: 'Waiting',
|
||||
status_done: 'Task Ended',
|
||||
status_terminated: 'Terminated',
|
||||
status_connection_lost: 'Lost',
|
||||
log: 'Log',
|
||||
show_log: 'View Log',
|
||||
last_execute_result: 'Last Result',
|
||||
execute_result: 'Execution Result',
|
||||
task_status: 'Task Status',
|
||||
sync: 'Sync',
|
||||
target_table: 'Target Table',
|
||||
batch_del: 'Batch Delete',
|
||||
selection_info: 'Selected {0} items',
|
||||
clear_button: 'Clear',
|
||||
task_text: 'Task',
|
||||
hour: 'Hour',
|
||||
day: 'Day',
|
||||
week: 'Week',
|
||||
month: 'Month',
|
||||
year: 'Year',
|
||||
minute: 'Minute',
|
||||
second: 'Second',
|
||||
hour_minute_second: 'Hour:Minute:Second',
|
||||
please_enter_task_name: 'Please enter task name',
|
||||
input_limit_255: 'Length cannot exceed 255 characters',
|
||||
please_enter: 'Please enter',
|
||||
please_cron: 'Please enter a valid Cron expression',
|
||||
please_choose: 'Please choose',
|
||||
please_choose_start_time: 'Please choose start time',
|
||||
please_choose_end_time: 'Please choose end time',
|
||||
end_time_must_be_later_than_start_time: 'End time must be later than start time',
|
||||
please_choose_database_type: 'Please choose database type',
|
||||
please_choose_database: 'Please choose database',
|
||||
please_choose_table: 'Please choose table',
|
||||
please_enter_sql: 'Please enter SQL',
|
||||
please_choose_incremental_field: 'Please choose incremental field',
|
||||
please_enter_table_name: 'Please enter table name',
|
||||
input_limit_64: 'Length cannot exceed 64 characters',
|
||||
must_be_met_the_table_name:
|
||||
'Table name must start with a letter and can only contain letters, numbers, and underscores',
|
||||
please_choose_partition_type: 'Please choose partition type',
|
||||
please_enter_end_offset: 'Please enter end offset',
|
||||
please_choose_partition_interval_unit: 'Please choose partition interval unit',
|
||||
please_enter_partition_column_value: 'Please enter partition column value',
|
||||
input_limit_4096: 'Length cannot exceed 4096 characters',
|
||||
please_enter_starting_value: 'Please enter starting value',
|
||||
please_enter_end_value: 'Please enter end value',
|
||||
please_enter_numerical_range_interval: 'Please enter numerical range interval',
|
||||
please_choose_time_range: 'Please choose time range',
|
||||
edit_success: 'Edit successful',
|
||||
add_success: 'Add successful',
|
||||
target_database_status_is_abnormal: 'Target database status is abnormal',
|
||||
edit_task: 'Edit Task',
|
||||
basic_information: 'Basic Information',
|
||||
source_database: 'Source Database',
|
||||
target_database: 'Target Database',
|
||||
task_time_out_time: 'Task Timeout (seconds)',
|
||||
effective_if_greater_than_0: 'In seconds, effective if greater than 0',
|
||||
retry_attempts_on_failure: 'Retry attempts on failure',
|
||||
sync_frequency: 'Sync Frequency',
|
||||
sync_immediately: 'Sync Immediately',
|
||||
sync_cron: 'Cron Expression Setup',
|
||||
sync_fixed_frequency: 'Fixed Frequency',
|
||||
cron_expression: 'Cron Expression',
|
||||
each: 'Every',
|
||||
sync_once: 'Sync Once',
|
||||
confirm: 'Confirm',
|
||||
msg_get_database_table_failed: 'Failed to get database table',
|
||||
msg_source_database_status_is_abnormal: 'Source database status is abnormal',
|
||||
database: 'Database',
|
||||
database_type: 'Type',
|
||||
query_method: 'Query Method',
|
||||
please_choose_data_extraction_method: 'Please choose data extraction method',
|
||||
table: 'Table',
|
||||
sql_tip_1:
|
||||
'This method does not always return the exact length or precision of column types as set by the user, but it can still serve as a reference for determining the maximum display length of each column in the result set.',
|
||||
sql_tip_2:
|
||||
'To obtain more accurate column type length and precision, please use the library table method, or set the length and precision in the field mapping of the next step.',
|
||||
please_enter_sql: 'Please enter query SQL',
|
||||
msg_confirm_delete_field: 'Are you sure you want to delete this field?',
|
||||
source_field: 'Source Field',
|
||||
field_type: 'Type',
|
||||
field_length: 'Length',
|
||||
field_precision: 'Precision',
|
||||
field_key: 'Key',
|
||||
field_index: 'Index',
|
||||
field_comment: 'Comment',
|
||||
confirm_delete_field: 'Are you sure you want to delete field {0}?',
|
||||
msg_field_list_empty_tip:
|
||||
'Field list cannot be empty, and fields with unknown types or empty names should not be included. Please check.',
|
||||
next_week: 'Next Week',
|
||||
next_month: 'Next Month',
|
||||
next_three_month: 'Next Three Months',
|
||||
must_be_start_less_end: 'End value of the range must be greater than the start value',
|
||||
must_be_partition_interval_greater_than_0: 'Partition interval must be greater than 0',
|
||||
must_be_partition_interval_less_end_start_difference:
|
||||
'Partition interval must be less than the difference between the end and start values',
|
||||
date: 'Date',
|
||||
list: 'Column',
|
||||
number: 'Number',
|
||||
define_mapping_field: 'Define Mapping Field',
|
||||
target_database_type: 'Target Database Type',
|
||||
delete_field: 'Delete Field',
|
||||
add_field: 'Add Field',
|
||||
edit_field: 'Edit Field',
|
||||
add_all_field: 'Add All Fields',
|
||||
fault_tolerance_rate: 'Fault Tolerance Rate',
|
||||
fault_tolerance_rate_tip:
|
||||
'0 to 1, default is 0, meaning if there is one error data in the sync batch, the entire batch import task will fail.',
|
||||
incremental_sync: 'Incremental Sync',
|
||||
incremental_sync_tip_1: 'Full Sync: Full overwrite sync',
|
||||
incremental_sync_tip_2:
|
||||
'Incremental Sync: Sync based on incremental field, the incremental field must be of integer or time type',
|
||||
incremental_field: 'Incremental Field',
|
||||
enable_partition: 'Enable Partition',
|
||||
enable_partition_tip:
|
||||
'Enabling partition requires the field list to not contain any empty values',
|
||||
partition_type: 'Partition Type',
|
||||
partition_field: 'Partition Field',
|
||||
on: 'Enable',
|
||||
off: 'Disable',
|
||||
picker_to: 'To',
|
||||
picker_start: 'Start',
|
||||
picker_end: 'End',
|
||||
end_offset: 'End Offset',
|
||||
number_range: 'Number Range',
|
||||
partition_interval: 'Partition Interval',
|
||||
partition_column_value: 'Partition Column Value',
|
||||
partition_column_value_placeholder: 'Partition format: p1:"v1","v2","v3";p2:"v1","v2"',
|
||||
partition_interval_unit: 'Partition Interval Unit',
|
||||
input_limit: 'Length cannot exceed {0} characters',
|
||||
cannot_begin_with_number: 'Field name cannot start with a number',
|
||||
duplicate_field_tip:
|
||||
'Duplicate field [{0}], the same source field cannot be mapped multiple times',
|
||||
duplicate_name_error: 'Name duplication [{0}]',
|
||||
confirm_batch_delete: 'Are you sure you want to batch delete the task?',
|
||||
op_success: 'Operation successful',
|
||||
search_input_name_desc_placeholder: 'Search by name or description',
|
||||
confirm_delete_msg: 'Confirm Deletion?',
|
||||
target_table_info: 'Target Table Information',
|
||||
confirm_clear_msg: 'Are you sure you want to clear {0}?',
|
||||
clear: 'Clear',
|
||||
op_success_refresh: 'Operation successful, please refresh later',
|
||||
execute_time: 'Execution Time',
|
||||
clear_log: 'Clear Log',
|
||||
search_input_name_id_placeholder: 'Search by Name or ID',
|
||||
log_id: 'Log ID',
|
||||
op: 'Operation',
|
||||
view_execute_log: 'View Execution Log',
|
||||
submit_true: 'Confirm',
|
||||
please_choose_clear_method: 'Please choose a clearing method',
|
||||
last_1_days_log: 'Logs from 1 day ago',
|
||||
last_1_weeks_log: 'Logs from 1 week ago',
|
||||
last_1_months_log: 'Logs from 1 month ago',
|
||||
last_3_months_log: 'Logs from 3 months ago',
|
||||
last_6_months_log: 'Logs from 6 months ago',
|
||||
last_1_years_log: 'Logs from 1 year ago',
|
||||
execute_log: 'Execution Log',
|
||||
done: 'Done',
|
||||
connection_lost: 'Connection Lost',
|
||||
task_name: 'Task Name'
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ export default {
|
||||
add_component_hint: '點擊或拖拽左側組件添加字段'
|
||||
},
|
||||
inputText: '請輸入',
|
||||
selectText: '請選擇',
|
||||
add: '添加',
|
||||
account: '賬號',
|
||||
email: '郵箱',
|
||||
@ -122,7 +123,11 @@ export default {
|
||||
delete_catalog_hint: '確定刪除該分類嗎?',
|
||||
delete_catalog_tip: '刪除后不可恢復,是否繼續?',
|
||||
illegal_name_hint: '不合法命名,請更換!',
|
||||
exists_name_hint: '當前名稱已在模版管理中存在,請修改'
|
||||
exists_name_hint: '當前名稱已在模版管理中存在,請修改',
|
||||
get_download_link_hint: '未獲取模板下載鏈接請聯系模板市場官方',
|
||||
search_result_count: '的搜索結果是 {0} 個',
|
||||
template_center: '模版中心',
|
||||
preview: '預覽'
|
||||
},
|
||||
work_branch: {
|
||||
back_to_work_branch: '返回工作台',
|
||||
@ -137,6 +142,7 @@ export default {
|
||||
last_edited_by: '最近編輯人',
|
||||
last_edit_time: '最近編輯時間',
|
||||
big_data_screen: '數據大屏',
|
||||
big_screen: '大屏',
|
||||
dashboard: '儀表板',
|
||||
data_set: '數據集',
|
||||
data_source: '數據源',
|
||||
@ -161,7 +167,13 @@ export default {
|
||||
error_link_hint: '鏈接格式錯誤,請重新填寫!',
|
||||
password_null_hint: '密碼不能為空,請重新輸入!',
|
||||
password_hint: '密碼必須是包含數字、字母、特殊字符[!@#$%^&*()_+]的4-10位字符串',
|
||||
max_ticket_count: '最多支持創建5個Ticket'
|
||||
max_ticket_count: '最多支持創建5個Ticket',
|
||||
last: '上一個',
|
||||
next: '下一個',
|
||||
recommend: '推薦',
|
||||
recent: '最近使用',
|
||||
all_types: '全部類型',
|
||||
all_source: '全部來源'
|
||||
},
|
||||
data_set: {
|
||||
ten_wan: '10萬',
|
||||
@ -1868,7 +1880,8 @@ export default {
|
||||
zoom_level: '縮放等級',
|
||||
central_point: '中心點',
|
||||
full_display: '全量顯示',
|
||||
show_hover_style: '顯示鼠標懸浮樣式'
|
||||
show_hover_style: '顯示鼠標懸浮樣式',
|
||||
merge_cells: '合並單元格'
|
||||
},
|
||||
dataset: {
|
||||
scope_edit: '僅編輯時生效',
|
||||
@ -2140,7 +2153,7 @@ export default {
|
||||
calc_tips: {
|
||||
tip1: '表達式語法請遵循calcite語法。',
|
||||
tip1_1: '表達式語法請遵循該數據源對應的數據庫語法。',
|
||||
tip2: '聚合運算僅能在圖表中生效。',
|
||||
tip2: '聚合運算僅能在圖表中生效。在預覽時顯示為"-"',
|
||||
tip3: '引用字段以 "[" 開始, "]" 結束',
|
||||
tip4: '請勿修改引用內容,否則將引用失敗',
|
||||
tip5: '若輸入與引用字段相同格式的內容,將被當作引用字段處理',
|
||||
@ -2603,6 +2616,8 @@ export default {
|
||||
enter_name_tips: '請輸入儀表板名稱',
|
||||
name: '名稱',
|
||||
apply_template: '應用模板',
|
||||
style_template: '樣式模板',
|
||||
all_type: '全部分類',
|
||||
enter_template_name_tips: '搜索模板名稱',
|
||||
pic_adaptation: '適應組件',
|
||||
pic_equiratio: '等比適應',
|
||||
@ -2949,7 +2964,14 @@ export default {
|
||||
pvp: '密碼有效期',
|
||||
defaultLogin: '默認登錄方式',
|
||||
shareDisable: '禁用分享',
|
||||
sharePeRequire: '分享有效期密碼必填'
|
||||
sharePeRequire: '分享有效期密碼必填',
|
||||
defaultSort: '資源默認排序方式'
|
||||
},
|
||||
resource_sort: {
|
||||
time_asc: '按創建時間升序',
|
||||
time_desc: '按創建時間降序',
|
||||
name_asc: '按名稱升序',
|
||||
name_desc: '按名稱降序'
|
||||
},
|
||||
setting_email: {
|
||||
title: '郵件設置',
|
||||
@ -2963,7 +2985,7 @@ export default {
|
||||
},
|
||||
sync_manage: {
|
||||
title: '同步管理',
|
||||
ds_search_placeholder: '搜索名稱,描述'
|
||||
ds_search_placeholder: '搜尋名稱或描述'
|
||||
},
|
||||
sync_datasource: {
|
||||
title: '數據連接管理',
|
||||
@ -2976,18 +2998,127 @@ export default {
|
||||
type: '類型',
|
||||
status: '狀態',
|
||||
create_time: '創建時間',
|
||||
update_time: '更新時間',
|
||||
update_time: '更新时间',
|
||||
operation: '操作',
|
||||
edit: '編輯',
|
||||
delete: '刪除',
|
||||
confirm_batch_delete_target_ds: '確定刪除{0}個目標數據源嗎?',
|
||||
confirm_batch_delete_source_ds: '確定刪除{0}個源數據源嗎?'
|
||||
confirm_batch_delete_source_ds: '確定刪除{0}個源數據源嗎?',
|
||||
recently_created: '最近創建',
|
||||
has_running_task_msg:
|
||||
'執行中的任務完成後,將繼續使用修改之前的配置進行同步,需手動對任務進行重新保存。',
|
||||
edit_datasource: '編輯數據源',
|
||||
add_datasource: '新建數據源',
|
||||
config_info: '配置信息',
|
||||
ds_type: '數據源類型',
|
||||
valid: '有效',
|
||||
invalid: '無效',
|
||||
start_time: '開始時間',
|
||||
end_time: '結束時間',
|
||||
ds_delete_confirm: '確定刪除該數據源嗎?',
|
||||
datasource: '數據源',
|
||||
select_folder: '請選擇文件夾',
|
||||
sync_ds: '同步數據源',
|
||||
sync_to_datasource: '將同步至數據準備的數據源列表',
|
||||
input_ds_name: '請輸入數據源名稱',
|
||||
folder: '所屬文件夾',
|
||||
cancel: '取消',
|
||||
save: '儲存',
|
||||
next: '下一步',
|
||||
prev: '上一步',
|
||||
validate: '驗證',
|
||||
validate_success: '驗證成功',
|
||||
select_type: '请选择數據源類型',
|
||||
extra_params: '額外的 JDBC 連線字串',
|
||||
remark: '備註',
|
||||
input_name: '請輸入名稱',
|
||||
input_limit_2_25: '{0}-{1}字符',
|
||||
input_limit_2_50: '2-50字符',
|
||||
input_limit_2_64: '2-64字符',
|
||||
input_limit_1_64: '1-64字符',
|
||||
data_source_configuration: '數據源配置',
|
||||
data_source_table: '數據源表',
|
||||
auth_method: '認證方式',
|
||||
passwd: '用戶名和密碼',
|
||||
kerbers_info: '請確保 krb5.conf 和 Keytab Key 已經添加到路徑:/opt/dataease2.0/conf',
|
||||
client_principal: '客戶端主體',
|
||||
keytab_Key_path: 'Keytab Key 路徑',
|
||||
data_base: '數據庫名稱',
|
||||
user_name: '用戶名',
|
||||
password: '密碼',
|
||||
host: '主機名/IP地址',
|
||||
doris_host: 'Doris 地址',
|
||||
query_port: '查詢端口',
|
||||
http_port: 'HTTP 端口',
|
||||
port: '端口',
|
||||
datasource_url: '地址',
|
||||
please_input_datasource_url: '請輸入 Elasticsearch 地址,如: http://es_host:es_port',
|
||||
please_input_data_base: '請輸入數據庫名稱',
|
||||
please_input_jdbc_url: '請輸入 JDBC 連接',
|
||||
please_select_oracle_type: '選擇連接類型',
|
||||
please_input_user_name: '請輸入用戶名',
|
||||
please_input_password: '請輸入密碼',
|
||||
please_input_host: '請輸入主機',
|
||||
please_input_url: '請輸入URL地址',
|
||||
please_input_port: '請輸入端口',
|
||||
please_input_be_port: '請輸入 BE 端口',
|
||||
modify: '編輯數據源',
|
||||
validate_failed: '驗證失敗',
|
||||
oracle_connection_type: '服務名/SID',
|
||||
oracle_sid: 'SID',
|
||||
oracle_service_name: '服務名',
|
||||
get_schema: '獲取 Schema',
|
||||
schema: 'Schema',
|
||||
charset: '字符集',
|
||||
targetCharset: '目標字符集',
|
||||
please_choose_schema: '請選擇數據庫 Schema',
|
||||
please_choose_charset: '請選擇數據庫字符集',
|
||||
please_choose_targetCharset: '請選擇目標字符集',
|
||||
edit_datasource_msg: '修改數據源信息,可能會導致該數據源下的數據集不可用,確認修改?',
|
||||
repeat_datasource_msg: '已經存在相同配置的數據源信息。',
|
||||
in_valid: '無效數據源',
|
||||
initial_pool_size: '初始連接數',
|
||||
min_pool_size: '最小連接數',
|
||||
max_pool_size: '最大連接數',
|
||||
max_idle_time: '最大空閒(秒)',
|
||||
bucket_num: 'Bucket 數量',
|
||||
replication_num: '副本數量',
|
||||
please_input_bucket_num: '請輸入 Bucket 數量',
|
||||
please_input_replication_num: '請輸入副本數量',
|
||||
acquire_increment: '增長數',
|
||||
connect_timeout: '連接超時(秒)',
|
||||
please_input_initial_pool_size: '請輸入初始連接數',
|
||||
please_input_min_pool_size: '請輸入最小連接數',
|
||||
please_input_max_pool_size: '請輸入最大連接數',
|
||||
please_input_max_idle_time: '請輸入最大空閒(秒)',
|
||||
please_input_acquire_increment: '請輸入增長數',
|
||||
please_input_query_timeout: '請輸入查詢超時',
|
||||
please_input_connect_timeout: '請輸入連接超時(秒)',
|
||||
no_less_then_0: '高級設置中的參數不能小於零',
|
||||
port_no_less_then_0: '端口不能小於零',
|
||||
priority: '高級設置',
|
||||
jdbcUrl: 'JDBC 連接',
|
||||
_ip_address: '請輸入主機名/IP地址',
|
||||
display_name: '顯示名稱',
|
||||
connection_mode: '連接方式',
|
||||
please_select: '請選擇',
|
||||
query_timeout: '查询超时',
|
||||
description: '描述',
|
||||
tips: '提示'
|
||||
},
|
||||
sync_summary: {
|
||||
summary: '概覽',
|
||||
data_source_number: '數據源數量',
|
||||
task_number: '任務數量',
|
||||
execution_count: '執行次數',
|
||||
execution_results_in_the_past_7_days: '過去7天執行情況',
|
||||
sync_status_distribution: '同步狀態分佈'
|
||||
},
|
||||
sync_task: {
|
||||
title: '任務管理',
|
||||
list: '任務列表',
|
||||
log_list: '任務日志',
|
||||
add_task: '添加任務',
|
||||
task_list: '任務列表',
|
||||
log_list: '任務日誌',
|
||||
add_task: '新增任務',
|
||||
name: '名稱',
|
||||
desc: '描述',
|
||||
status: '狀態',
|
||||
@ -3010,17 +3141,158 @@ export default {
|
||||
status_done: '任務結束',
|
||||
status_terminated: '終止',
|
||||
status_connection_lost: '連接丟失',
|
||||
log: '日志',
|
||||
show_log: '查看日志',
|
||||
log: '日誌',
|
||||
show_log: '查看日誌',
|
||||
last_execute_result: '上次執行結果',
|
||||
execute_result: '執行結果',
|
||||
task_status: '任務狀態',
|
||||
sync: '同步',
|
||||
target_table: '目標表',
|
||||
batch_del: '批量刪除',
|
||||
selection_info: '已選 {0} 項',
|
||||
selection_info: '已選擇 {0} 項',
|
||||
clear_button: '清空',
|
||||
task_text: '任務'
|
||||
task_text: '任務',
|
||||
hour: '小時',
|
||||
day: '天',
|
||||
week: '週',
|
||||
month: '月',
|
||||
year: '年',
|
||||
minute: '分鐘',
|
||||
second: '秒',
|
||||
hour_minute_second: '時:分:秒',
|
||||
please_enter_task_name: '請輸入任務名稱',
|
||||
input_limit_255: '長度不能超過255個字符',
|
||||
please_enter: '請輸入',
|
||||
please_cron: '請輸入有效的Cron表達式',
|
||||
please_choose: '請選擇',
|
||||
please_choose_start_time: '請選擇開始時間',
|
||||
please_choose_end_time: '請選擇結束時間',
|
||||
end_time_must_be_later_than_start_time: '結束時間必須晚於開始時間',
|
||||
please_choose_database_type: '請選擇數據庫類型',
|
||||
please_choose_database: '請選擇數據庫',
|
||||
please_choose_table: '請選擇表格',
|
||||
please_enter_sql: '請輸入SQL',
|
||||
please_choose_incremental_field: '請選擇增量字段',
|
||||
please_enter_table_name: '請輸入表名',
|
||||
input_limit_64: '長度不能超過64個字符',
|
||||
must_be_met_the_table_name: '表名必須以字母開頭,並且只能包含字母、數字和下劃線',
|
||||
please_choose_partition_type: '請選擇分區類型',
|
||||
please_enter_end_offset: '請輸入結束偏移',
|
||||
please_choose_partition_interval_unit: '請選擇分區間隔單位',
|
||||
please_enter_partition_column_value: '請輸入分區列值',
|
||||
input_limit_4096: '長度不能超過4096個字符',
|
||||
please_enter_starting_value: '請輸入起始數值',
|
||||
please_enter_end_value: '請輸入結束數值',
|
||||
please_enter_numerical_range_interval: '請輸入數值範圍間隔',
|
||||
please_choose_time_range: '請選擇時間範圍',
|
||||
edit_success: '修改成功',
|
||||
add_success: '新增成功',
|
||||
target_database_status_is_abnormal: '目標數據庫狀態異常',
|
||||
edit_task: '編輯任務',
|
||||
basic_information: '基本信息',
|
||||
source_database: '源數據庫',
|
||||
target_database: '目標數據庫',
|
||||
task_time_out_time: '任務超時時間(秒)',
|
||||
effective_if_greater_than_0: '單位秒,大於0時生效',
|
||||
retry_attempts_on_failure: '失敗重試次數',
|
||||
sync_frequency: '同步頻率',
|
||||
sync_immediately: '立即同步',
|
||||
sync_cron: '表達式設置',
|
||||
sync_fixed_frequency: '固定頻率',
|
||||
cron_expression: 'Cron表達式',
|
||||
each: '每',
|
||||
sync_once: '同步一次',
|
||||
confirm: '確認',
|
||||
msg_get_database_table_failed: '獲取數據庫表格失敗',
|
||||
msg_source_database_status_is_abnormal: '源數據庫狀態異常',
|
||||
database: '數據庫',
|
||||
database_type: '類型',
|
||||
query_method: '查詢方式',
|
||||
please_choose_data_extraction_method: '請選擇數據抽取方式',
|
||||
table: '表格',
|
||||
sql_tip_1:
|
||||
'此方式在獲取列類型的長度或精度時,並不總是返回用戶設置的精確長度或精度,但它仍然可以作為一個參考值,用於確定結果集中每列的最大顯示長度。',
|
||||
sql_tip_2:
|
||||
'若需要獲得更精確的列類型長度和精度,請使用庫表方式,或在下一步中的字段映射中進行長度精度的設置。',
|
||||
please_enter_sql: '請輸入查詢SQL',
|
||||
msg_confirm_delete_field: '確定刪除該字段嗎?',
|
||||
source_field: '源字段',
|
||||
field_type: '類型',
|
||||
field_length: '長度',
|
||||
field_precision: '精度',
|
||||
field_key: '鍵',
|
||||
field_index: '索引',
|
||||
field_comment: '注釋',
|
||||
confirm_delete_field: '確定刪除字段 {0} 嗎?',
|
||||
msg_field_list_empty_tip: '字段列表不能為空,且不能包含名稱為空或類型為UNKNOWN的數據,請檢查',
|
||||
next_week: '未來一週',
|
||||
next_month: '未來一個月',
|
||||
next_three_month: '未來三個月',
|
||||
must_be_start_less_end: '數值範圍結束數值必須大於起始數值',
|
||||
must_be_partition_interval_greater_than_0: '分區間隔必須大於0',
|
||||
must_be_partition_interval_less_end_start_difference:
|
||||
'分區間隔必須小於結束數值與起始數值的差值',
|
||||
date: '日期',
|
||||
list: '列',
|
||||
number: '數值',
|
||||
define_mapping_field: '定義映射字段',
|
||||
target_database_type: '目標數據庫類型',
|
||||
delete_field: '刪除字段',
|
||||
add_field: '新增字段',
|
||||
edit_field: '編輯字段',
|
||||
add_all_field: '新增所有字段',
|
||||
fault_tolerance_rate: '容錯率',
|
||||
fault_tolerance_rate_tip:
|
||||
'0~1,默認為0,即表示同步批次數據有一條錯誤數據時,整個批次的導入任務將會失敗。',
|
||||
incremental_sync: '增量同步',
|
||||
incremental_sync_tip_1: '全量:全量覆蓋同步',
|
||||
incremental_sync_tip_2: '增量:根據增量字段增量同步,增量字段必須是整型或時間類型',
|
||||
incremental_field: '增量字段',
|
||||
enable_partition: '啟用分區',
|
||||
enable_partition_tip: '啟用分區,字段列表不能有空值',
|
||||
partition_type: '分區類型',
|
||||
partition_field: '分區字段',
|
||||
on: '啟用',
|
||||
off: '關閉',
|
||||
picker_to: '至',
|
||||
picker_start: '開始',
|
||||
picker_end: '截止',
|
||||
end_offset: '結束偏移',
|
||||
number_range: '數值範圍',
|
||||
partition_interval: '分區間隔',
|
||||
partition_column_value: '分區列值',
|
||||
partition_column_value_placeholder: '分區格式為: p1:"v1","v2","v3";p2:"v1","v2"',
|
||||
partition_interval_unit: '分區間隔單位',
|
||||
input_limit: '長度不能超過 {0} 個字符',
|
||||
cannot_begin_with_number: '字段名稱不能以數字開頭',
|
||||
duplicate_field_tip: '重複字段 [{0}],同一源字段不能映射多次',
|
||||
duplicate_name_error: '名稱重複 [{0}]',
|
||||
confirm_batch_delete: '確定批量刪除任務',
|
||||
op_success: '操作成功',
|
||||
search_input_name_desc_placeholder: '搜索名稱、描述',
|
||||
confirm_delete_msg: '確定刪除?',
|
||||
target_table_info: '目標表資訊',
|
||||
confirm_clear_msg: '確定清理 {0} 嗎?',
|
||||
clear: '清理',
|
||||
op_success_refresh: '操作成功,請稍後刷新',
|
||||
execute_time: '執行時間',
|
||||
clear_log: '清理日誌',
|
||||
search_input_name_id_placeholder: '搜尋名稱或ID',
|
||||
log_id: '日誌ID',
|
||||
op: '操作',
|
||||
view_execute_log: '查看執行日誌',
|
||||
submit_true: '確定',
|
||||
please_choose_clear_method: '請選擇清理方式',
|
||||
last_1_days_log: '1 天前的日誌',
|
||||
last_1_weeks_log: '1 週前的日誌',
|
||||
last_1_months_log: '1 個月前的日誌',
|
||||
last_3_months_log: '3 個月前的日誌',
|
||||
last_6_months_log: '6 個月前的日誌',
|
||||
last_1_years_log: '1 年前的日誌',
|
||||
execute_log: '執行日誌',
|
||||
done: '完成',
|
||||
connection_lost: '連接斷開',
|
||||
task_name: '任務名稱'
|
||||
},
|
||||
watermark: {
|
||||
support_params: '當前支持的參數:',
|
||||
|
||||
@ -11,6 +11,7 @@ export default {
|
||||
add_component_hint: '点击或拖拽左侧组件添加字段'
|
||||
},
|
||||
inputText: '请输入',
|
||||
selectText: '请选择',
|
||||
add: '添加',
|
||||
account: '账号',
|
||||
email: '邮箱',
|
||||
@ -122,7 +123,11 @@ export default {
|
||||
delete_catalog_hint: '确定删除该分类吗?',
|
||||
delete_catalog_tip: '删除后不可恢复,是否继续?',
|
||||
illegal_name_hint: '不合法命名,请更换!',
|
||||
exists_name_hint: '当前名称已在模版管理中存在,请修改'
|
||||
exists_name_hint: '当前名称已在模版管理中存在,请修改',
|
||||
get_download_link_hint: '未获取模板下载链接请联系模板市场官方',
|
||||
search_result_count: '的搜索结果是 {0} 个',
|
||||
template_center: '模版中心',
|
||||
preview: '预览'
|
||||
},
|
||||
work_branch: {
|
||||
back_to_work_branch: '返回工作台',
|
||||
@ -137,6 +142,7 @@ export default {
|
||||
last_edited_by: '最近编辑人',
|
||||
last_edit_time: '最近编辑时间',
|
||||
big_data_screen: '数据大屏',
|
||||
big_screen: '大屏',
|
||||
dashboard: '仪表板',
|
||||
data_set: '数据集',
|
||||
data_source: '数据源',
|
||||
@ -161,7 +167,13 @@ export default {
|
||||
error_link_hint: '链接格式错误,请重新填写!',
|
||||
password_null_hint: '密码不能为空,请重新输入!',
|
||||
password_hint: '密码必须是包含数字、字母、特殊字符[!@#$%^&*()_+]的4-10位字符串',
|
||||
max_ticket_count: '最多支持创建5个Ticket'
|
||||
max_ticket_count: '最多支持创建5个Ticket',
|
||||
last: '上一个',
|
||||
next: '下一个',
|
||||
recommend: '推荐',
|
||||
recent: '最近使用',
|
||||
all_types: '全部类型',
|
||||
all_source: '全部来源'
|
||||
},
|
||||
data_set: {
|
||||
ten_wan: '10万',
|
||||
@ -1868,7 +1880,8 @@ export default {
|
||||
zoom_level: '缩放等级',
|
||||
central_point: '中心点',
|
||||
full_display: '全量显示',
|
||||
show_hover_style: '显示鼠标悬浮样式'
|
||||
show_hover_style: '显示鼠标悬浮样式',
|
||||
merge_cells: '合并单元格'
|
||||
},
|
||||
dataset: {
|
||||
scope_edit: '仅编辑时生效',
|
||||
@ -2140,7 +2153,7 @@ export default {
|
||||
calc_tips: {
|
||||
tip1: '表达式语法请遵循calcite语法。',
|
||||
tip1_1: '表达式语法请遵循该数据源对应的数据库语法。',
|
||||
tip2: '聚合运算仅能在图表中生效。',
|
||||
tip2: '聚合运算仅能在图表中生效。在预览时显示为"-"',
|
||||
tip3: '引用字段以 "[" 开始, "]" 结束',
|
||||
tip4: '请勿修改引用内容,否则将引用失败',
|
||||
tip5: '若输入与引用字段相同格式的内容,将被当作引用字段处理',
|
||||
@ -2540,6 +2553,98 @@ export default {
|
||||
sql_variable: {
|
||||
variable_mgm: '参数设置'
|
||||
},
|
||||
v_query: {
|
||||
the_minimum_value: '数值区间最大值必须大于最小值',
|
||||
before_querying: '查询条件是必填项,请设置选项值后,再进行查询!',
|
||||
here_or_click: '将右侧的字段拖拽到这里 或 点击',
|
||||
add_query_condition: '添加查询条件',
|
||||
set_filter_condition: '设置过滤条件',
|
||||
delete_condition: '删除条件',
|
||||
last_3_months: '最近 3 个 月',
|
||||
last_6_months: '最近 6 个 月',
|
||||
last_12_months: '最近 12 个 月',
|
||||
last_3_days: '最近 3 天',
|
||||
month_to_date: '月初至今',
|
||||
year_to_date: '年初至今',
|
||||
exact_match: '精确匹配',
|
||||
fuzzy_match: '模糊匹配',
|
||||
option_type: '选项类型',
|
||||
time_filter_range: '设置时间筛选范围',
|
||||
configured: '已配置',
|
||||
is_not_supported: '绑定参数后,不支持传空数据',
|
||||
contains_empty_data: '选项值包含空数据',
|
||||
unnamed: '未命名',
|
||||
cannot_be_empty: '查询条件或字段不能为空',
|
||||
the_first_level: '第一级无需配置被级联字段',
|
||||
configure_cascaded_fields: '与上一级使用同一个数据集,无需配置被级联字段',
|
||||
condition_cascade_configuration: '查询条件级联配置',
|
||||
not_reverse_cascade: '(仅上级能级联下级,不可反向级联)',
|
||||
must_be_met: '基于当前查询组件的查询条件,如果需要进行级联配置,需要满足以下条件:',
|
||||
select_data_set: '1. 展示类型:文本下拉组件和数字下拉组件;2. 选项值来源:选择数据集',
|
||||
add_cascade_configuration: '添加级联配置',
|
||||
add_cascade_condition: '添加级联条件',
|
||||
query_condition_level: '查询条件层级',
|
||||
select_query_condition: '请选择查询条件',
|
||||
select_cascaded_field: '请选择被级联字段',
|
||||
level_1: '第{msg}级',
|
||||
to_modify_it: '数据集的修改,会导致级联配置失效,因此对应的级联关系将被清除,确定修改吗?',
|
||||
be_linked_first: '请先勾选需要联动的图表及字段',
|
||||
cannot_be_performed: '所选字段类型不一致,无法进行查询配置',
|
||||
numerical_parameter_configuration: '数值参数配置必须配置最大值和最小值',
|
||||
format_is_inconsistent: '时间格式不一致',
|
||||
cannot_be_empty_de: '查询条件为必填项,默认值不能为空',
|
||||
the_start_time: '结束时间必须大于开始时间!',
|
||||
and_end_time: '时间参数配置必须配置开始时间和结束时间',
|
||||
cannot_be_empty_time: '默认时间不能为空!',
|
||||
range_please_reset: '默认值超出日期筛选范围内,请重新设置!',
|
||||
cannot_be_empty_input: '手工输入-选项值不能为空',
|
||||
option_value_field: '请选择数据集及选项值字段',
|
||||
the_data_set: '请选择数据集的选项值字段',
|
||||
cannot_be_empty_name: '字段名称不能为空',
|
||||
query_condition_setting: '查询条件设置',
|
||||
query_condition: '查询条件',
|
||||
chart_and_field: '选择关联图表及字段',
|
||||
be_switched_to: '注意:自动模式支持同数据集自动关联字段,可切换到',
|
||||
to_automatic_again: '自定义模式。切换到自定义模式后无法再切换为自动!',
|
||||
as_query_conditions: '脱敏字段,不能被设置为查询条件',
|
||||
query_condition_configuration: '查询条件配置',
|
||||
required_items: '必填项',
|
||||
display_type: '展示类型',
|
||||
text_drop_down: '文本下拉',
|
||||
text_search: '文本搜索',
|
||||
drop_down_tree: '下拉树',
|
||||
number_drop_down: '数字下拉',
|
||||
number_range: '数值区间',
|
||||
of_option_values: '选项值数量',
|
||||
tree_structure_design: '下拉树结构设计',
|
||||
the_tree_structure: '点击进行树结构设计',
|
||||
time_granularity: '时间粒度',
|
||||
the_time_granularity: '请选择时间粒度',
|
||||
option_value_source: '选项值来源',
|
||||
manual_input: '手动输入',
|
||||
query_field: '查询字段',
|
||||
display_field: '显示字段',
|
||||
the_sorting_field: '请选择排序字段',
|
||||
condition_type: '条件类型',
|
||||
single_condition: '单条件',
|
||||
with_condition: '与条件',
|
||||
or_condition: '或条件',
|
||||
hide_condition_switch: '隐藏条件切换',
|
||||
cannot_be_displayed: '图表所使用的数据集不同, 无法展示配置项',
|
||||
component_cascade_configuration: '查询组件级联配置',
|
||||
time_type: '时间类型',
|
||||
start_at: '开始于',
|
||||
end_at: '结束于',
|
||||
time_interval: '时间区间',
|
||||
interval_type: '区间类型',
|
||||
query_time_window: '动态查询时间窗口',
|
||||
maximum_single_query: '单次查询最多',
|
||||
empty_data: '空数据',
|
||||
time_selection: '时间选择',
|
||||
select_a_field: '层级字段不能为空,请选择字段!',
|
||||
add_level: '添加层级',
|
||||
tree_query_field: '下拉树查询字段'
|
||||
},
|
||||
panel: {
|
||||
column_name: '字段名称'
|
||||
},
|
||||
@ -2603,6 +2708,8 @@ export default {
|
||||
enter_name_tips: '请输入仪表板名称',
|
||||
name: '名称',
|
||||
apply_template: '应用模板',
|
||||
style_template: '样式模板',
|
||||
all_type: '全部分类',
|
||||
enter_template_name_tips: '搜索模板名称',
|
||||
pic_adaptation: '适应组件',
|
||||
pic_equiratio: '等比适应',
|
||||
@ -2949,7 +3056,14 @@ export default {
|
||||
pvp: '密码有效期',
|
||||
defaultLogin: '默认登录方式',
|
||||
shareDisable: '禁用分享',
|
||||
sharePeRequire: '分享有效期密码必填'
|
||||
sharePeRequire: '分享有效期密码必填',
|
||||
defaultSort: '资源默认排序方式'
|
||||
},
|
||||
resource_sort: {
|
||||
time_asc: '按创建时间升序',
|
||||
time_desc: '按创建时间降序',
|
||||
name_asc: '按名称升序',
|
||||
name_desc: '按名称降序'
|
||||
},
|
||||
setting_email: {
|
||||
title: '邮件设置',
|
||||
@ -2981,11 +3095,120 @@ export default {
|
||||
edit: '编辑',
|
||||
delete: '删除',
|
||||
confirm_batch_delete_target_ds: '确定删除{0}个目标数据源吗?',
|
||||
confirm_batch_delete_source_ds: '确定删除{0}个源数据源吗?'
|
||||
confirm_batch_delete_source_ds: '确定删除{0}个源数据源吗?',
|
||||
recently_created: '最近创建',
|
||||
has_running_task_msg:
|
||||
'执行中的任务完成后,将继续使用修改之前的配置进行同步,需手动对任务进行重新保存。',
|
||||
edit_datasource: '编辑数据源',
|
||||
add_datasource: '新建数据源',
|
||||
config_info: '配置信息',
|
||||
ds_type: '数据源类型',
|
||||
valid: '有效',
|
||||
invalid: '无效',
|
||||
start_time: '开始时间',
|
||||
end_time: '结束时间',
|
||||
ds_delete_confirm: '确定删除该数据源吗?',
|
||||
datasource: '数据源',
|
||||
select_folder: '请选择文件夹',
|
||||
sync_ds: '同步数据源',
|
||||
sync_to_datasource: '将同步至数据准备的数据源列表',
|
||||
input_ds_name: '请输入数据源名称',
|
||||
folder: '所属文件夹',
|
||||
cancel: '取消',
|
||||
save: '保存',
|
||||
next: '下一步',
|
||||
prev: '上一步',
|
||||
validate: '校验',
|
||||
validate_success: '校验成功',
|
||||
select_type: '请选择数据源类型',
|
||||
extra_params: '额外的 JDBC 连接字符串',
|
||||
remark: '备注',
|
||||
input_name: '请输入名称',
|
||||
input_limit_2_25: '{0}-{1}字符',
|
||||
input_limit_2_50: '2-50字符',
|
||||
input_limit_2_64: '2-64字符',
|
||||
input_limit_1_64: '1-64字符',
|
||||
data_source_configuration: '数据源配置',
|
||||
data_source_table: '数据源表',
|
||||
auth_method: '认证方式',
|
||||
passwd: '用户名密码',
|
||||
kerbers_info: '请确保 krb5.Conf、Keytab Key,已经添加到路径:/opt/dataease2.0/conf',
|
||||
client_principal: 'Client Principal',
|
||||
keytab_Key_path: 'Keytab Key Path',
|
||||
data_base: '数据库名称',
|
||||
user_name: '用户名',
|
||||
password: '密码',
|
||||
host: '主机名/IP地址',
|
||||
doris_host: 'Doris 地址',
|
||||
query_port: 'Query Port',
|
||||
http_port: 'Http Port',
|
||||
port: '端口',
|
||||
datasource_url: '地址',
|
||||
please_input_datasource_url: '请输入 Elasticsearch 地址,如: http://es_host:es_port',
|
||||
please_input_data_base: '请输入数据库名称',
|
||||
please_input_jdbc_url: '请输入 JDBC 连接',
|
||||
please_select_oracle_type: '选择连接类型',
|
||||
please_input_user_name: '请输入用户名',
|
||||
please_input_password: '请输入密码',
|
||||
please_input_host: '请输入主机',
|
||||
please_input_url: '请输入URL地址',
|
||||
please_input_port: '请输入端口',
|
||||
please_input_be_port: '请输入BE端口',
|
||||
modify: '编辑数据源',
|
||||
validate_failed: '校验失败',
|
||||
oracle_connection_type: '服务名/SID',
|
||||
oracle_sid: 'SID',
|
||||
oracle_service_name: '服务名',
|
||||
get_schema: '获取 Schema',
|
||||
schema: 'Schema',
|
||||
charset: '字符集',
|
||||
targetCharset: '目标字符集',
|
||||
please_choose_schema: '请选择数据库 Schema',
|
||||
please_choose_charset: '请选择数据库字符集',
|
||||
please_choose_targetCharset: '请选择目标字符集',
|
||||
edit_datasource_msg: '修改数据源信息,可能会导致该数据源下的数据集不可用,确认修改?',
|
||||
repeat_datasource_msg: '已经存在相同配置的数据源信息, ',
|
||||
in_valid: '无效数据源',
|
||||
initial_pool_size: '初始连接数',
|
||||
min_pool_size: '最小连接数',
|
||||
max_pool_size: '最大连接数',
|
||||
max_idle_time: '最大空闲(秒)',
|
||||
bucket_num: 'Bucket 数量',
|
||||
replication_num: '副本数量',
|
||||
please_input_bucket_num: '请输入 Bucket 数量',
|
||||
please_input_replication_num: '请输入副本数量',
|
||||
acquire_increment: '增长数',
|
||||
connect_timeout: '连接超时(秒)',
|
||||
please_input_initial_pool_size: '请输入初始连接数',
|
||||
please_input_min_pool_size: '请输入最小连接数',
|
||||
please_input_max_pool_size: '请输入最大连接数',
|
||||
please_input_max_idle_time: '请输入最大空闲(秒)',
|
||||
please_input_acquire_increment: '请输入增长数',
|
||||
please_input_query_timeout: '请输入查询超时',
|
||||
please_input_connect_timeout: '请输入连接超时(秒)',
|
||||
no_less_then_0: '高级设置中的参数不能小于零',
|
||||
port_no_less_then_0: '端口不能小于零',
|
||||
priority: '高级设置',
|
||||
jdbcUrl: 'JDBC 连接',
|
||||
_ip_address: '请输入主机名/IP地址',
|
||||
display_name: '显示名称',
|
||||
connection_mode: '连接方式',
|
||||
please_select: '请选择',
|
||||
query_timeout: '查询超时',
|
||||
description: '描述',
|
||||
tips: '提示'
|
||||
},
|
||||
sync_summary: {
|
||||
summary: '概览',
|
||||
data_source_number: '数据源数量',
|
||||
task_number: '任务数量',
|
||||
execution_count: '执行次数',
|
||||
execution_results_in_the_past_7_days: '过去7天执行情况',
|
||||
sync_status_distribution: '同步状态分布'
|
||||
},
|
||||
sync_task: {
|
||||
title: '任务管理',
|
||||
list: '任务列表',
|
||||
task_list: '任务列表',
|
||||
log_list: '任务日志',
|
||||
add_task: '添加任务',
|
||||
name: '名称',
|
||||
@ -3020,7 +3243,148 @@ export default {
|
||||
batch_del: '批量删除',
|
||||
selection_info: '已选 {0} 项',
|
||||
clear_button: '清空',
|
||||
task_text: '任务'
|
||||
task_text: '任务',
|
||||
hour: '小时',
|
||||
day: '天',
|
||||
week: '周',
|
||||
month: '月',
|
||||
year: '年',
|
||||
minute: '分钟',
|
||||
second: '秒',
|
||||
hour_minute_second: '时:分:秒',
|
||||
please_enter_task_name: '请输入任务名称',
|
||||
input_limit_255: '长度不能超过255个字符',
|
||||
please_enter: '请输入',
|
||||
please_cron: '请输入可用的Cron表达式:',
|
||||
please_choose: '请选择',
|
||||
please_choose_start_time: '请选择开始时间',
|
||||
please_choose_end_time: '请选择结束时间',
|
||||
end_time_must_be_later_than_start_time: '结束时间必须大于开始时间!',
|
||||
please_choose_database_type: '请选择数据库类型',
|
||||
please_choose_database: '请选择数据库',
|
||||
please_choose_table: '请选择表',
|
||||
please_enter_sql: '请输入SQL',
|
||||
please_choose_incremental_field: '请选择增量字段',
|
||||
please_enter_table_name: '请输入表名',
|
||||
input_limit_64: '长度不能超过64个字符',
|
||||
must_be_met_the_table_name: '必须以字母开头,并且只能包含字母、数字、下划线',
|
||||
please_choose_partition_type: '请选择分区类型',
|
||||
please_enter_end_offset: '请输入结束偏移度',
|
||||
please_choose_partition_interval_unit: '请选择分区间隔的单位',
|
||||
please_enter_partition_column_value: '请输入分区列值',
|
||||
input_limit_4096: '长度不能超过4096个字符',
|
||||
please_enter_starting_value: '请输入起始数值',
|
||||
please_enter_end_value: '请输入结束数值',
|
||||
please_enter_numerical_range_interval: '请输入数值分区间隔',
|
||||
please_choose_time_range: '请选择时间范围',
|
||||
edit_success: '修改成功',
|
||||
add_success: '添加成功',
|
||||
target_database_status_is_abnormal: '目标数据库状态异常',
|
||||
edit_task: '编辑任务',
|
||||
basic_information: '基本信息',
|
||||
source_database: '源数据库',
|
||||
target_database: '目标数据库',
|
||||
task_time_out_time: '任务超时时间(秒)',
|
||||
effective_if_greater_than_0: '单位秒,大于0时生效',
|
||||
retry_attempts_on_failure: '失败重试次数',
|
||||
sync_frequency: '同步频率',
|
||||
sync_immediately: '立即同步',
|
||||
sync_cron: '表达式设定',
|
||||
sync_fixed_frequency: '固定频率',
|
||||
cron_expression: 'Cron表达式',
|
||||
each: '每',
|
||||
sync_once: '同步一次',
|
||||
confirm: '确认',
|
||||
msg_get_database_table_failed: '获取数据库表失败',
|
||||
msg_source_database_status_is_abnormal: '源数据库状态异常',
|
||||
database: '数据库',
|
||||
database_type: '类型',
|
||||
query_method: '查询方式',
|
||||
please_choose_data_extraction_method: '请选择数据抽取方式',
|
||||
table: '表',
|
||||
sql_tip_1:
|
||||
'该方式在获取列类型的长度或者精度时,并不总是返回用户设置的精确和长度,但它仍然可以作为一个参考值,用于确定结果集中每列的最大显示长度。',
|
||||
sql_tip_2:
|
||||
'如需获取更精确的列类型长度精度,请使用库表方式,或者在下一步中的字段映射中进行长度精度的设置。',
|
||||
please_enter_sql: '请输入查询SQL',
|
||||
msg_confirm_delete_field: '确定删除该字段?',
|
||||
source_field: '源字段',
|
||||
field_type: '类型',
|
||||
field_length: '长度',
|
||||
field_precision: '精度',
|
||||
field_key: '键',
|
||||
field_index: '索引',
|
||||
field_comment: '注释',
|
||||
confirm_delete_field: '确定删除 {0} 字段?',
|
||||
msg_field_list_empty_tip:
|
||||
'字段列表不能为空,不能存在名称为空或者字段类型为UNKNOWN的数据,请检查',
|
||||
next_week: '未来一周',
|
||||
next_month: '未来一个月',
|
||||
next_three_month: '未来三个月',
|
||||
must_be_start_less_end: '数值范围结束数值必须大于起始数值',
|
||||
must_be_partition_interval_greater_than_0: '分区间隔必须大于0',
|
||||
must_be_partition_interval_less_end_start_difference: '分区间隔必须小于结束数值与起始数值差值',
|
||||
date: '日期',
|
||||
list: '列',
|
||||
number: '数值',
|
||||
define_mapping_field: '定义映射字段',
|
||||
target_database_type: '目标数据库类型',
|
||||
delete_field: '删除字段',
|
||||
add_field: '添加字段',
|
||||
edit_field: '编辑字段',
|
||||
add_all_field: '添加所有字段',
|
||||
fault_tolerance_rate: '容错率',
|
||||
fault_tolerance_rate_tip:
|
||||
'0~1,默认为0,即表示同步批次数据有一条错误数据时,整个批次的导入任务将会失败。',
|
||||
incremental_sync: '增量同步',
|
||||
incremental_sync_tip_1: '全量:全量覆盖同步',
|
||||
incremental_sync_tip_2: '增量:根据增量字段增量同步,增量字段必须是整型或时间类型',
|
||||
incremental_field: '增量字段',
|
||||
enable_partition: '启用分区',
|
||||
enable_partition_tip: '启用分区,需要字段列表不能有空值',
|
||||
partition_type: '分区类型',
|
||||
partition_field: '分区字段',
|
||||
on: '启用',
|
||||
off: '关闭',
|
||||
picker_to: '至',
|
||||
picker_start: '开始',
|
||||
picker_end: '截止',
|
||||
end_offset: '结束偏移',
|
||||
number_range: '数值范围',
|
||||
partition_interval: '分区间隔',
|
||||
partition_column_value: '分区列值',
|
||||
partition_column_value_placeholder: '分区格式为:p1:"v1","v2","v3";p2:"v1","v2"',
|
||||
partition_interval_unit: '分区间隔单位',
|
||||
input_limit: '长度不能超过{0}个字符',
|
||||
cannot_begin_with_number: '字段名称不能以数字开头',
|
||||
duplicate_field_tip: '重复字段[{0}],同一个源字段不能映射多次',
|
||||
duplicate_name_error: '名称重复[{0}]',
|
||||
confirm_batch_delete: '确定批量删除任务',
|
||||
op_success: '操作成功',
|
||||
search_input_name_desc_placeholder: '搜索名称、描述',
|
||||
confirm_delete_msg: '确定删除?',
|
||||
target_table_info: '目标表信息',
|
||||
confirm_clear_msg: '确定清理 {0} 吗?',
|
||||
clear: '清理',
|
||||
op_success_refresh: '执行成功,请稍后刷新',
|
||||
execute_time: '执行时间',
|
||||
clear_log: '清理日志',
|
||||
search_input_name_id_placeholder: '搜索名称、ID',
|
||||
log_id: '日志ID',
|
||||
op: '操作',
|
||||
view_execute_log: '查看执行日志',
|
||||
submit_true: '确定',
|
||||
please_choose_clear_method: '请选择清理方式',
|
||||
last_1_days_log: '1 天前的日志',
|
||||
last_1_weeks_log: '1 周前的日志',
|
||||
last_1_months_log: '1 个月前的日志',
|
||||
last_3_months_log: '3 个月前的日志',
|
||||
last_6_months_log: '6 个月前的日志',
|
||||
last_1_years_log: '1 年前的日志',
|
||||
execute_log: '执行日志',
|
||||
done: '完成',
|
||||
connection_lost: '连接断开',
|
||||
task_name: '任务名称'
|
||||
},
|
||||
watermark: {
|
||||
support_params: '当前支持的参数:',
|
||||
|
||||
@ -459,6 +459,10 @@ declare interface ChartTableCellAttr {
|
||||
* 冻结行
|
||||
*/
|
||||
tableRowFreezeHead: number
|
||||
/**
|
||||
* 合并单元格
|
||||
*/
|
||||
mergeCells: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||