mirror of
https://github.com/dataease/dataease.git
synced 2025-02-24 19:42:56 +08:00
Merge branch 'dev-v2' into radius-column-bar
This commit is contained in:
commit
ee8bce2fe4
@ -175,7 +175,7 @@ public class ChartDataManage {
|
||||
FilterTreeObj fieldCustomFilter = view.getCustomFilter();
|
||||
List<ChartViewFieldDTO> drill = new ArrayList<>(view.getDrillFields());
|
||||
|
||||
DatasetGroupInfoDTO table = datasetGroupManage.get(view.getTableId(), null);
|
||||
DatasetGroupInfoDTO table = datasetGroupManage.getDatasetGroupInfoDTO(view.getTableId(), null);
|
||||
if (table == null) {
|
||||
DEException.throwException(ResultCode.DATA_IS_WRONG.code(), Translator.get("i18n_no_ds"));
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.dataease.api.chart.dto.*;
|
||||
import io.dataease.api.chart.vo.ViewSelectorVO;
|
||||
import io.dataease.api.chart.filter.FilterTreeObj;
|
||||
import io.dataease.api.chart.vo.ViewSelectorVO;
|
||||
import io.dataease.api.dataset.union.model.SQLObj;
|
||||
import io.dataease.chart.dao.auto.entity.CoreChartView;
|
||||
import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
|
||||
@ -20,6 +20,7 @@ import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.IDUtils;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
@ -120,6 +121,7 @@ public class ChartViewManege {
|
||||
QueryWrapper<CoreDatasetTableField> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("dataset_group_id", id);
|
||||
wrapper.eq("checked", true);
|
||||
wrapper.isNull("chart_id");
|
||||
|
||||
List<CoreDatasetTableField> fields = coreDatasetTableFieldMapper.selectList(wrapper);
|
||||
List<DatasetTableFieldDTO> collect = fields.stream().map(ele -> {
|
||||
@ -173,6 +175,36 @@ public class ChartViewManege {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void copyField(Long id, Long chartId) {
|
||||
CoreDatasetTableField coreDatasetTableField = coreDatasetTableFieldMapper.selectById(id);
|
||||
QueryWrapper<CoreDatasetTableField> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("dataset_group_id", coreDatasetTableField.getDatasetGroupId());
|
||||
List<CoreDatasetTableField> coreDatasetTableFields = coreDatasetTableFieldMapper.selectList(queryWrapper);
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
for (CoreDatasetTableField ele : coreDatasetTableFields) {
|
||||
map.put(ele.getName(), ele.getName());
|
||||
}
|
||||
newName(map, coreDatasetTableField, coreDatasetTableField.getName());
|
||||
coreDatasetTableField.setChartId(chartId);
|
||||
coreDatasetTableField.setExtField(2);
|
||||
coreDatasetTableField.setOriginName("[" + id + "]");
|
||||
coreDatasetTableField.setId(IDUtils.snowID());
|
||||
coreDatasetTableFieldMapper.insert(coreDatasetTableField);
|
||||
}
|
||||
|
||||
private void newName(HashMap<String, String> map, CoreDatasetTableField coreDatasetTableField, String name) {
|
||||
name = name + "_copy";
|
||||
if (map.containsKey(name)) {
|
||||
newName(map, coreDatasetTableField, name);
|
||||
} else {
|
||||
coreDatasetTableField.setName(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteField(Long id) {
|
||||
coreDatasetTableFieldMapper.deleteById(id);
|
||||
}
|
||||
|
||||
public DatasetTableFieldDTO createCountField(Long id) {
|
||||
DatasetTableFieldDTO dto = new DatasetTableFieldDTO();
|
||||
dto.setId(-1L);
|
||||
|
@ -4,6 +4,7 @@ import io.dataease.api.chart.ChartDataApi;
|
||||
import io.dataease.api.chart.dto.ChartViewDTO;
|
||||
import io.dataease.api.chart.dto.ViewDetailField;
|
||||
import io.dataease.api.chart.request.ChartExcelRequest;
|
||||
import io.dataease.chart.constant.ChartConstants;
|
||||
import io.dataease.chart.manage.ChartDataManage;
|
||||
import io.dataease.constant.AuthConstant;
|
||||
import io.dataease.constant.CommonConstants;
|
||||
@ -69,7 +70,12 @@ public class ChartDataServer implements ChartDataApi {
|
||||
try {
|
||||
ChartViewDTO viewDTO = request.getViewInfo();
|
||||
viewDTO.setIsExcelExport(true);
|
||||
viewDTO.setResultCount(limit);
|
||||
if(ChartConstants.VIEW_RESULT_MODE.CUSTOM.equals(viewDTO.getResultMode())){
|
||||
Integer limitCount = viewDTO.getResultCount();
|
||||
viewDTO.setResultCount(limitCount>limit?limit:limitCount);
|
||||
}else{
|
||||
viewDTO.setResultCount(limit);
|
||||
}
|
||||
ChartViewDTO chartViewInfo = getData(viewDTO);
|
||||
List<Object[]> tableRow = (List) chartViewInfo.getData().get("sourceData");
|
||||
request.setDetails(tableRow);
|
||||
|
@ -57,4 +57,14 @@ public class ChartViewServer implements ChartViewApi {
|
||||
public List<ViewSelectorVO> viewOption(Long resourceId) {
|
||||
return chartViewManege.viewOption(resourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyField(Long id, Long chartId) {
|
||||
chartViewManege.copyField(id, chartId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteField(Long id) {
|
||||
chartViewManege.deleteField(id);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.dataease.dataset.manage;
|
||||
|
||||
import io.dataease.api.chart.dto.ChartExtFilterDTO;
|
||||
import io.dataease.api.chart.dto.ChartViewDTO;
|
||||
import io.dataease.api.chart.dto.ColumnPermissionItem;
|
||||
import io.dataease.api.chart.dto.DeSortField;
|
||||
import io.dataease.api.chart.request.ChartExtRequest;
|
||||
@ -204,7 +203,7 @@ public class DatasetDataManage {
|
||||
Table2SQLObj.table2sqlobj(sqlMeta, null, "(" + sql + ")", crossDs);
|
||||
Field2SQLObj.field2sqlObj(sqlMeta, fields, fields, crossDs, dsMap);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, fields, crossDs, dsMap);
|
||||
Order2SQLObj.getOrders(sqlMeta, fields, datasetGroupInfoDTO.getSortFields(), crossDs, dsMap);
|
||||
Order2SQLObj.getOrders(sqlMeta, datasetGroupInfoDTO.getSortFields(), fields, crossDs, dsMap);
|
||||
String querySQL;
|
||||
if (start == null || count == null) {
|
||||
querySQL = SQLProvider.createQuerySQL(sqlMeta, false, needOrder, false);
|
||||
@ -425,13 +424,9 @@ public class DatasetDataManage {
|
||||
}
|
||||
List<DatasetTableFieldDTO> allFields = new ArrayList<>();
|
||||
// 根据图表计算字段,获取数据集
|
||||
Long datasetGroupId;
|
||||
if (field.getDatasetGroupId() == null && field.getChartId() != null) {
|
||||
ChartViewDTO chart = chartViewManege.getChart(field.getChartId());
|
||||
datasetGroupId = chart.getTableId();
|
||||
Long datasetGroupId = field.getDatasetGroupId();
|
||||
if (field.getChartId() != null) {
|
||||
allFields.addAll(datasetTableFieldManage.getChartCalcFields(field.getChartId()));
|
||||
} else {
|
||||
datasetGroupId = field.getDatasetGroupId();
|
||||
}
|
||||
DatasetGroupInfoDTO datasetGroupInfoDTO = datasetGroupManage.get(datasetGroupId, null);
|
||||
|
||||
@ -471,9 +466,9 @@ public class DatasetDataManage {
|
||||
rowPermissionsTree = permissionManage.getRowPermissionsTree(datasetGroupInfoDTO.getId(), user.getUserId());
|
||||
}
|
||||
|
||||
Field2SQLObj.field2sqlObj(sqlMeta, fields, datasetGroupInfoDTO.getAllFields(), crossDs, dsMap);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, fields, crossDs, dsMap);
|
||||
Order2SQLObj.getOrders(sqlMeta, fields, datasetGroupInfoDTO.getSortFields(), crossDs, dsMap);
|
||||
Field2SQLObj.field2sqlObj(sqlMeta, fields, allFields, crossDs, dsMap);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, allFields, crossDs, dsMap);
|
||||
Order2SQLObj.getOrders(sqlMeta, datasetGroupInfoDTO.getSortFields(), allFields, crossDs, dsMap);
|
||||
String querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, true, 0, 1000);
|
||||
querySQL = SqlUtils.rebuildSQL(querySQL, sqlMeta, crossDs, dsMap);
|
||||
logger.info("calcite data enum sql: " + querySQL);
|
||||
@ -539,20 +534,18 @@ public class DatasetDataManage {
|
||||
}
|
||||
}
|
||||
|
||||
List<DatasetTableFieldDTO> allFields = new ArrayList<>();
|
||||
|
||||
for (Long id : ids) {
|
||||
DatasetTableFieldDTO field = datasetTableFieldManage.selectById(id);
|
||||
if (field == null) {
|
||||
DEException.throwException(Translator.get("i18n_no_field"));
|
||||
}
|
||||
List<DatasetTableFieldDTO> allFields = new ArrayList<>();
|
||||
|
||||
// 根据图表计算字段,获取数据集
|
||||
Long datasetGroupId;
|
||||
if (field.getDatasetGroupId() == null && field.getChartId() != null) {
|
||||
ChartViewDTO chart = chartViewManege.getChart(field.getChartId());
|
||||
datasetGroupId = chart.getTableId();
|
||||
Long datasetGroupId = field.getDatasetGroupId();
|
||||
if (field.getChartId() != null) {
|
||||
allFields.addAll(datasetTableFieldManage.getChartCalcFields(field.getChartId()));
|
||||
} else {
|
||||
datasetGroupId = field.getDatasetGroupId();
|
||||
}
|
||||
datasetGroupInfoDTO = datasetGroupManage.get(datasetGroupId, null);
|
||||
|
||||
@ -687,10 +680,10 @@ public class DatasetDataManage {
|
||||
sortDistinct = false;
|
||||
}
|
||||
|
||||
Field2SQLObj.field2sqlObj(sqlMeta, fields, datasetGroupInfoDTO.getAllFields(), crossDs, dsMap);
|
||||
ExtWhere2Str.extWhere2sqlOjb(sqlMeta, extFilterList, datasetGroupInfoDTO.getAllFields(), crossDs, dsMap);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, fields, crossDs, dsMap);
|
||||
Order2SQLObj.getOrders(sqlMeta, fields, datasetGroupInfoDTO.getSortFields(), crossDs, dsMap);
|
||||
Field2SQLObj.field2sqlObj(sqlMeta, fields, allFields, crossDs, dsMap);
|
||||
ExtWhere2Str.extWhere2sqlOjb(sqlMeta, extFilterList, allFields, crossDs, dsMap);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, allFields, crossDs, dsMap);
|
||||
Order2SQLObj.getOrders(sqlMeta, datasetGroupInfoDTO.getSortFields(), allFields, crossDs, dsMap);
|
||||
String querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, sortDistinct && ids.size() == 1, 0, 1000);
|
||||
querySQL = SqlUtils.rebuildSQL(querySQL, sqlMeta, crossDs, dsMap);
|
||||
logger.info("calcite data enum sql: " + querySQL);
|
||||
|
@ -371,6 +371,10 @@ public class DatasetGroupManage {
|
||||
return dto;
|
||||
}
|
||||
|
||||
public DatasetGroupInfoDTO getDatasetGroupInfoDTO(Long id, String type) throws Exception {
|
||||
return get(id, type);
|
||||
}
|
||||
|
||||
public DatasetGroupInfoDTO get(Long id, String type) throws Exception {
|
||||
CoreDatasetGroup coreDatasetGroup = coreDatasetGroupMapper.selectById(id);
|
||||
if (coreDatasetGroup == null) {
|
||||
|
@ -156,6 +156,7 @@ public class DatasetTableFieldManage {
|
||||
QueryWrapper<CoreDatasetTableField> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("dataset_group_id", id);
|
||||
wrapper.eq("checked", true);
|
||||
wrapper.isNull("chart_id");
|
||||
return transDTO(coreDatasetTableFieldMapper.selectList(wrapper));
|
||||
}
|
||||
|
||||
|
@ -117,9 +117,9 @@ public class CalciteProvider {
|
||||
tableDesc.setDatasourceId(datasourceRequest.getDatasource().getId());
|
||||
tableDesc.setType("db");
|
||||
tableDesc.setTableName(resultSet.getString(1));
|
||||
if(resultSet.getMetaData().getColumnCount() > 1){
|
||||
if (resultSet.getMetaData().getColumnCount() > 1) {
|
||||
tableDesc.setName(resultSet.getString(2));
|
||||
}else {
|
||||
} else {
|
||||
tableDesc.setName(resultSet.getString(1));
|
||||
}
|
||||
return tableDesc;
|
||||
@ -316,10 +316,104 @@ public class CalciteProvider {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void hidePW(DatasourceDTO datasourceDTO) {
|
||||
DatasourceConfiguration configuration = null;
|
||||
DatasourceType datasourceType = DatasourceType.valueOf(datasourceDTO.getType());
|
||||
switch (datasourceType) {
|
||||
case mysql:
|
||||
case mongo:
|
||||
case mariadb:
|
||||
case TiDB:
|
||||
case StarRocks:
|
||||
case doris:
|
||||
configuration = JsonUtil.parseObject(datasourceDTO.getConfiguration(), Mysql.class);
|
||||
if (StringUtils.isNotEmpty(configuration.getUrlType()) && configuration.getUrlType().equalsIgnoreCase("jdbcUrl")) {
|
||||
if (configuration.getJdbcUrl().contains("password=")) {
|
||||
String[] params = configuration.getJdbcUrl().split("\\?")[1].split("&");
|
||||
String pd = "";
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (params[i].contains("password=")) {
|
||||
pd = params[i];
|
||||
}
|
||||
}
|
||||
configuration.setJdbcUrl(configuration.getJdbcUrl().replace(pd, "password=******"));
|
||||
datasourceDTO.setConfiguration(JsonUtil.toJSONString(configuration).toString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case pg:
|
||||
configuration = JsonUtil.parseObject(datasourceDTO.getConfiguration(), Pg.class);
|
||||
if (StringUtils.isNotEmpty(configuration.getUrlType()) && configuration.getUrlType().equalsIgnoreCase("jdbcUrl")) {
|
||||
if (configuration.getJdbcUrl().contains("password=")) {
|
||||
String[] params = configuration.getJdbcUrl().split("\\?")[1].split("&");
|
||||
String pd = "";
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (params[i].contains("password=")) {
|
||||
pd = params[i];
|
||||
}
|
||||
}
|
||||
configuration.setJdbcUrl(configuration.getJdbcUrl().replace(pd, "password=******"));
|
||||
datasourceDTO.setConfiguration(JsonUtil.toJSONString(configuration).toString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case redshift:
|
||||
configuration = JsonUtil.parseObject(datasourceDTO.getConfiguration(), Redshift.class);
|
||||
if (StringUtils.isNotEmpty(configuration.getUrlType()) && configuration.getUrlType().equalsIgnoreCase("jdbcUrl")) {
|
||||
if (configuration.getJdbcUrl().contains("password=")) {
|
||||
String[] params = configuration.getJdbcUrl().split("\\?")[1].split("&");
|
||||
String pd = "";
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (params[i].contains("password=")) {
|
||||
pd = params[i];
|
||||
}
|
||||
}
|
||||
configuration.setJdbcUrl(configuration.getJdbcUrl().replace(pd, "password=******"));
|
||||
datasourceDTO.setConfiguration(JsonUtil.toJSONString(configuration).toString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ck:
|
||||
configuration = JsonUtil.parseObject(datasourceDTO.getConfiguration(), CK.class);
|
||||
if (StringUtils.isNotEmpty(configuration.getUrlType()) && configuration.getUrlType().equalsIgnoreCase("jdbcUrl")) {
|
||||
if (configuration.getJdbcUrl().contains("password=")) {
|
||||
String[] params = configuration.getJdbcUrl().split("\\?")[1].split("&");
|
||||
String pd = "";
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (params[i].contains("password=")) {
|
||||
pd = params[i];
|
||||
}
|
||||
}
|
||||
configuration.setJdbcUrl(configuration.getJdbcUrl().replace(pd, "password=******"));
|
||||
datasourceDTO.setConfiguration(JsonUtil.toJSONString(configuration).toString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case impala:
|
||||
configuration = JsonUtil.parseObject(datasourceDTO.getConfiguration(), Impala.class);
|
||||
if (StringUtils.isNotEmpty(configuration.getUrlType()) && configuration.getUrlType().equalsIgnoreCase("jdbcUrl")) {
|
||||
if (configuration.getJdbcUrl().contains("password=")) {
|
||||
String[] params = configuration.getJdbcUrl().split(";")[1].split("&");
|
||||
String pd = "";
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (params[i].contains("password=")) {
|
||||
pd = params[i];
|
||||
}
|
||||
}
|
||||
configuration.setJdbcUrl(configuration.getJdbcUrl().replace(pd, "password=******"));
|
||||
datasourceDTO.setConfiguration(JsonUtil.toJSONString(configuration).toString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private String getTableFiledSql(DatasourceRequest datasourceRequest) {
|
||||
String sql = "";
|
||||
DatasourceConfiguration configuration = null;
|
||||
String database="";
|
||||
String database = "";
|
||||
DatasourceType datasourceType = DatasourceType.valueOf(datasourceRequest.getDatasource().getType());
|
||||
switch (datasourceType) {
|
||||
case mysql:
|
||||
@ -440,7 +534,8 @@ public class CalciteProvider {
|
||||
return sql;
|
||||
}
|
||||
|
||||
private TableField getTableFieldDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws SQLException {
|
||||
private TableField getTableFieldDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws
|
||||
SQLException {
|
||||
TableField tableField = new TableField();
|
||||
tableField.setOriginName(resultSet.getString(1));
|
||||
tableField.setType(resultSet.getString(2).toUpperCase());
|
||||
@ -809,7 +904,7 @@ public class CalciteProvider {
|
||||
" AND ep.class = 1 \n" +
|
||||
" AND ep.name = 'MS_Description'\n" +
|
||||
"where sc.name ='DS_SCHEMA'"
|
||||
.replace("DS_SCHEMA", configuration.getSchema()));
|
||||
.replace("DS_SCHEMA", configuration.getSchema()));
|
||||
tableSqls.add("SELECT \n" +
|
||||
" t.name AS TableName, \n" +
|
||||
" ep.value AS TableDescription \n" +
|
||||
|
@ -488,12 +488,20 @@ public class DatasourceServer implements DatasourceApi {
|
||||
return calciteProvider.getSchema(datasourceRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatasourceDTO hidePw(Long datasourceId) throws DEException {
|
||||
return getDatasourceDTOById(datasourceId, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatasourceDTO get(Long datasourceId) throws DEException {
|
||||
return getDatasourceDTOById(datasourceId, false);
|
||||
}
|
||||
|
||||
private DatasourceDTO getDatasourceDTOById(Long datasourceId, boolean hidePw) throws DEException {
|
||||
DatasourceDTO datasourceDTO = new DatasourceDTO();
|
||||
CoreDatasource datasource = datasourceMapper.selectById(datasourceId);
|
||||
if(datasource == null){
|
||||
if (datasource == null) {
|
||||
DEException.throwException("不存在的数据源!");
|
||||
}
|
||||
BeanUtils.copyBean(datasourceDTO, datasource);
|
||||
@ -547,15 +555,18 @@ public class DatasourceServer implements DatasourceApi {
|
||||
if (task != null) {
|
||||
datasourceDTO.setLastSyncTime(task.getStartTime());
|
||||
}
|
||||
} else {
|
||||
if (hidePw) {
|
||||
calciteProvider.hidePW(datasourceDTO);
|
||||
}
|
||||
|
||||
}
|
||||
if (datasourceDTO.getType().equalsIgnoreCase(DatasourceConfiguration.DatasourceType.Excel.toString())) {
|
||||
datasourceDTO.setFileName(ExcelUtils.getFileName(datasource));
|
||||
datasourceDTO.setSize(ExcelUtils.getSize(datasource));
|
||||
}
|
||||
datasourceDTO.setConfiguration(new String(Base64.getEncoder().encode(datasourceDTO.getConfiguration().getBytes())));
|
||||
|
||||
datasourceDTO.setCreator(coreUserManage.getUserName(Long.valueOf(datasourceDTO.getCreateBy())));
|
||||
|
||||
return datasourceDTO;
|
||||
}
|
||||
|
||||
@ -750,7 +761,7 @@ public class DatasourceServer implements DatasourceApi {
|
||||
datasourceRequest.setDsList(Map.of(datasourceSchemaDTO.getId(), datasourceSchemaDTO));
|
||||
datasourceRequest.setQuery(TableUtils.tableName2Sql(datasourceSchemaDTO, tableName) + " LIMIT 0 OFFSET 0");
|
||||
datasourceRequest.setTable(tableName);
|
||||
List<TableField> tableFields = (List<TableField>) calciteProvider.fetchTableField(datasourceRequest) ;
|
||||
List<TableField> tableFields = (List<TableField>) calciteProvider.fetchTableField(datasourceRequest);
|
||||
return tableFields.stream().filter(tableField -> {
|
||||
return !tableField.getOriginName().equalsIgnoreCase("dataease_uuid");
|
||||
}).collect(Collectors.toList());
|
||||
|
@ -22,17 +22,17 @@ import java.util.Objects;
|
||||
*/
|
||||
public class Order2SQLObj {
|
||||
|
||||
public static void getOrders(SQLMeta meta, List<DatasetTableFieldDTO> fields, List<DeSortField> sortFields, boolean isCross, Map<Long, DatasourceSchemaDTO> dsMap) {
|
||||
public static void getOrders(SQLMeta meta, List<DeSortField> sortFields, List<DatasetTableFieldDTO> originFields, boolean isCross, Map<Long, DatasourceSchemaDTO> dsMap) {
|
||||
SQLObj tableObj = meta.getTable();
|
||||
List<SQLObj> xOrders = meta.getXOrders() == null ? new ArrayList<>() : meta.getXOrders();
|
||||
if (ObjectUtils.isEmpty(tableObj)) {
|
||||
return;
|
||||
}
|
||||
if (ObjectUtils.isNotEmpty(sortFields)) {
|
||||
int step = fields.size();
|
||||
int step = originFields.size();
|
||||
for (int i = step; i < (step + sortFields.size()); i++) {
|
||||
DeSortField deSortField = sortFields.get(i - step);
|
||||
SQLObj order = buildSortField(deSortField, tableObj, i, fields, isCross, dsMap);
|
||||
SQLObj order = buildSortField(deSortField, tableObj, i, originFields, isCross, dsMap);
|
||||
xOrders.add(order);
|
||||
}
|
||||
meta.setXOrders(xOrders);
|
||||
|
@ -12,6 +12,7 @@ import io.dataease.engine.constant.DeTypeConstants;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.exportCenter.dao.auto.entity.CoreExportTask;
|
||||
import io.dataease.exportCenter.dao.auto.mapper.CoreExportTaskMapper;
|
||||
import io.dataease.system.manage.SysParameterManage;
|
||||
import io.dataease.utils.*;
|
||||
import io.dataease.visualization.server.DataVisualizationServer;
|
||||
import io.dataease.websocket.WsMessage;
|
||||
@ -50,6 +51,8 @@ public class ExportCenterManage {
|
||||
private CoreChartViewMapper coreChartViewMapper;
|
||||
@Autowired
|
||||
private WsService wsService;
|
||||
@Resource
|
||||
private SysParameterManage sysParameterManage;
|
||||
|
||||
@Value("${export.dataset.limit:100000}")
|
||||
private int limit;
|
||||
@ -183,12 +186,21 @@ public class ExportCenterManage {
|
||||
if (status.equalsIgnoreCase(exportTaskDTO.getExportStatus())) {
|
||||
setExportFromAbsName(exportTaskDTO);
|
||||
}
|
||||
if (status.equalsIgnoreCase(exportTaskDTO.getExportStatus())) {
|
||||
setOrgName(exportTaskDTO);
|
||||
}
|
||||
result.add(exportTaskDTO);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void setOrgName(ExportTaskDTO exportTaskDTO) {
|
||||
if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) {
|
||||
exportTaskDTO.setOrgName(dataVisualizationServer.getAbsPath(exportTaskDTO.getExportFrom()));
|
||||
}
|
||||
}
|
||||
|
||||
private void setExportFromAbsName(ExportTaskDTO exportTaskDTO) {
|
||||
if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) {
|
||||
exportTaskDTO.setExportFromName(dataVisualizationServer.getAbsPath(exportTaskDTO.getExportFrom()));
|
||||
@ -408,6 +420,21 @@ public class ExportCenterManage {
|
||||
|
||||
private static final String LOG_RETENTION = "30";
|
||||
|
||||
public void cleanLog() {
|
||||
String key = "basic.exportFileLiveTime";
|
||||
String val = sysParameterManage.singleVal(key);
|
||||
if (StringUtils.isBlank(val)) {
|
||||
DEException.throwException("未获取到文件保留时间");
|
||||
}
|
||||
QueryWrapper<CoreExportTask> queryWrapper = new QueryWrapper<>();
|
||||
long expTime = Long.parseLong(val) * 24L * 3600L * 1000L;
|
||||
long threshold = System.currentTimeMillis() - expTime;
|
||||
queryWrapper.lt("export_time", threshold);
|
||||
exportTaskMapper.selectList(queryWrapper).forEach(coreExportTask -> {
|
||||
delete(coreExportTask.getId());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -10,9 +10,9 @@ import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component
|
||||
public class CheckDsStatusJob implements Job {
|
||||
|
||||
@Resource
|
||||
private DatasourceServer datasourceServer;
|
||||
|
||||
|
@ -14,12 +14,13 @@ import io.dataease.constant.AuthConstant;
|
||||
import io.dataease.constant.BusiResourceEnum;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.license.config.XpackInteract;
|
||||
import io.dataease.share.dao.auto.mapper.XpackShareMapper;
|
||||
import io.dataease.utils.*;
|
||||
import io.dataease.license.utils.LicenseUtil;
|
||||
import io.dataease.share.dao.auto.entity.XpackShare;
|
||||
import io.dataease.share.dao.auto.mapper.XpackShareMapper;
|
||||
import io.dataease.share.dao.ext.mapper.XpackShareExtMapper;
|
||||
import io.dataease.share.dao.ext.po.XpackSharePO;
|
||||
import io.dataease.share.util.LinkTokenUtil;
|
||||
import io.dataease.utils.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
@ -125,7 +126,6 @@ public class XpackShareManage {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public IPage<XpackSharePO> querySharePage(int goPage, int pageSize, VisualizationWorkbranchQueryRequest request) {
|
||||
Long uid = AuthUtils.getUser().getUserId();
|
||||
QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
|
||||
@ -174,7 +174,7 @@ public class XpackShareManage {
|
||||
return pos.stream().map(po ->
|
||||
new XpackShareGridVO(
|
||||
po.getShareId(), po.getResourceId(), po.getName(), po.getCreator().toString(),
|
||||
po.getTime(), po.getExp(), 9,po.getExtFlag(),po.getType())).toList();
|
||||
po.getTime(), po.getExp(), 9, po.getExtFlag(), po.getType())).toList();
|
||||
}
|
||||
|
||||
private XpackShareManage proxy() {
|
||||
@ -182,6 +182,10 @@ public class XpackShareManage {
|
||||
}
|
||||
|
||||
public XpackShareProxyVO proxyInfo(XpackShareProxyRequest request) {
|
||||
boolean inIframeError = request.isInIframe() && !LicenseUtil.licenseValid();
|
||||
if (inIframeError) {
|
||||
return new XpackShareProxyVO();
|
||||
}
|
||||
QueryWrapper<XpackShare> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("uuid", request.getUuid());
|
||||
XpackShare xpackShare = xpackShareMapper.selectOne(queryWrapper);
|
||||
@ -192,7 +196,7 @@ public class XpackShareManage {
|
||||
response.addHeader(AuthConstant.LINK_TOKEN_KEY, linkToken);
|
||||
Integer type = xpackShare.getType();
|
||||
String typeText = (ObjectUtils.isNotEmpty(type) && type == 1) ? "dashboard" : "dataV";
|
||||
return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText);
|
||||
return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText, inIframeError);
|
||||
}
|
||||
|
||||
private boolean linkExp(XpackShare xpackShare) {
|
||||
|
@ -20,8 +20,10 @@ public class DeWebSocketHandlerDecorator extends WebSocketHandlerDecorator {
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
Optional.ofNullable(session.getPrincipal()).ifPresent(principal -> {
|
||||
String name = principal.getName();
|
||||
Long userId = Long.parseLong(name);
|
||||
WsUtil.onLine(userId);
|
||||
if(name != null){
|
||||
Long userId = Long.parseLong(name);
|
||||
WsUtil.onLine(userId);
|
||||
}
|
||||
});
|
||||
super.afterConnectionEstablished(session);
|
||||
}
|
||||
@ -30,8 +32,10 @@ public class DeWebSocketHandlerDecorator extends WebSocketHandlerDecorator {
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
|
||||
Optional.ofNullable(session.getPrincipal()).ifPresent(principal -> {
|
||||
String name = principal.getName();
|
||||
Long userId = Long.parseLong(name);
|
||||
WsUtil.offLine(userId);
|
||||
if(name != null){
|
||||
Long userId = Long.parseLong(name);
|
||||
WsUtil.offLine(userId);
|
||||
}
|
||||
});
|
||||
|
||||
super.afterConnectionClosed(session, closeStatus);
|
||||
|
@ -13,3 +13,24 @@ CREATE TABLE `core_sys_startup_job`
|
||||
BEGIN;
|
||||
INSERT INTO `core_sys_startup_job` VALUES ('chartFilterMerge', 'chartFilterMerge', 'ready');
|
||||
COMMIT;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `core_export_task`;
|
||||
CREATE TABLE `core_export_task`
|
||||
(
|
||||
`id` VARCHAR(255) NOT NULL,
|
||||
`user_id` BIGINT(20) NOT NULL,
|
||||
`file_name` VARCHAR(2048) DEFAULT NULL,
|
||||
`file_size` DOUBLE DEFAULT NULL,
|
||||
`file_size_unit` VARCHAR(255) DEFAULT NULL,
|
||||
`export_from` VARCHAR(255) DEFAULT NULL,
|
||||
`export_status` VARCHAR(255) DEFAULT NULL,
|
||||
`export_from_type` VARCHAR(255) DEFAULT NULL,
|
||||
`export_time` BIGINT(20) DEFAULT NULL,
|
||||
`export_progress` VARCHAR(255) DEFAULT NULL,
|
||||
`export_machine_name` VARCHAR(512) DEFAULT NULL,
|
||||
`params` longtext NOT NULL COMMENT '过滤参数',
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT='导出任务表';
|
||||
|
||||
UPDATE `QRTZ_JOB_DETAILS` SET `JOB_CLASS_NAME` = 'io.dataease.job.schedule.CheckDsStatusJob' WHERE (`SCHED_NAME` = 'deSyncJob') and (`JOB_NAME` = 'Datasource') and (`JOB_GROUP` = 'check_status');
|
||||
|
@ -52,3 +52,6 @@ CREATE TABLE `xpack_platform_token`
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
|
||||
|
||||
UPDATE `QRTZ_JOB_DETAILS` SET `JOB_CLASS_NAME` = 'io.dataease.job.schedule.CheckDsStatusJob' WHERE (`SCHED_NAME` = 'deSyncJob') and (`JOB_NAME` = 'Datasource') and (`JOB_GROUP` = 'check_status');
|
||||
|
@ -20,6 +20,7 @@
|
||||
"@codemirror/lang-sql": "^6.4.0",
|
||||
"@npkg/tinymce-plugins": "^0.0.7",
|
||||
"@tinymce/tinymce-vue": "^5.1.0",
|
||||
"@videojs-player/vue": "^1.0.0",
|
||||
"@vueuse/core": "^9.13.0",
|
||||
"ace-builds": "^1.15.3",
|
||||
"axios": "^1.3.3",
|
||||
@ -46,6 +47,7 @@
|
||||
"snowflake-id": "^1.1.0",
|
||||
"tinymce": "^5.8.2",
|
||||
"vant": "^4.8.3",
|
||||
"video.js": "^7.21.6",
|
||||
"vue": "^3.3.4",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-codemirror": "^6.1.1",
|
||||
@ -54,7 +56,6 @@
|
||||
"vue-types": "^5.0.2",
|
||||
"vue-uuid": "^3.0.0",
|
||||
"vue3-ace-editor": "^2.2.2",
|
||||
"vue3-video-play": "^1.3.2",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"web-storage-cache": "^1.1.1",
|
||||
"xss": "^1.0.14"
|
||||
|
@ -147,6 +147,8 @@ export const deleteById = (id: number) => request.get({ url: '/datasource/delete
|
||||
|
||||
export const getById = (id: number) => request.get({ url: '/datasource/get/' + id })
|
||||
|
||||
export const getHidePwById = (id: number) => request.get({ url: '/datasource/hidePw/' + id })
|
||||
|
||||
export const uploadFile = async (data): Promise<IResponse> => {
|
||||
return request
|
||||
.post({
|
||||
|
7
core/core-frontend/src/assets/svg/bar-range-origin.svg
Normal file
7
core/core-frontend/src/assets/svg/bar-range-origin.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="80" height="56" viewBox="0 0 80 56" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 2.00391V53.0016V54.0016H4V2.00391H7Z" />
|
||||
<path d="M17.5 50C17.2239 50 17 49.7761 17 49.5V42.5C17 42.2239 17.2239 42 17.5 42H52.5C52.7761 42 53 42.2239 53 42.5V49.5C53 49.7761 52.7761 50 52.5 50H17.5Z" />
|
||||
<path d="M48.5 38C48.2239 38 48 37.7761 48 37.5V30.5C48 30.2239 48.2239 30 48.5 30H71.5C71.7761 30 72 30.2239 72 30.5V37.5C72 37.7761 71.7761 38 71.5 38H48.5Z" />
|
||||
<path d="M28.5 26C28.2239 26 28 25.7761 28 25.5V18.5C28 18.2239 28.2239 18 28.5 18H47.5C47.7761 18 48 18.2239 48 18.5V25.5C48 25.7761 47.7761 26 47.5 26H28.5Z" />
|
||||
<path d="M9.5 14C9.22386 14 9 13.7761 9 13.5V6.5C9 6.22386 9.22386 6 9.5 6L48.5 6C48.7761 6 49 6.22386 49 6.5V13.5C49 13.7761 48.7761 14 48.5 14L9.5 14Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 831 B |
@ -0,0 +1,11 @@
|
||||
<svg width="80" height="56" viewBox="0 0 80 56" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M41 2.00391V53.0016V54.0016H38V2.00391H41Z" />
|
||||
<path d="M4.5 50C4.22386 50 4 49.7761 4 49.5L4 42.5C4 42.2239 4.22386 42 4.5 42H35.5C35.7761 42 36 42.2239 36 42.5V49.5C36 49.7761 35.7761 50 35.5 50H4.5Z" />
|
||||
<path d="M12.5 38C12.2239 38 12 37.7761 12 37.5V30.5C12 30.2239 12.2239 30 12.5 30H35.5C35.7761 30 36 30.2239 36 30.5V37.5C36 37.7761 35.7761 38 35.5 38H12.5Z" />
|
||||
<path d="M43.5 14C43.2239 14 43 13.7761 43 13.5V6.5C43 6.22386 43.2239 6 43.5 6L71.5 6C71.7761 6 72 6.22386 72 6.5V13.5C72 13.7761 71.7761 14 71.5 14L43.5 14Z" />
|
||||
<path d="M43.5 26C43.2239 26 43 25.7761 43 25.5V18.5C43 18.2239 43.2239 18 43.5 18H62.5C62.7761 18 63 18.2239 63 18.5V25.5C63 25.7761 62.7761 26 62.5 26H43.5Z" />
|
||||
<path d="M43.5 38C43.2239 38 43 37.7761 43 37.5V30.5C43 30.2239 43.2239 30 43.5 30H57.5C57.7761 30 58 30.2239 58 30.5V37.5C58 37.7761 57.7761 38 57.5 38H43.5Z" />
|
||||
<path d="M43.5 50C43.2239 50 43 49.7761 43 49.5V42.5C43 42.2239 43.2239 42 43.5 42H75.5C75.7761 42 76 42.2239 76 42.5V49.5C76 49.7761 75.7761 50 75.5 50H43.5Z" />
|
||||
<path d="M16.5 26C16.2239 26 16 25.7761 16 25.5V18.5C16 18.2239 16.2239 18 16.5 18H35.5C35.7761 18 36 18.2239 36 18.5V25.5C36 25.7761 35.7761 26 35.5 26H16.5Z" />
|
||||
<path d="M8.5 14C8.22386 14 8 13.7761 8 13.5V6.5C8 6.22386 8.22386 6 8.5 6L35.5 6C35.7761 6 36 6.22386 36 6.5V13.5C36 13.7761 35.7761 14 35.5 14L8.5 14Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
1
core/core-frontend/src/assets/svg/icon_search.svg
Normal file
1
core/core-frontend/src/assets/svg/icon_search.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="1717496887274" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4257" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M376.5 70c41.4 0 81.5 8.1 119.3 24.1 36.5 15.4 69.3 37.5 97.4 65.7 28.2 28.2 50.3 61 65.7 97.4 16 37.7 24.1 77.9 24.1 119.3s-8.1 81.5-24.1 119.3c-15.4 36.5-37.5 69.3-65.7 97.4-28.2 28.2-61 50.3-97.4 65.7-37.7 16-77.9 24.1-119.3 24.1s-81.5-8.1-119.3-24.1c-36.5-15.4-69.3-37.5-97.4-65.7s-50.3-61-65.7-97.4C78.1 458 70 417.9 70 376.5s8.1-81.5 24.1-119.3c15.4-36.5 37.5-69.3 65.7-97.4 28.2-28.2 61-50.3 97.4-65.7C295 78.1 335.1 70 376.5 70m0-70C168.6 0 0 168.6 0 376.5S168.6 753 376.5 753 753 584.4 753 376.5 584.4 0 376.5 0z" p-id="4258"></path><path d="M274.5 136.1c8.8-8.8 18-17 27.5-24.6-37.3 13.6-72.2 35.3-102.1 65.2-109.7 109.7-109.7 287.7 0 397.4 33.2 33.2 72.6 56.3 114.4 69.4-13.9-10.1-27.2-21.5-39.8-34.1-130.7-130.7-130.7-342.6 0-473.3zM998.3 998.3c-34.2 34.2-90.2 34.2-124.5 0L622.2 746.6c-34.2-34.2-34.2-90.2 0-124.5 34.2-34.2 90.2-34.2 124.5 0l251.7 251.7c34.2 34.3 34.2 90.3-0.1 124.5z" p-id="4259"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
11
core/core-frontend/src/assets/svg/progress-bar-origin.svg
Normal file
11
core/core-frontend/src/assets/svg/progress-bar-origin.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg width="80" height="56" viewBox="0 0 80 56" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 2.00391V53.0016V54.0016H4V2.00391H7Z" />
|
||||
<path d="M9.5 14C9.22386 14 9 13.7761 9 13.5V6.5C9 6.22386 9.22386 6 9.5 6L71.5 6C71.7761 6 72 6.22386 72 6.5V13.5C72 13.7761 71.7761 14 71.5 14L9.5 14Z" />
|
||||
<path d="M9.5 26C9.22386 26 9 25.7761 9 25.5V18.5C9 18.2239 9.22386 18 9.5 18H71.5C71.7761 18 72 18.2239 72 18.5V25.5C72 25.7761 71.7761 26 71.5 26L9.5 26Z" />
|
||||
<path d="M9.5 38C9.22386 38 9 37.7761 9 37.5V30.5C9 30.2239 9.22386 30 9.5 30H71.5C71.7761 30 72 30.2239 72 30.5V37.5C72 37.7761 71.7761 38 71.5 38H9.5Z" />
|
||||
<path d="M9.5 50C9.22386 50 9 49.7761 9 49.5V42.5C9 42.2239 9.22386 42 9.5 42H71.5C71.7761 42 72 42.2239 72 42.5V49.5C72 49.7761 71.7761 50 71.5 50H9.5Z" />
|
||||
<path d="M9.5 14C9.22386 14 9 13.7761 9 13.5V6.5C9 6.22386 9.22386 6 9.5 6L59.5 6C59.7761 6 60 6.22386 60 6.5V13.5C60 13.7761 59.7761 14 59.5 14L9.5 14Z" />
|
||||
<path d="M9.5 26C9.22386 26 9 25.7761 9 25.5V18.5C9 18.2239 9.22386 18 9.5 18H46.5C46.7761 18 47 18.2239 47 18.5V25.5C47 25.7761 46.7761 26 46.5 26H9.5Z" />
|
||||
<path d="M9.5 38C9.22386 38 9 37.7761 9 37.5V30.5C9 30.2239 9.22386 30 9.5 30H37.5C37.7761 30 38 30.2239 38 30.5V37.5C38 37.7761 37.7761 38 37.5 38H9.5Z" />
|
||||
<path d="M9.5 50C9.22386 50 9 49.7761 9 49.5V42.5C9 42.2239 9.22386 42 9.5 42H21.5C21.7761 42 22 42.2239 22 42.5V49.5C22 49.7761 21.7761 50 21.5 50H9.5Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
12
core/core-frontend/src/assets/svg/quadrant-origin.svg
Normal file
12
core/core-frontend/src/assets/svg/quadrant-origin.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg width="88" height="64" viewBox="0 0 88 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 30.002H80L80 33.002H8V30.002H9Z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.0417 6H31L31 58H28V6H28.0417Z"/>
|
||||
<path d="M57.666 22C58.0616 22 58.4483 21.8827 58.7772 21.6629C59.1061 21.4432 59.3624 21.1308 59.5138 20.7654C59.6651 20.3999 59.7048 19.9978 59.6276 19.6098C59.5504 19.2219 59.3599 18.8655 59.0802 18.5858C58.8005 18.3061 58.4442 18.1156 58.0562 18.0384C57.6682 17.9613 57.2661 18.0009 56.9006 18.1522C56.5352 18.3036 56.2228 18.56 56.0031 18.8889C55.7833 19.2178 55.666 19.6044 55.666 20C55.666 20.5304 55.8767 21.0391 56.2518 21.4142C56.6269 21.7893 57.1356 22 57.666 22Z" />
|
||||
<path d="M46.4432 46.9969C46.1143 47.2167 45.7276 47.334 45.332 47.334C44.8016 47.334 44.2929 47.1233 43.9178 46.7482C43.5427 46.3731 43.332 45.8644 43.332 45.334C43.332 44.9384 43.4493 44.5517 43.6691 44.2228C43.8889 43.8939 44.2012 43.6376 44.5667 43.4862C44.9321 43.3349 45.3342 43.2952 45.7222 43.3724C46.1102 43.4496 46.4665 43.6401 46.7462 43.9198C47.0259 44.1995 47.2164 44.5558 47.2936 44.9438C47.3708 45.3318 47.3312 45.7339 47.1798 46.0994C47.0284 46.4648 46.7721 46.7772 46.4432 46.9969Z" />
|
||||
<path d="M18.7772 48.9969C18.4483 49.2167 18.0616 49.334 17.666 49.334C17.1356 49.334 16.6269 49.1233 16.2518 48.7482C15.8767 48.3731 15.666 47.8644 15.666 47.334C15.666 46.9384 15.7833 46.5517 16.0031 46.2228C16.2228 45.8939 16.5352 45.6376 16.9006 45.4862C17.2661 45.3349 17.6682 45.2952 18.0562 45.3724C18.4442 45.4496 18.8005 45.6401 19.0802 45.9198C19.3599 46.1995 19.5504 46.5558 19.6276 46.9438C19.7048 47.3318 19.6651 47.7339 19.5138 48.0994C19.3624 48.4648 19.1061 48.7772 18.7772 48.9969Z" />
|
||||
<path d="M44.5543 19.9938C43.8965 20.4334 43.1232 20.668 42.332 20.668C41.2712 20.668 40.2537 20.2465 39.5036 19.4964C38.7535 18.7463 38.332 17.7288 38.332 16.668C38.332 15.8768 38.5666 15.1035 39.0062 14.4457C39.4457 13.7879 40.0704 13.2752 40.8013 12.9725C41.5322 12.6697 42.3365 12.5905 43.1124 12.7448C43.8883 12.8992 44.601 13.2801 45.1605 13.8395C45.7199 14.399 46.1008 15.1117 46.2552 15.8876C46.4095 16.6635 46.3303 17.4678 46.0275 18.1987C45.7248 18.9296 45.2121 19.5543 44.5543 19.9938Z" />
|
||||
<path d="M62.221 49.3272C61.5632 49.7667 60.7898 50.0013 59.9987 50.0013C58.9378 50.0013 57.9204 49.5799 57.1703 48.8297C56.4201 48.0796 55.9987 47.0622 55.9987 46.0013C55.9987 45.2102 56.2333 44.4368 56.6728 43.779C57.1123 43.1212 57.7371 42.6085 58.468 42.3058C59.1989 42.003 60.0031 41.9238 60.7791 42.0782C61.555 42.2325 62.2677 42.6135 62.8271 43.1729C63.3865 43.7323 63.7675 44.445 63.9218 45.2209C64.0762 45.9969 63.997 46.8011 63.6942 47.532C63.3915 48.2629 62.8788 48.8877 62.221 49.3272Z" />
|
||||
<path d="M20.5543 21.6605C19.8965 22.1 19.1232 22.3346 18.332 22.3346C17.2712 22.3346 16.2538 21.9132 15.5036 21.1631C14.7535 20.4129 14.332 19.3955 14.332 18.3346C14.332 17.5435 14.5666 16.7702 15.0062 16.1124C15.4457 15.4546 16.0704 14.9419 16.8013 14.6391C17.5322 14.3364 18.3365 14.2572 19.1124 14.4115C19.8883 14.5658 20.601 14.9468 21.1605 15.5062C21.7199 16.0656 22.1008 16.7784 22.2552 17.5543C22.4095 18.3302 22.3303 19.1345 22.0275 19.8654C21.7248 20.5963 21.2121 21.221 20.5543 21.6605Z" />
|
||||
<path d="M68.666 16C69.4571 16 70.2305 15.7654 70.8883 15.3259C71.5461 14.8864 72.0588 14.2616 72.3615 13.5307C72.6643 12.7998 72.7435 11.9956 72.5892 11.2196C72.4348 10.4437 72.0539 9.73099 71.4944 9.17158C70.935 8.61217 70.2223 8.2312 69.4464 8.07686C68.6705 7.92252 67.8662 8.00173 67.1353 8.30448C66.4044 8.60723 65.7797 9.11993 65.3401 9.77772C64.9006 10.4355 64.666 11.2089 64.666 12C64.666 13.0609 65.0874 14.0783 65.8376 14.8284C66.5877 15.5786 67.6052 16 68.666 16Z" />
|
||||
<path d="M16 43C16.7911 43 17.5645 42.7654 18.2223 42.3259C18.8801 41.8864 19.3928 41.2616 19.6955 40.5307C19.9983 39.7998 20.0775 38.9956 19.9231 38.2196C19.7688 37.4437 19.3878 36.731 18.8284 36.1716C18.269 35.6122 17.5563 35.2312 16.7804 35.0769C16.0044 34.9225 15.2002 35.0017 14.4693 35.3045C13.7384 35.6072 13.1136 36.1199 12.6741 36.7777C12.2346 37.4355 12 38.2089 12 39C12 40.0609 12.4214 41.0783 13.1716 41.8284C13.9217 42.5786 14.9391 43 16 43Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
@ -93,10 +93,13 @@ const saveCanvasWithCheck = () => {
|
||||
const saveResource = () => {
|
||||
wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id)
|
||||
if (styleChangeTimes.value > 0) {
|
||||
snapshotStore.resetStyleChangeTimes()
|
||||
canvasSave(() => {
|
||||
ElMessage.success('保存成功')
|
||||
window.history.pushState({}, '', `#/dvCanvas?dvId=${dvInfo.value.id}`)
|
||||
eventBus.emit('hideArea-canvas-main')
|
||||
nextTick(() => {
|
||||
snapshotStore.resetStyleChangeTimes()
|
||||
canvasSave(() => {
|
||||
ElMessage.success('保存成功')
|
||||
window.history.pushState({}, '', `#/dvCanvas?dvId=${dvInfo.value.id}`)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,473 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
import { layerStoreWithOut } from '@/store/modules/data-visualization/layer'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ElIcon, ElRow } from 'element-plus-secondary'
|
||||
import Icon from '../icon-custom/src/Icon.vue'
|
||||
import { nextTick, ref } from 'vue'
|
||||
import draggable from 'vuedraggable'
|
||||
import { lockStoreWithOut } from '@/store/modules/data-visualization/lock'
|
||||
import ContextMenuAsideDetails from '@/components/data-visualization/canvas/ContextMenuAsideDetails.vue'
|
||||
import ComposeShow from '@/components/data-visualization/canvas/ComposeShow.vue'
|
||||
import { composeStoreWithOut } from '@/store/modules/data-visualization/compose'
|
||||
const dropdownMore = ref(null)
|
||||
const lockStore = lockStoreWithOut()
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const layerStore = layerStoreWithOut()
|
||||
const composeStore = composeStoreWithOut()
|
||||
|
||||
const { areaData, isCtrlOrCmdDown, isShiftDown, laterIndex } = storeToRefs(composeStore)
|
||||
|
||||
const { componentData, curComponent, canvasViewInfo } = storeToRefs(dvMainStore)
|
||||
const getComponent = index => {
|
||||
return componentData.value[componentData.value.length - 1 - index]
|
||||
}
|
||||
const transformIndex = index => {
|
||||
return componentData.value.length - 1 - index
|
||||
}
|
||||
const areaDataPush = component => {
|
||||
if (component && !component.isLock && component.isShow) {
|
||||
areaData.value.components.push(component)
|
||||
}
|
||||
}
|
||||
// shift 选择算法逻辑
|
||||
// 1.记录上次点击的laterIndex(初始状态laterIndex=0);
|
||||
// 2.获取当前index curClickIndex;
|
||||
// 3.比较laterIndex 和 curClickIndex之间的大小;
|
||||
// 4.将[laterIndex,curClickIndex] 或者 [curClickIndex,laterIndex]区域的图层加入areaData.value.components(已包含的不再重复加入);
|
||||
const shiftDataPush = curClickIndex => {
|
||||
const areaDataIdArray = areaData.value.components.map(com => com.id)
|
||||
let indexBegin, indexEnd
|
||||
const laterIndexTrans = laterIndex.value === null ? componentData.value.length : laterIndex.value
|
||||
if (laterIndexTrans < curClickIndex) {
|
||||
indexBegin = laterIndexTrans
|
||||
indexEnd = curClickIndex
|
||||
} else {
|
||||
indexBegin = curClickIndex
|
||||
indexEnd = laterIndexTrans
|
||||
}
|
||||
const shiftAreaComponents = componentData.value
|
||||
.slice(indexBegin, indexEnd + 1)
|
||||
.filter(
|
||||
component => !areaDataIdArray.includes(component.id) && !component.isLock && component.isShow
|
||||
)
|
||||
areaData.value.components.push(...shiftAreaComponents)
|
||||
dvMainStore.setCurComponent({ component: null, index: null })
|
||||
}
|
||||
|
||||
const onClick = (e, index) => {
|
||||
// 初始化点击是 laterIndex=0
|
||||
if (!curComponent.value) {
|
||||
composeStore.setLaterIndex(null)
|
||||
}
|
||||
// ctrl or command 按下时 鼠标点击为选择需要组合的组件(取消需要组合的组件在ComposeShow组件中)
|
||||
if (isCtrlOrCmdDown.value && !areaData.value.components.includes(componentData.value[index])) {
|
||||
areaDataPush(componentData.value[index])
|
||||
if (curComponent.value && curComponent.value.id !== componentData.value[index].id) {
|
||||
areaDataPush(curComponent.value)
|
||||
}
|
||||
dvMainStore.setCurComponent({ component: null, index: null })
|
||||
e.stopPropagation()
|
||||
composeStore.setLaterIndex(index)
|
||||
return
|
||||
}
|
||||
//shift操作逻辑
|
||||
if (isShiftDown.value) {
|
||||
shiftDataPush(index)
|
||||
return
|
||||
}
|
||||
|
||||
//其他情况点击清理选择区域
|
||||
areaData.value.components.splice(0, areaData.value.components.length)
|
||||
setCurComponent(index)
|
||||
composeStore.setLaterIndex(index)
|
||||
}
|
||||
const setCurComponent = index => {
|
||||
dvMainStore.setCurComponent({ component: componentData.value[index], index })
|
||||
}
|
||||
|
||||
let nameEdit = ref(false)
|
||||
let editComponentId = ref('')
|
||||
let inputName = ref('')
|
||||
let nameInput = ref(null)
|
||||
let curEditComponent = null
|
||||
const editComponentName = item => {
|
||||
curEditComponent = curComponent.value
|
||||
editComponentId.value = `#component-label-${item.id}`
|
||||
nameEdit.value = true
|
||||
inputName.value = item.name
|
||||
nextTick(() => {
|
||||
nameInput.value.focus()
|
||||
})
|
||||
}
|
||||
const closeEditComponentName = () => {
|
||||
nameEdit.value = false
|
||||
if (!inputName.value || !inputName.value.trim()) {
|
||||
return
|
||||
}
|
||||
if (inputName.value.trim() === curEditComponent.name) {
|
||||
return
|
||||
}
|
||||
curEditComponent.name = inputName.value
|
||||
inputName.value = ''
|
||||
curEditComponent = null
|
||||
}
|
||||
|
||||
const lock = () => {
|
||||
setTimeout(() => {
|
||||
lockStore.lock()
|
||||
snapshotStore.recordSnapshotCache('realTime-lock')
|
||||
})
|
||||
}
|
||||
|
||||
const unlock = () => {
|
||||
setTimeout(() => {
|
||||
lockStore.unlock()
|
||||
snapshotStore.recordSnapshotCache('realTime-unlock')
|
||||
})
|
||||
}
|
||||
|
||||
const hideComponent = () => {
|
||||
setTimeout(() => {
|
||||
layerStore.hideComponent()
|
||||
snapshotStore.recordSnapshotCache('realTime-hideComponent')
|
||||
})
|
||||
}
|
||||
|
||||
const showComponent = () => {
|
||||
setTimeout(() => {
|
||||
layerStore.showComponent()
|
||||
snapshotStore.recordSnapshotCache()
|
||||
})
|
||||
}
|
||||
|
||||
const dragOnEnd = ({ oldIndex, newIndex }) => {
|
||||
const source = componentData.value[newIndex]
|
||||
const comLength = componentData.value.length
|
||||
// 还原数组
|
||||
componentData.value.splice(newIndex, 1)
|
||||
componentData.value.splice(oldIndex, 0, source)
|
||||
const target = componentData.value[comLength - 1 - oldIndex]
|
||||
// 反向移动数组
|
||||
componentData.value.splice(comLength - 1 - oldIndex, 1)
|
||||
componentData.value.splice(comLength - 1 - newIndex, 0, target)
|
||||
dvMainStore.setCurComponent({ component: target, index: transformIndex(comLength - oldIndex) })
|
||||
}
|
||||
|
||||
const getIconName = item => {
|
||||
if (item.component === 'UserView') {
|
||||
const viewInfo = canvasViewInfo.value[item.id]
|
||||
return `${viewInfo.type}-origin`
|
||||
} else {
|
||||
return item.icon
|
||||
}
|
||||
}
|
||||
|
||||
const menuAsideClose = (param, index) => {
|
||||
const iconDom = document.getElementById('close-button')
|
||||
if (iconDom) {
|
||||
iconDom.click()
|
||||
}
|
||||
if (param.opt === 'rename') {
|
||||
setTimeout(() => {
|
||||
editComponentName(getComponent(index))
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
const handleContextMenu = e => {
|
||||
e.preventDefault()
|
||||
// 获取鼠标点击位置
|
||||
const x = e.clientX
|
||||
const y = e.clientY
|
||||
const customContextMenu = document.createElement('div')
|
||||
customContextMenu.style.position = 'fixed'
|
||||
customContextMenu.style.left = x + 'px'
|
||||
customContextMenu.style.top = y + 'px'
|
||||
|
||||
// 将自定义菜单添加到页面
|
||||
document.body.appendChild(customContextMenu)
|
||||
|
||||
// 为自定义菜单添加事件监听器,例如,点击菜单项后执行的操作
|
||||
customContextMenu.addEventListener('click', () => {
|
||||
// 在这里执行菜单项点击后的操作
|
||||
// 例如,关闭菜单
|
||||
document.body.removeChild(customContextMenu)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!--为了保持图层视觉上的一致性 这里进行数组的倒序排列 相应的展示和移动按照倒序处理-->
|
||||
<div class="real-time-component-list">
|
||||
<button hidden="true" id="close-button"></button>
|
||||
<el-row class="list-wrap">
|
||||
<div class="list-container" @contextmenu="handleContextMenu">
|
||||
<draggable
|
||||
@end="dragOnEnd"
|
||||
:list="componentData"
|
||||
animation="100"
|
||||
class="drag-list"
|
||||
item-key="id"
|
||||
>
|
||||
<template #item="{ index }">
|
||||
<div
|
||||
:title="getComponent(index)?.name"
|
||||
class="component-item"
|
||||
:class="{
|
||||
'container-item-not-show': !getComponent(index)?.isShow,
|
||||
activated:
|
||||
(curComponent && curComponent?.id === getComponent(index)?.id) ||
|
||||
areaData.components.includes(getComponent(index))
|
||||
}"
|
||||
@click="onClick($event, transformIndex(index))"
|
||||
>
|
||||
<el-icon class="component-icon">
|
||||
<Icon :name="getIconName(getComponent(index))"></Icon>
|
||||
</el-icon>
|
||||
<span
|
||||
:id="`component-label-${getComponent(index)?.id}`"
|
||||
class="component-label"
|
||||
@dblclick="editComponentName(getComponent(index))"
|
||||
>
|
||||
{{ getComponent(index)?.name }}
|
||||
</span>
|
||||
<div
|
||||
v-show="!nameEdit || (nameEdit && curComponent?.id !== getComponent(index)?.id)"
|
||||
class="icon-container"
|
||||
:class="{
|
||||
'icon-container-lock': getComponent(index)?.isLock && getComponent(index)?.isShow,
|
||||
'icon-container-show': !getComponent(index)?.isShow
|
||||
}"
|
||||
>
|
||||
<el-icon
|
||||
class="component-base component-icon-display"
|
||||
v-show="!getComponent(index).isShow"
|
||||
@click="showComponent"
|
||||
>
|
||||
<Icon name="dv-eye-close" class="opt-icon"></Icon>
|
||||
</el-icon>
|
||||
<el-icon
|
||||
class="component-base"
|
||||
v-show="getComponent(index)?.isShow"
|
||||
@click="hideComponent"
|
||||
>
|
||||
<Icon name="dv-show" class="opt-icon"></Icon>
|
||||
</el-icon>
|
||||
<el-icon v-show="!getComponent(index)?.isLock" class="component-base" @click="lock">
|
||||
<Icon class="opt-icon" name="dv-unlock"></Icon>
|
||||
</el-icon>
|
||||
<el-icon
|
||||
class="component-base component-icon-display"
|
||||
v-show="getComponent(index)?.isLock"
|
||||
@click="unlock"
|
||||
>
|
||||
<Icon name="dv-lock" class="opt-icon"></Icon>
|
||||
</el-icon>
|
||||
<el-dropdown
|
||||
ref="dropdownMore"
|
||||
trigger="click"
|
||||
placement="bottom-start"
|
||||
effect="dark"
|
||||
:hide-timeout="0"
|
||||
>
|
||||
<span :class="'dropdownMore-' + index" @click="onClick(transformIndex(index))">
|
||||
<el-icon class="component-base">
|
||||
<Icon name="dv-more" class="opt-icon"></Icon>
|
||||
</el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<context-menu-aside-details
|
||||
:element="getComponent(index)"
|
||||
@close="menuAsideClose($event, index)"
|
||||
></context-menu-aside-details>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<el-dropdown
|
||||
class="compose-dropdown"
|
||||
trigger="contextmenu"
|
||||
placement="bottom-start"
|
||||
effect="dark"
|
||||
:hide-timeout="0"
|
||||
>
|
||||
<compose-show
|
||||
:show-border="false"
|
||||
:element-index="transformIndex(index)"
|
||||
:element="getComponent(index)"
|
||||
></compose-show>
|
||||
<template #dropdown>
|
||||
<context-menu-aside-details
|
||||
:element="getComponent(index)"
|
||||
@close="menuAsideClose($event, index)"
|
||||
></context-menu-aside-details>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
<el-row style="width: 100%; height: 150px"></el-row>
|
||||
</div>
|
||||
</el-row>
|
||||
<Teleport v-if="editComponentId && nameEdit" :to="editComponentId">
|
||||
<input
|
||||
@keydown.stop
|
||||
@keyup.stop
|
||||
ref="nameInput"
|
||||
v-model="inputName"
|
||||
@blur="closeEditComponentName"
|
||||
/>
|
||||
</Teleport>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.real-time-component-list {
|
||||
white-space: nowrap;
|
||||
.list-wrap {
|
||||
max-height: calc(100% - @component-toolbar-height);
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
.list-container {
|
||||
width: 100%;
|
||||
.component-item {
|
||||
position: relative;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
cursor: grab;
|
||||
color: @dv-canvas-main-font-color;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
font-size: 12px;
|
||||
padding: 0 2px 0 22px;
|
||||
user-select: none;
|
||||
|
||||
.component-icon {
|
||||
color: #a6a6a6;
|
||||
font-size: 14px;
|
||||
}
|
||||
.component-label {
|
||||
color: #ebebeb;
|
||||
}
|
||||
|
||||
> span.component-label {
|
||||
font-size: 12px;
|
||||
margin-left: 10px;
|
||||
position: relative;
|
||||
min-width: 65px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
input {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: white;
|
||||
outline: none;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
padding: 0 4px;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(235, 235, 235, 0.1);
|
||||
|
||||
.icon-container {
|
||||
.component-base {
|
||||
opacity: 1;
|
||||
}
|
||||
width: 70px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
.component-base {
|
||||
opacity: 0;
|
||||
}
|
||||
width: 0px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
cursor: none;
|
||||
i {
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.activated {
|
||||
background-color: var(--ed-color-primary-1a, rgba(51, 112, 255, 0.1)) !important;
|
||||
:deep(.component-icon) {
|
||||
color: var(--ed-color-primary);
|
||||
}
|
||||
:deep(.component-label) {
|
||||
color: var(--ed-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.real-time-component-list :deep(.ed-popper) {
|
||||
background: #303133 !important;
|
||||
}
|
||||
|
||||
.component-base {
|
||||
cursor: pointer;
|
||||
height: 22px !important;
|
||||
width: 22px !important;
|
||||
border-radius: 4px;
|
||||
padding: 0 4px;
|
||||
|
||||
.opt-icon {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(235, 235, 235, 0.1);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: rgba(235, 235, 235, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.component-icon-display {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.icon-container-show {
|
||||
width: 70px !important;
|
||||
}
|
||||
|
||||
.icon-container-lock {
|
||||
width: 45px !important;
|
||||
}
|
||||
|
||||
.container-item-not-show {
|
||||
color: #5f5f5f !important;
|
||||
:deep(.component-icon) {
|
||||
color: #5f5f5f !important;
|
||||
}
|
||||
:deep(.component-label) {
|
||||
color: #5f5f5f !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
.compose-dropdown {
|
||||
position: initial !important;
|
||||
}
|
||||
</style>
|
@ -1380,6 +1380,11 @@ const groupAreaClickChange = async () => {
|
||||
groupAreaCom.style.top = areaData.value.style.top
|
||||
groupAreaCom.style.width = areaData.value.style.width
|
||||
groupAreaCom.style.height = areaData.value.style.height
|
||||
dvMainStore.setClickComponentStatus(true)
|
||||
dvMainStore.setCurComponent({
|
||||
component: groupAreaCom,
|
||||
index: dvMainStore.componentData.length - 1
|
||||
})
|
||||
} else if (groupAreaCom) {
|
||||
groupAreaHis.forEach(ele => {
|
||||
dvMainStore.deleteComponentById(ele.id)
|
||||
|
@ -37,7 +37,7 @@ const handleMouseDown = e => {
|
||||
return
|
||||
}
|
||||
const index = areaData.value.components.findIndex(component => component === props.element)
|
||||
if (index != -1) {
|
||||
if (index != -1 && props.element.component !== 'GroupArea') {
|
||||
areaData.value.components.splice(index, 1)
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
@ -424,7 +424,6 @@ const handleInnerMouseDownOnShape = e => {
|
||||
if (curComponent.value && curComponent.value.id !== element.value.id) {
|
||||
areaDataPush(curComponent.value)
|
||||
}
|
||||
dvMainStore.setCurComponent({ component: null, index: null })
|
||||
e.stopPropagation()
|
||||
return
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import { i18n } from '@/plugins/vue-i18n'
|
||||
import * as Vue from 'vue'
|
||||
import axios from 'axios'
|
||||
import * as Pinia from 'pinia'
|
||||
import * as vueI18n from 'vue-i18n'
|
||||
import * as vueRouter from 'vue-router'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
|
||||
@ -82,7 +81,11 @@ const storeCacheProxy = byteArray => {
|
||||
}
|
||||
const pluginProxy = ref(null)
|
||||
const invokeMethod = param => {
|
||||
pluginProxy.value['invokeMethod'](param)
|
||||
if (pluginProxy.value['invokeMethod']) {
|
||||
pluginProxy.value['invokeMethod'](param)
|
||||
} else {
|
||||
pluginProxy.value[param.methodName](param.args)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@ -96,17 +99,16 @@ onMounted(async () => {
|
||||
distributed = wsCache.get(key)
|
||||
}
|
||||
if (distributed) {
|
||||
window['Vue'] = Vue
|
||||
window['Axios'] = axios
|
||||
window['Pinia'] = Pinia
|
||||
window['vueI18n'] = vueI18n
|
||||
window['vueRouter'] = vueRouter
|
||||
window['MittAll'] = useEmitt().emitter.all
|
||||
window['i18n'] = i18n
|
||||
if (window['DEXPack']) {
|
||||
const xpack = await window['DEXPack'].mapping[attrs.jsname]
|
||||
plugin.value = xpack.default
|
||||
} else {
|
||||
window['Vue'] = Vue
|
||||
window['Axios'] = axios
|
||||
window['Pinia'] = Pinia
|
||||
window['vueRouter'] = vueRouter
|
||||
window['MittAll'] = useEmitt().emitter.all
|
||||
window['I18n'] = i18n
|
||||
loadDistributed().then(async res => {
|
||||
new Function(res.data)()
|
||||
const xpack = await window['DEXPack'].mapping[attrs.jsname]
|
||||
@ -125,7 +127,13 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component ref="pluginProxy" :is="plugin" v-loading="loading" v-bind="attrs"></component>
|
||||
<component
|
||||
:key="attrs.jsname"
|
||||
ref="pluginProxy"
|
||||
:is="plugin"
|
||||
v-loading="loading"
|
||||
v-bind="attrs"
|
||||
></component>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
@ -371,14 +371,9 @@ const linkageFieldAdaptor = async data => {
|
||||
if (state.curLinkageViewInfo.tableId === targetChartDetails.tableId) {
|
||||
const curCheckAllAxisStr =
|
||||
JSON.stringify(state.curLinkageViewInfo.xAxis) +
|
||||
JSON.stringify(state.curLinkageViewInfo.xAxisExt) +
|
||||
JSON.stringify(state.curLinkageViewInfo.yAxis) +
|
||||
JSON.stringify(state.curLinkageViewInfo.yAxisExt)
|
||||
JSON.stringify(state.curLinkageViewInfo.xAxisExt)
|
||||
const targetCheckAllAxisStr =
|
||||
JSON.stringify(targetChartDetails.xAxis) +
|
||||
JSON.stringify(targetChartDetails.xAxisExt) +
|
||||
JSON.stringify(targetChartDetails.yAxis) +
|
||||
JSON.stringify(targetChartDetails.yAxisExt)
|
||||
JSON.stringify(targetChartDetails.xAxis) + JSON.stringify(targetChartDetails.xAxisExt)
|
||||
state.sourceLinkageInfo.targetViewFields.forEach(item => {
|
||||
if (curCheckAllAxisStr.includes(item.id) && targetCheckAllAxisStr.includes(item.id)) {
|
||||
addLinkageField(item.id, item.id)
|
||||
@ -395,9 +390,7 @@ const sourceLinkageInfoFilter = computed(() => {
|
||||
if (state.sourceLinkageInfo.targetViewFields) {
|
||||
const curCheckAllAxisStr =
|
||||
JSON.stringify(state.curLinkageViewInfo.xAxis) +
|
||||
JSON.stringify(state.curLinkageViewInfo.xAxisExt) +
|
||||
JSON.stringify(state.curLinkageViewInfo.yAxis) +
|
||||
JSON.stringify(state.curLinkageViewInfo.yAxisExt)
|
||||
JSON.stringify(state.curLinkageViewInfo.xAxisExt)
|
||||
return state.sourceLinkageInfo.targetViewFields.filter(item =>
|
||||
curCheckAllAxisStr.includes(item.id)
|
||||
)
|
||||
|
@ -8,7 +8,12 @@
|
||||
trigger="click"
|
||||
>
|
||||
<div class="export-button">
|
||||
<el-select v-if="optType === 'enlarge'" v-model="pixel" class="pixel-select" size="small">
|
||||
<el-select
|
||||
v-if="optType === 'enlarge' && authShow"
|
||||
v-model="pixel"
|
||||
class="pixel-select"
|
||||
size="small"
|
||||
>
|
||||
<el-option-group v-for="group in pixelOptions" :key="group.label" :label="group.label">
|
||||
<el-option
|
||||
v-for="item in group.options"
|
||||
@ -21,7 +26,7 @@
|
||||
|
||||
<el-button
|
||||
class="m-button"
|
||||
v-if="optType === 'enlarge'"
|
||||
v-if="optType === 'enlarge' && authShow"
|
||||
link
|
||||
icon="Download"
|
||||
size="middle"
|
||||
@ -31,7 +36,7 @@
|
||||
</el-button>
|
||||
<el-button
|
||||
class="m-button"
|
||||
v-if="optType === 'details'"
|
||||
v-if="optType === 'details' && authShow"
|
||||
link
|
||||
icon="Download"
|
||||
size="middle"
|
||||
@ -40,7 +45,7 @@
|
||||
>
|
||||
导出Excel
|
||||
</el-button>
|
||||
<el-divider class="close-divider" direction="vertical" />
|
||||
<el-divider class="close-divider" direction="vertical" v-if="authShow" />
|
||||
</div>
|
||||
<div
|
||||
v-loading="downLoading"
|
||||
@ -93,7 +98,7 @@ const viewContainer = ref(null)
|
||||
const { t } = useI18n()
|
||||
const optType = ref(null)
|
||||
const chartComponentDetails = ref(null)
|
||||
const { dvInfo } = storeToRefs(dvMainStore)
|
||||
const { dvInfo, editMode } = storeToRefs(dvMainStore)
|
||||
const exportLoading = ref(false)
|
||||
const sourceViewType = ref()
|
||||
const DETAIL_TABLE_ATTR: DeepPartial<ChartObj> = {
|
||||
@ -111,10 +116,15 @@ const DETAIL_TABLE_ATTR: DeepPartial<ChartObj> = {
|
||||
tableItemBgColor: '#FFFFFF',
|
||||
tableFontColor: '#7C7E81',
|
||||
enableTableCrossBG: false
|
||||
},
|
||||
tooltip: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const authShow = computed(() => editMode.value === 'edit' || dvInfo.value.weight > 3)
|
||||
|
||||
const customExport = computed(() => {
|
||||
if (downLoading.value) {
|
||||
const bashStyle = pixel.value.split(' * ')
|
||||
@ -204,8 +214,8 @@ const downloadViewDetails = () => {
|
||||
exportLoading.value = true
|
||||
exportExcelDownload(chart, () => {
|
||||
openMessageLoading(exportData)
|
||||
exportLoading.value = false
|
||||
})
|
||||
exportLoading.value = false
|
||||
}
|
||||
|
||||
const exportData = () => {
|
||||
|
@ -16,8 +16,8 @@ export const STREAMMEDIALINKS = {
|
||||
isLive: false,
|
||||
cors: true, // 允许跨域
|
||||
loop: true,
|
||||
autoplay: false
|
||||
// url: null // 网络动画视频
|
||||
autoplay: false,
|
||||
url: null // 网络动画视频
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,21 +26,20 @@ export const VIDEO_LINKS_DE2 = {
|
||||
videoType: 'web',
|
||||
poster: null,
|
||||
web: {
|
||||
width: '100%', //播放器宽度
|
||||
height: '100%', //播放器高度
|
||||
color: '#409eff', //主题色
|
||||
title: '', //视频名称
|
||||
src: null, //视频源
|
||||
muted: false, //静音
|
||||
webFullScreen: false,
|
||||
speedRate: ['0.75', '1.0', '1.25', '1.5', '2.0'], //播放倍速
|
||||
autoPlay: true, //自动播放
|
||||
loop: false, //循环播放
|
||||
mirror: false, //镜像画面
|
||||
lightOff: false, //关灯模式
|
||||
volume: 0.3, //默认音量大小
|
||||
control: true, //是否显示控制
|
||||
controlBtns: ['audioTrack', 'quality', 'volume', 'fullScreen'] //显示所有按钮,
|
||||
autoplay: true, // 如果true,浏览器准备好时开始回放。
|
||||
muted: true, // 默认情况下将会消除任何音频。
|
||||
loop: true, // 导致视频一结束就重新开始。
|
||||
preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
|
||||
language: 'zh-CN',
|
||||
fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
|
||||
notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
|
||||
controls: true,
|
||||
controlBar: {
|
||||
timeDivider: true,
|
||||
remainingTimeDisplay: false,
|
||||
fullscreenToggle: true // 全屏按钮
|
||||
}
|
||||
},
|
||||
rtmp: {
|
||||
sources: [
|
||||
@ -209,7 +208,7 @@ const list = [
|
||||
name: '查询',
|
||||
label: '查询',
|
||||
propValue: '',
|
||||
icon: 'other_text',
|
||||
icon: 'icon_search',
|
||||
innerType: 'VQuery',
|
||||
isHang: false,
|
||||
x: 1,
|
||||
|
@ -21,7 +21,7 @@
|
||||
<script lang="ts" setup>
|
||||
import flvjs from 'flv.js'
|
||||
import '@/style/custom-theme.css'
|
||||
import { onMounted, reactive, toRefs, getCurrentInstance } from 'vue'
|
||||
import { onMounted, reactive, toRefs, getCurrentInstance, nextTick, onBeforeUnmount } from 'vue'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
const { t } = useI18n()
|
||||
@ -76,25 +76,29 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
const initOption = () => {
|
||||
if (flvjs.isSupported() && state.pOption.url) {
|
||||
destroyPlayer()
|
||||
const video = currentInstance.proxy.$refs['player-' + element.value.id]
|
||||
if (video) {
|
||||
try {
|
||||
state.flvPlayer = flvjs.createPlayer(state.pOption, {
|
||||
enableWorker: false, // 不启用分离线程
|
||||
enableStashBuffer: false, // 关闭IO隐藏缓冲区
|
||||
isLive: state.pOption.isLive,
|
||||
lazyLoad: false
|
||||
})
|
||||
state.flvPlayer.attachMediaElement(video)
|
||||
state.flvPlayer.load()
|
||||
state.flvPlayer.play()
|
||||
} catch (error) {
|
||||
console.error('flvjs err ignore', error)
|
||||
state.pOption = element.value.streamMediaLinks[element.value.streamMediaLinks.videoType]
|
||||
delete state.pOption.segments
|
||||
nextTick(() => {
|
||||
if (flvjs.isSupported() && state.pOption.url) {
|
||||
destroyPlayer()
|
||||
const video = currentInstance.proxy.$refs['player-' + element.value.id]
|
||||
if (video) {
|
||||
try {
|
||||
state.flvPlayer = flvjs.createPlayer(state.pOption, {
|
||||
enableWorker: false, // 不启用分离线程
|
||||
enableStashBuffer: false, // 关闭IO隐藏缓冲区
|
||||
isLive: state.pOption.isLive,
|
||||
lazyLoad: false
|
||||
})
|
||||
state.flvPlayer.attachMediaElement(video)
|
||||
state.flvPlayer.load()
|
||||
state.flvPlayer.play()
|
||||
} catch (error) {
|
||||
console.error('flvjs err ignore', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const destroyPlayer = () => {
|
||||
@ -105,6 +109,10 @@ const destroyPlayer = () => {
|
||||
state.flvPlayer = null
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
destroyPlayer()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-row ref="mainPlayer">
|
||||
<div v-if="element.videoLinks[element.videoLinks.videoType].src" class="player">
|
||||
<video-play v-bind="playerOptions" />
|
||||
<VideoPlayer :src="playerOptions.src" :options="playerOptions" />
|
||||
</div>
|
||||
<div v-else class="info-class">
|
||||
<span>{{ t('visualization.video_add_tips') }}</span>
|
||||
@ -10,8 +10,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { videoPlay } from 'vue3-video-play/lib/index' // 引入组件
|
||||
import 'vue3-video-play/dist/style.css' // 引入css
|
||||
import { VideoPlayer } from '@videojs-player/vue'
|
||||
import 'video.js/dist/video-js.css'
|
||||
import { computed, nextTick, reactive, toRefs, watch, onMounted, ref } from 'vue'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
|
@ -5,7 +5,7 @@
|
||||
<el-switch
|
||||
:effect="themes"
|
||||
@change="onChange"
|
||||
v-model="state.linkInfoTemp[state.linkInfoTemp.videoType].autoPlay"
|
||||
v-model="state.linkInfoTemp[state.linkInfoTemp.videoType].autoplay"
|
||||
size="mini"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
@ -81,14 +81,14 @@ const clearStyle = e => {
|
||||
}
|
||||
|
||||
const handleBlur = e => {
|
||||
element.value.propValue = e.target.innerHTML || ' '
|
||||
element.value.propValue = e.target.innerHTML || ''
|
||||
const html = e.target.innerHTML
|
||||
if (html !== '') {
|
||||
element.value.propValue = e.target.innerHTML
|
||||
} else {
|
||||
element.value.propValue = ''
|
||||
nextTick(function () {
|
||||
element.value.propValue = ' '
|
||||
element.value.propValue = ''
|
||||
})
|
||||
}
|
||||
canEdit.value = false
|
||||
|
@ -389,7 +389,7 @@ const autoStyle = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="v-query-container" :style="autoStyle">
|
||||
<div class="v-query-container" :style="autoStyle" @keydown.stop @keyup.stop>
|
||||
<p v-if="customStyle.titleShow" class="title" :style="titleStyle">
|
||||
{{ customStyle.title }}
|
||||
</p>
|
||||
@ -423,8 +423,8 @@ const autoStyle = computed(() => {
|
||||
<el-tooltip effect="dark" :content="ele.name" placement="top">
|
||||
{{ ele.name }}
|
||||
</el-tooltip>
|
||||
<span v-if="ele.required" class="required">*</span>
|
||||
</div>
|
||||
<span v-if="ele.required" class="required">*</span>
|
||||
</div>
|
||||
<div
|
||||
class="label-wrapper-tooltip"
|
||||
@ -573,13 +573,13 @@ const autoStyle = computed(() => {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.required {
|
||||
font-size: 14px;
|
||||
color: #f54a45;
|
||||
margin-left: 3px;
|
||||
line-height: 22px;
|
||||
}
|
||||
.required {
|
||||
font-size: 14px;
|
||||
color: #f54a45;
|
||||
margin-left: 3px;
|
||||
line-height: 22px;
|
||||
}
|
||||
.label-wrapper-tooltip {
|
||||
align-items: center;
|
||||
|
@ -501,7 +501,6 @@ const validate = () => {
|
||||
const isMultiple = +ele.displayType === 7 || ele.multiple
|
||||
ele.selectValue = isMultiple ? [] : undefined
|
||||
ele.defaultValue = isMultiple ? [] : undefined
|
||||
return false
|
||||
}
|
||||
|
||||
if (ele.displayType === '1') {
|
||||
@ -587,7 +586,7 @@ const validate = () => {
|
||||
return false
|
||||
}
|
||||
|
||||
if (ele.optionValueSource === 2 && !ele.valueSource?.length) {
|
||||
if (ele.optionValueSource === 2 && !ele.valueSource?.filter(ele => !!ele).length) {
|
||||
ElMessage.error('手工输入-选项值不能为空')
|
||||
return true
|
||||
}
|
||||
@ -687,6 +686,19 @@ const setConditionOut = () => {
|
||||
init(conditions.value[conditions.value.length - 1].id)
|
||||
}
|
||||
|
||||
const setActiveSelectTab = (arr, id) => {
|
||||
let activelist = 'dimensionList'
|
||||
arr.some((ele, index) => {
|
||||
if ((ele || []).some(itx => itx.id === id)) {
|
||||
activelist = ['dimensionList', 'quotaList', 'parameterList'][index]
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
return activelist
|
||||
}
|
||||
|
||||
const init = (queryId: string) => {
|
||||
if (!datasetTree.value.length) {
|
||||
initDataset()
|
||||
@ -725,7 +737,12 @@ const init = (queryId: string) => {
|
||||
fields.value = datasetFieldList.value
|
||||
.map(ele => {
|
||||
if (!datasetMap[ele.tableId]) return null
|
||||
return { ...datasetMap[ele.tableId], componentId: ele.id }
|
||||
const activeCom = datasetMap[ele.tableId].fields || {}
|
||||
const activelist = setActiveSelectTab(
|
||||
[activeCom.dimensionList, activeCom.quotaList, activeCom.parameterList],
|
||||
curComponent.value.checkedFieldsMap[ele.id]
|
||||
)
|
||||
return { ...datasetMap[ele.tableId], componentId: ele.id, activelist }
|
||||
})
|
||||
.filter(ele => !!ele)
|
||||
})
|
||||
@ -813,6 +830,13 @@ const handleCondition = item => {
|
||||
idMap.includes(ele)
|
||||
)
|
||||
if (!!fields.value?.length) {
|
||||
fields.value.forEach(ele => {
|
||||
const activeCom = ele.fields
|
||||
ele.activelist = setActiveSelectTab(
|
||||
[activeCom.dimensionList, activeCom.quotaList, activeCom.parameterList],
|
||||
curComponent.value.checkedFieldsMap[ele.componentId]
|
||||
)
|
||||
})
|
||||
handleCheckedFieldsChange(curComponent.value.checkedFields)
|
||||
}
|
||||
multipleChange(curComponent.value.multiple)
|
||||
@ -1337,7 +1361,7 @@ defineExpose({
|
||||
value="1"
|
||||
/>
|
||||
<el-option
|
||||
:disabled="!['1', '7'].includes(curComponent.displayType)"
|
||||
:disabled="!['1', '7'].includes(curComponent.displayType) || isTimeParameter"
|
||||
label="时间范围"
|
||||
value="7"
|
||||
/>
|
||||
@ -1544,11 +1568,7 @@ defineExpose({
|
||||
</el-icon>
|
||||
</template>
|
||||
<el-option
|
||||
v-for="ele in curComponent.dataset.fields.filter(
|
||||
ele =>
|
||||
ele.deType === +curComponent.displayType ||
|
||||
([3, 4].includes(ele.deType) && +curComponent.displayType === 2)
|
||||
)"
|
||||
v-for="ele in curComponent.dataset.fields"
|
||||
:key="ele.id"
|
||||
:label="ele.name"
|
||||
:value="ele.id"
|
||||
@ -1603,6 +1623,13 @@ defineExpose({
|
||||
<div :key="index" v-for="(_, index) in valueSource" class="select-item">
|
||||
<el-input
|
||||
maxlength="20"
|
||||
v-if="curComponent.displayType === '2'"
|
||||
@blur="weightlessness"
|
||||
v-model.number="valueSource[index]"
|
||||
></el-input>
|
||||
<el-input
|
||||
maxlength="20"
|
||||
v-else
|
||||
@blur="weightlessness"
|
||||
v-model="valueSource[index]"
|
||||
></el-input>
|
||||
|
@ -334,15 +334,19 @@ watch(
|
||||
|
||||
watch(
|
||||
() => config.value.optionValueSource,
|
||||
val => {
|
||||
debounceOptions(val)
|
||||
(valNew, newOld) => {
|
||||
if ([valNew, newOld].includes(2)) {
|
||||
selectValue.value = Array.isArray(selectValue.value) ? [] : undefined
|
||||
config.value.selectValue = cloneDeep(selectValue.value)
|
||||
config.value.defaultValue = cloneDeep(selectValue.value)
|
||||
}
|
||||
debounceOptions(valNew)
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
[() => config.value.checkedFields, () => config.value.checkedFieldsMap],
|
||||
() => {
|
||||
if (!props.isConfig) return
|
||||
debounceOptions(config.value.optionValueSource)
|
||||
},
|
||||
{
|
||||
|
@ -23,7 +23,8 @@ import AiTips from '@/layout/components/AiTips.vue'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { push } = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
const { wsCache } = useCache('localStorage')
|
||||
const aiBaseUrl = ref(null)
|
||||
const handleIconClick = () => {
|
||||
if (route.path === '/workbranch/index') return
|
||||
@ -69,7 +70,7 @@ const navigateBg = computed(() => appearanceStore.getNavigateBg)
|
||||
const navigate = computed(() => appearanceStore.getNavigate)
|
||||
|
||||
const initAiBase = async () => {
|
||||
const aiTipsCheck = localStorage.getItem('DE-AI-TIPS-CHECK')
|
||||
const aiTipsCheck = wsCache.get('DE-AI-TIPS-CHECK')
|
||||
if (aiTipsCheck === 'CHECKED') {
|
||||
showOverlay.value = false
|
||||
} else {
|
||||
@ -84,7 +85,7 @@ const initAiBase = async () => {
|
||||
}
|
||||
|
||||
const aiTipsConfirm = () => {
|
||||
localStorage.setItem('DE-AI-TIPS-CHECK', 'CHECKED')
|
||||
wsCache.set('DE-AI-TIPS-CHECK', 'CHECKED')
|
||||
showOverlay.value = false
|
||||
}
|
||||
onMounted(() => {
|
||||
|
@ -1,11 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import { ElMain } from 'element-plus-secondary'
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-main>
|
||||
<RouterView />
|
||||
<RouterView :key="route.path" />
|
||||
</el-main>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
@ -2232,6 +2232,7 @@ export default {
|
||||
dsExecuteTime: '数据源检测频率',
|
||||
frontTimeOut: '请求超时时间(秒)',
|
||||
logLiveTime: '操作日志保留时间(天)',
|
||||
exportFileLiveTime: '后台导出文件保留时间(天)',
|
||||
platformOid: '第三方平台用户组织',
|
||||
platformRid: '第三方平台用户角色',
|
||||
pwdStrategy: '开启密码策略',
|
||||
|
@ -491,3 +491,8 @@ strong {
|
||||
color: var(--deSuccess, #34c724);
|
||||
}
|
||||
}
|
||||
|
||||
.vjs-big-play-button {
|
||||
top: calc(50% - 22px) !important;
|
||||
left: calc(50% - 40px) !important;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ let isShiftDown = false
|
||||
// 全局监听按键操作并执行相应命令
|
||||
export function listenGlobalKeyDown() {
|
||||
window.onkeydown = e => {
|
||||
if (!isInEditor.value || editMode.value === 'preview' || checkDialog()) return
|
||||
if (editMode.value === 'preview' || checkDialog()) return
|
||||
const { keyCode } = e
|
||||
if (positionMoveKey[keyCode] && curComponent.value) {
|
||||
positionMoveKey[keyCode](keyCode)
|
||||
|
17
core/core-frontend/src/utils/ParseUrl.ts
Normal file
17
core/core-frontend/src/utils/ParseUrl.ts
Normal file
@ -0,0 +1,17 @@
|
||||
function parseUrl(url) {
|
||||
const [pathname, params] = url.split('?')
|
||||
const [_, path] = pathname.split('#/')
|
||||
return {
|
||||
path,
|
||||
query: params
|
||||
.split('&')
|
||||
.map(ele => ele.split('='))
|
||||
.reduce((pre, next) => {
|
||||
const [key, value] = next
|
||||
pre[key] = value
|
||||
return pre
|
||||
}, {})
|
||||
}
|
||||
}
|
||||
|
||||
export { parseUrl }
|
@ -125,8 +125,14 @@ export const customAttrTrans = {
|
||||
'wordSizeRange',
|
||||
'wordSpacing'
|
||||
],
|
||||
label: ['fontSize'],
|
||||
tooltip: ['fontSize'],
|
||||
label: {
|
||||
fontSize: '',
|
||||
seriesLabelFormatter: ['fontSize']
|
||||
},
|
||||
tooltip: {
|
||||
fontSize: '',
|
||||
seriesTooltipFormatter: ['fontSize']
|
||||
},
|
||||
indicator: ['fontSize', 'suffixFontSize'],
|
||||
indicatorName: ['fontSize', 'nameValueSpacing']
|
||||
}
|
||||
@ -296,15 +302,25 @@ export function recursionTransObj(template, infoObj, scale, terminal) {
|
||||
// 如果是数组 进行赋值计算
|
||||
if (template[templateKey] instanceof Array) {
|
||||
template[templateKey].forEach(templateProp => {
|
||||
if (infoObj[templateKey] && infoObj[templateKey][templateProp]) {
|
||||
if (
|
||||
infoObj[templateKey] &&
|
||||
(infoObj[templateKey][templateProp] || infoObj[templateKey].length)
|
||||
) {
|
||||
// 移动端特殊属性值设置
|
||||
if (terminal === 'mobile' && mobileSpecialProps[templateProp] !== undefined) {
|
||||
infoObj[templateKey][templateProp] = mobileSpecialProps[templateProp]
|
||||
} else {
|
||||
infoObj[templateKey][templateProp] = getScaleValue(
|
||||
infoObj[templateKey][templateProp],
|
||||
scale
|
||||
)
|
||||
// 数组依次设置
|
||||
if (infoObj[templateKey] instanceof Array) {
|
||||
infoObj[templateKey].forEach(v => {
|
||||
v[templateProp] = getScaleValue(v[templateProp], scale)
|
||||
})
|
||||
} else {
|
||||
infoObj[templateKey][templateProp] = getScaleValue(
|
||||
infoObj[templateKey][templateProp],
|
||||
scale
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -152,7 +152,7 @@ export function initCanvasDataPrepare(dvId, busiFlag, callBack) {
|
||||
})
|
||||
}
|
||||
|
||||
export function initCanvasData(dvId, busiFlag, callBack) {
|
||||
export async function initCanvasData(dvId, busiFlag, callBack) {
|
||||
initCanvasDataPrepare(
|
||||
dvId,
|
||||
busiFlag,
|
||||
@ -174,6 +174,48 @@ export function initCanvasData(dvId, busiFlag, callBack) {
|
||||
)
|
||||
}
|
||||
|
||||
export async function backCanvasData(dvId, busiFlag, callBack) {
|
||||
initCanvasDataPrepare(dvId, busiFlag, function ({ canvasDataResult, canvasStyleResult }) {
|
||||
const componentDataCopy = canvasDataResult.filter(ele => !!ele.inMobile)
|
||||
const componentDataId = componentDataCopy.map(ele => ele.id)
|
||||
componentData.value.forEach(ele => {
|
||||
ele.inMobile = componentDataId.includes(ele.id)
|
||||
if (ele.inMobile) {
|
||||
const { mx, my, mSizeX, mSizeY } = componentDataCopy.find(itx => itx.id === ele.id)
|
||||
ele.mx = mx
|
||||
ele.my = my
|
||||
ele.mSizeX = mSizeX
|
||||
ele.mSizeY = mSizeY
|
||||
if (ele.component === 'DeTabs') {
|
||||
ele.propValue.forEach(tabItem => {
|
||||
tabItem.componentData.forEach(tabComponent => {
|
||||
tabComponent.mx = tabComponent.mx
|
||||
tabComponent.my = tabComponent.my
|
||||
tabComponent.mSizeX = tabComponent.mSizeX
|
||||
tabComponent.mSizeY = tabComponent.mSizeY
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
dvMainStore.setComponentData(componentData.value)
|
||||
const canvasStyleDataCopy = cloneDeep(canvasStyleData.value)
|
||||
if (!canvasStyleDataCopy.mobileSetting) {
|
||||
canvasStyleDataCopy.mobileSetting = {
|
||||
backgroundColorSelect: false,
|
||||
background: '',
|
||||
color: '#ffffff',
|
||||
backgroundImageEnable: false,
|
||||
customSetting: false
|
||||
}
|
||||
} else {
|
||||
canvasStyleDataCopy.mobileSetting = canvasStyleResult.mobileSetting
|
||||
}
|
||||
dvMainStore.setCanvasStyle(canvasStyleDataCopy)
|
||||
callBack()
|
||||
})
|
||||
}
|
||||
|
||||
export function initCanvasDataMobile(dvId, busiFlag, callBack) {
|
||||
initCanvasDataPrepare(
|
||||
dvId,
|
||||
|
@ -64,10 +64,15 @@ const changeThreshold = () => {
|
||||
const changeSplitThreshold = (threshold: string) => {
|
||||
// check input
|
||||
if (threshold) {
|
||||
const regex = /^(\d+)(,\d+)*$/
|
||||
if (!regex.test(threshold)) {
|
||||
ElMessage.error(t('chart.gauge_threshold_format_error'))
|
||||
return
|
||||
}
|
||||
const arr = threshold.split(',')
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const ele = arr[i]
|
||||
if (parseFloat(ele).toString() === 'NaN' || parseFloat(ele) <= 0 || parseFloat(ele) >= 100) {
|
||||
if (parseFloat(ele) <= 0 || parseFloat(ele) >= 100) {
|
||||
ElMessage.error(t('chart.gauge_threshold_format_error'))
|
||||
return
|
||||
}
|
||||
|
@ -634,7 +634,7 @@ onMounted(() => {
|
||||
:effect="themes"
|
||||
v-model="state.basicStyleForm.showZoom"
|
||||
:predefine="predefineColors"
|
||||
@change="changeBasicStyle('zoomShow')"
|
||||
@change="changeBasicStyle('showZoom')"
|
||||
>
|
||||
{{ t('chart.show_zoom') }}
|
||||
</el-checkbox>
|
||||
|
@ -101,6 +101,7 @@ onMounted(() => {
|
||||
:themes="themes"
|
||||
type="left"
|
||||
:chart-type="chart.type"
|
||||
:layout="chart.customAttr.basicStyle.layout"
|
||||
@on-change-y-axis-form="changeAxisStyle"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
@ -120,6 +121,7 @@ onMounted(() => {
|
||||
:themes="themes"
|
||||
type="right"
|
||||
:chart-type="chart.type"
|
||||
:layout="chart.customAttr.basicStyle.layout"
|
||||
@on-change-y-axis-form="changeSubAxisStyle"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
@ -14,6 +14,7 @@ const props = withDefaults(
|
||||
propertyInner?: Array<string>
|
||||
type?: 'left' | 'right'
|
||||
chartType?: string
|
||||
layout?: string
|
||||
}>(),
|
||||
{
|
||||
themes: 'dark',
|
||||
@ -75,6 +76,14 @@ const init = () => {
|
||||
|
||||
const showProperty = prop => props.propertyInner?.includes(prop)
|
||||
|
||||
const isBidirectionalBar = computed(() => {
|
||||
return props.chartType === 'bidirectional-bar'
|
||||
})
|
||||
|
||||
const isVerticalLayout = computed(() => {
|
||||
return props.layout === 'vertical'
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
@ -99,9 +108,19 @@ onMounted(() => {
|
||||
size="small"
|
||||
@change="changeAxisStyle('position')"
|
||||
>
|
||||
<div v-if="chartType === 'bidirectional-bar'">
|
||||
<el-radio :effect="props.themes" label="right">{{ t('chart.text_pos_top') }}</el-radio>
|
||||
<el-radio :effect="props.themes" label="left">{{ t('chart.text_pos_bottom') }}</el-radio>
|
||||
<div v-if="isBidirectionalBar">
|
||||
<div v-if="isVerticalLayout">
|
||||
<el-radio :effect="props.themes" label="left">{{ t('chart.text_pos_left') }}</el-radio>
|
||||
<el-radio :effect="props.themes" label="right">{{
|
||||
t('chart.text_pos_right')
|
||||
}}</el-radio>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-radio :effect="props.themes" label="right">{{ t('chart.text_pos_top') }}</el-radio>
|
||||
<el-radio :effect="props.themes" label="left">{{
|
||||
t('chart.text_pos_bottom')
|
||||
}}</el-radio>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-radio :effect="props.themes" label="left">{{ t('chart.text_pos_left') }}</el-radio>
|
||||
@ -309,7 +328,7 @@ onMounted(() => {
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-left: 4px">
|
||||
<el-input-number
|
||||
:disabled="!state.axisForm.splitLine.show"
|
||||
style="width: 74px"
|
||||
style="width: 70px"
|
||||
:effect="props.themes"
|
||||
v-model="state.axisForm.splitLine.lineStyle.width"
|
||||
:min="1"
|
||||
|
@ -220,6 +220,48 @@ const isBarRangeTime = computed<boolean>(() => {
|
||||
}
|
||||
return false
|
||||
})
|
||||
const showPositionH = computed(() => {
|
||||
if (showProperty('hPosition')) {
|
||||
if (props.chart.type !== 'bidirectional-bar') {
|
||||
return true
|
||||
}
|
||||
return props.chart.customAttr.basicStyle.layout === 'horizontal'
|
||||
}
|
||||
return false
|
||||
})
|
||||
const showPositionV = computed(() => {
|
||||
if (showProperty('vPosition')) {
|
||||
if (props.chart.type !== 'bidirectional-bar') {
|
||||
return true
|
||||
}
|
||||
return props.chart.customAttr.basicStyle.layout === 'vertical'
|
||||
}
|
||||
return false
|
||||
})
|
||||
watch(
|
||||
() => props.chart.customAttr.basicStyle.layout,
|
||||
() => {
|
||||
const layout = props.chart.customAttr.basicStyle.layout
|
||||
if (layout === 'horizontal') {
|
||||
if (state?.labelForm?.position === 'top') {
|
||||
state.labelForm.position = 'right'
|
||||
}
|
||||
if (state?.labelForm?.position === 'bottom') {
|
||||
state.labelForm.position = 'left'
|
||||
}
|
||||
}
|
||||
if (layout === 'vertical') {
|
||||
if (state?.labelForm?.position === 'left') {
|
||||
state.labelForm.position = 'bottom'
|
||||
}
|
||||
if (state?.labelForm?.position === 'right') {
|
||||
state.labelForm.position = 'top'
|
||||
}
|
||||
}
|
||||
changeLabelAttr('position')
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
@ -298,7 +340,7 @@ onMounted(() => {
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="showProperty('hPosition')"
|
||||
v-if="showPositionH"
|
||||
:label="t('chart.label_position')"
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
@ -319,7 +361,7 @@ onMounted(() => {
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="showProperty('vPosition')"
|
||||
v-if="showPositionV"
|
||||
:label="t('chart.label_position')"
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
|
@ -100,6 +100,14 @@ const init = () => {
|
||||
|
||||
const showProperty = prop => props.propertyInner?.includes(prop)
|
||||
|
||||
const isBidirectionalBar = computed(() => {
|
||||
return props.chart.type === 'bidirectional-bar'
|
||||
})
|
||||
|
||||
const isHorizontalLayout = computed(() => {
|
||||
return props.chart.customAttr.basicStyle.layout === 'horizontal'
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
@ -124,8 +132,10 @@ onMounted(() => {
|
||||
size="small"
|
||||
@change="changeAxisStyle('position')"
|
||||
>
|
||||
<div v-if="chart.type === 'bidirectional-bar'">
|
||||
<el-radio :effect="props.themes" label="top">{{ t('chart.text_pos_left') }}</el-radio>
|
||||
<div v-if="isBidirectionalBar">
|
||||
<el-radio :effect="props.themes" label="top">{{
|
||||
isHorizontalLayout ? t('chart.text_pos_left') : t('chart.text_pos_top')
|
||||
}}</el-radio>
|
||||
<el-radio :effect="props.themes" label="bottom">{{
|
||||
t('chart.text_pos_center')
|
||||
}}</el-radio>
|
||||
@ -335,7 +345,7 @@ onMounted(() => {
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-left: 4px">
|
||||
<el-input-number
|
||||
:disabled="!state.axisForm.splitLine.show"
|
||||
style="width: 74px"
|
||||
style="width: 70px"
|
||||
:effect="props.themes"
|
||||
v-model="state.axisForm.splitLine.lineStyle.width"
|
||||
:min="1"
|
||||
|
@ -317,7 +317,7 @@ onMounted(() => {
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-left: 4px">
|
||||
<el-input-number
|
||||
:disabled="!state.axisForm.splitLine.show"
|
||||
style="width: 74px"
|
||||
style="width: 70px"
|
||||
:effect="props.themes"
|
||||
v-model="state.axisForm.splitLine.lineStyle.width"
|
||||
:min="1"
|
||||
|
@ -1461,7 +1461,7 @@ export const BASE_VIEW_CONFIG = {
|
||||
type: 'bar',
|
||||
render: 'antv',
|
||||
resultCount: 1000,
|
||||
resultMode: 'all',
|
||||
resultMode: 'custom',
|
||||
refreshViewEnable: false,
|
||||
refreshTime: 5,
|
||||
refreshUnit: 'minute',
|
||||
|
@ -87,7 +87,7 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
|
||||
],
|
||||
'legend-selector': ['icon', 'orient', 'fontSize', 'color', 'hPosition', 'vPosition'],
|
||||
'function-cfg': ['emptyDataStrategy'],
|
||||
'label-selector': ['hPosition', 'seriesLabelFormatter'],
|
||||
'label-selector': ['hPosition', 'vPosition', 'seriesLabelFormatter'],
|
||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter', 'show']
|
||||
}
|
||||
|
||||
@ -339,8 +339,9 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
|
||||
valueExt: undefined
|
||||
}
|
||||
}
|
||||
const layoutHorizontal = options.layout === 'horizontal'
|
||||
// 处理横轴标题方向不对
|
||||
if (yAxis && yAxis['title']) {
|
||||
if (yAxis && yAxis['title'] && layoutHorizontal) {
|
||||
yAxis['title'].autoRotate = false
|
||||
}
|
||||
const yAxisTmp = parseJson(chart.customStyle).yAxis
|
||||
@ -400,6 +401,7 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
|
||||
...chart.customAttr.label,
|
||||
position: 'right'
|
||||
}
|
||||
chart.customAttr.basicStyle.layout = 'horizontal'
|
||||
return chart
|
||||
}
|
||||
|
||||
@ -413,6 +415,7 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
|
||||
return pre
|
||||
}, {})
|
||||
let customAttr: DeepPartial<ChartAttr>
|
||||
const layoutHorizontal = options.layout === 'horizontal'
|
||||
if (chart.customAttr) {
|
||||
customAttr = parseJson(chart.customAttr)
|
||||
// label
|
||||
@ -448,7 +451,33 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
|
||||
} else {
|
||||
res = valueFormatter(value, l.labelFormatter)
|
||||
}
|
||||
return res
|
||||
const group = new G2PlotChartView.engine.Group({})
|
||||
const isValue = param['series-field-key'] === 'value'
|
||||
const textAlign = isValue && layoutHorizontal ? 'end' : 'start'
|
||||
const isMiddle = label.position === 'middle'
|
||||
group.addShape({
|
||||
type: 'text',
|
||||
attrs: {
|
||||
x:
|
||||
isValue && layoutHorizontal && !isMiddle
|
||||
? -6
|
||||
: !isValue && layoutHorizontal && !isMiddle
|
||||
? 6
|
||||
: 0,
|
||||
y:
|
||||
isValue && !layoutHorizontal && !isMiddle
|
||||
? -8
|
||||
: !isValue && !layoutHorizontal && !isMiddle
|
||||
? 8
|
||||
: 0,
|
||||
text: res,
|
||||
textAlign: label.position === 'middle' ? 'start' : textAlign,
|
||||
textBaseline: 'top',
|
||||
fontSize: labelCfg.fontSize,
|
||||
fill: labelCfg.color
|
||||
}
|
||||
})
|
||||
return group
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -456,6 +485,14 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!layoutHorizontal) {
|
||||
if (label.position === 'left') {
|
||||
label.position = 'bottom'
|
||||
}
|
||||
if (label.position === 'right') {
|
||||
label.position = 'top'
|
||||
}
|
||||
}
|
||||
return { ...options, label }
|
||||
}
|
||||
|
||||
|
@ -86,24 +86,25 @@ export class Area extends G2PlotChartView<AreaOptions, G2Area> {
|
||||
|
||||
drawChart(drawOptions: G2PlotDrawOptions<G2Area>): G2Area {
|
||||
const { chart, container, action } = drawOptions
|
||||
if (chart?.data) {
|
||||
// data
|
||||
const data = cloneDeep(chart.data.data)
|
||||
|
||||
const initOptions: AreaOptions = {
|
||||
...this.baseOptions,
|
||||
data,
|
||||
appendPadding: getPadding(chart)
|
||||
}
|
||||
// options
|
||||
const options = this.setupOptions(chart, initOptions)
|
||||
// 开始渲染
|
||||
const newChart = new G2Area(container, options)
|
||||
|
||||
newChart.on('point:click', action)
|
||||
|
||||
return newChart
|
||||
if (!chart.data.data?.length) {
|
||||
return
|
||||
}
|
||||
// data
|
||||
const data = cloneDeep(chart.data.data)
|
||||
|
||||
const initOptions: AreaOptions = {
|
||||
...this.baseOptions,
|
||||
data,
|
||||
appendPadding: getPadding(chart)
|
||||
}
|
||||
// options
|
||||
const options = this.setupOptions(chart, initOptions)
|
||||
// 开始渲染
|
||||
const newChart = new G2Area(container, options)
|
||||
|
||||
newChart.on('point:click', action)
|
||||
|
||||
return newChart
|
||||
}
|
||||
|
||||
protected configLabel(chart: Chart, options: AreaOptions): AreaOptions {
|
||||
|
@ -260,57 +260,63 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
||||
...options
|
||||
}
|
||||
|
||||
tempOption.yAxis = {}
|
||||
if (!yAxis) {
|
||||
//左右轴都要隐藏
|
||||
tempOption.yAxis = {
|
||||
value: false,
|
||||
valueExt: false
|
||||
}
|
||||
tempOption.yAxis.value = false
|
||||
} else {
|
||||
tempOption.yAxis = {
|
||||
value: undefined,
|
||||
valueExt: undefined
|
||||
tempOption.yAxis.value = undefined
|
||||
yAxis.position = 'left'
|
||||
|
||||
const yAxisTmp = parseJson(chart.customStyle).yAxis
|
||||
if (yAxis.label) {
|
||||
yAxis.label.style.textAlign = 'end'
|
||||
yAxis.label.formatter = value => {
|
||||
return valueFormatter(value, yAxisTmp.axisLabelFormatter)
|
||||
}
|
||||
}
|
||||
const axisValue = yAxisTmp.axisValue
|
||||
if (!axisValue?.auto) {
|
||||
tempOption.yAxis.value = {
|
||||
...yAxis,
|
||||
min: axisValue.min,
|
||||
max: axisValue.max,
|
||||
minLimit: axisValue.min,
|
||||
maxLimit: axisValue.max,
|
||||
tickCount: axisValue.splitCount
|
||||
}
|
||||
} else {
|
||||
tempOption.yAxis.value = yAxis
|
||||
}
|
||||
}
|
||||
|
||||
const yAxisTmp = parseJson(chart.customStyle).yAxis
|
||||
if (yAxis.label) {
|
||||
yAxis.label.formatter = value => {
|
||||
return valueFormatter(value, yAxisTmp.axisLabelFormatter)
|
||||
}
|
||||
}
|
||||
const axisValue = yAxisTmp.axisValue
|
||||
if (!axisValue?.auto) {
|
||||
tempOption.yAxis.value = {
|
||||
...yAxis,
|
||||
min: axisValue.min,
|
||||
max: axisValue.max,
|
||||
minLimit: axisValue.min,
|
||||
maxLimit: axisValue.max,
|
||||
tickCount: axisValue.splitCount
|
||||
}
|
||||
if (!yAxisExt) {
|
||||
//左右轴都要隐藏
|
||||
tempOption.yAxis.valueExt = false
|
||||
} else {
|
||||
tempOption.yAxis.value = yAxis
|
||||
}
|
||||
tempOption.yAxis.valueExt = undefined
|
||||
yAxisExt.position = 'right'
|
||||
|
||||
const yAxisExtTmp = parseJson(chart.customStyle).yAxisExt
|
||||
if (yAxisExt.label) {
|
||||
yAxisExt.label.formatter = value => {
|
||||
return valueFormatter(value, yAxisExtTmp.axisLabelFormatter)
|
||||
const yAxisExtTmp = parseJson(chart.customStyle).yAxisExt
|
||||
if (yAxisExt.label) {
|
||||
yAxisExt.label.style.textAlign = 'start'
|
||||
yAxisExt.label.formatter = value => {
|
||||
return valueFormatter(value, yAxisExtTmp.axisLabelFormatter)
|
||||
}
|
||||
}
|
||||
}
|
||||
const axisExtValue = yAxisExtTmp.axisValue
|
||||
if (!axisExtValue?.auto) {
|
||||
tempOption.yAxis.valueExt = {
|
||||
...yAxisExt,
|
||||
min: axisExtValue.min,
|
||||
max: axisExtValue.max,
|
||||
minLimit: axisExtValue.min,
|
||||
maxLimit: axisExtValue.max,
|
||||
tickCount: axisExtValue.splitCount
|
||||
const axisExtValue = yAxisExtTmp.axisValue
|
||||
if (!axisExtValue?.auto) {
|
||||
tempOption.yAxis.valueExt = {
|
||||
...yAxisExt,
|
||||
min: axisExtValue.min,
|
||||
max: axisExtValue.max,
|
||||
minLimit: axisExtValue.min,
|
||||
maxLimit: axisExtValue.max,
|
||||
tickCount: axisExtValue.splitCount
|
||||
}
|
||||
} else {
|
||||
tempOption.yAxis.valueExt = yAxisExt
|
||||
}
|
||||
} else {
|
||||
tempOption.yAxis.valueExt = yAxisExt
|
||||
}
|
||||
|
||||
return tempOption
|
||||
|
@ -24,9 +24,10 @@ import {
|
||||
import substitute from '@antv/util/esm/substitute'
|
||||
import type { Plot as L7Plot, PlotOptions } from '@antv/l7plot/dist/esm'
|
||||
import { Zoom } from '@antv/l7'
|
||||
import { createL7Icon } from '@antv/l7-component/es/utils/icon'
|
||||
import { DOM } from '@antv/l7-utils'
|
||||
import { Scene } from '@antv/l7-scene'
|
||||
import { type IZoomControlOption } from '@antv/l7-component'
|
||||
import { PositionType } from '@antv/l7-core'
|
||||
|
||||
export function getPadding(chart: Chart): number[] {
|
||||
if (chart.drill) {
|
||||
@ -828,7 +829,8 @@ export function configL7Label(chart: Chart): false | LabelOptions {
|
||||
visible: label.show,
|
||||
style: {
|
||||
fill: label.color,
|
||||
fontSize: label.fontSize
|
||||
fontSize: label.fontSize,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -970,7 +972,13 @@ export function configL7Legend(chart: Chart): LegendOptions | false {
|
||||
}
|
||||
}
|
||||
}
|
||||
class CustomZoom extends Zoom {
|
||||
const ZOOM_IN_BTN =
|
||||
'<svg t="1717484429999" fill="${fill}" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9332" width="14px" height="14px"><path d="M47.653 439.326c-24.501 0-44.368 19.881-44.368 44.4v56.548c0 24.492 19.862 44.4 44.368 44.4h928.694c24.501 0 44.368-19.881 44.368-44.4v-56.548c0-24.497-19.862-44.4-44.368-44.4H47.653z" p-id="9333"></path><path d="M586.326 47.653c0-24.501-19.881-44.368-44.4-44.368h-56.548c-24.492 0-44.4 19.862-44.4 44.368v928.694c0 24.501 19.881 44.368 44.4 44.368h56.548c24.497 0 44.4-19.862 44.4-44.368V47.653z" p-id="9334"></path></svg>'
|
||||
const RESET_BTN =
|
||||
'<svg t="1717487786436" fill="${fill}" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="18361" width="14px" height="14px"><path d="M127.594667 503.274667a383.573333 383.573333 0 0 1 112.426666-263.04 380.864 380.864 0 0 1 122.24-82.474667 382.421333 382.421333 0 0 1 149.632-30.165333c51.946667 0 102.250667 10.176 149.504 30.165333a381.610667 381.610667 0 0 1 122.133334 82.474667 385.152 385.152 0 0 1 31.082666 35.093333l-67.285333 52.501333a8.96 8.96 0 0 0 3.349333 15.765334l196.352 48.042666a8.96 8.96 0 0 0 11.050667-8.597333l0.896-202.154667c0-7.466667-8.597333-11.733333-14.421333-7.04l-63.018667 49.28C795.605333 113.173333 661.973333 42.666667 511.786667 42.666667 255.786667 42.666667 47.488 247.829333 42.666667 502.826667a8.96 8.96 0 0 0 8.96 9.173333h67.029333c4.906667 0 8.832-3.925333 8.96-8.725333z m844.8 8.725333h-67.050667a8.917333 8.917333 0 0 0-8.96 8.704 381.76 381.76 0 0 1-30.037333 140.8 382.336 382.336 0 0 1-82.346667 122.24 382.656 382.656 0 0 1-271.893333 112.64 382.421333 382.421333 0 0 1-271.765334-112.64 385.152 385.152 0 0 1-31.061333-35.072l67.264-52.522667a8.96 8.96 0 0 0-3.349333-15.765333l-196.330667-48.042667a8.96 8.96 0 0 0-11.050667 8.597334l-0.789333 202.261333c0 7.488 8.597333 11.733333 14.421333 7.04l63.018667-49.28C228.394667 910.826667 362.026667 981.333333 512.213333 981.333333 768.341333 981.333333 976.512 776.042667 981.333333 521.173333a8.96 8.96 0 0 0-8.96-9.173333z" p-id="18362"></path></svg>'
|
||||
const ZOOM_OUT_BTN =
|
||||
'<svg t="1717486240292" fill="${fill}" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13641" width="14px" height="14px"><path d="M935 423.3H89C40.2 423.3 0.3 463.2 0.3 512c0 48.8 39.9 88.7 88.7 88.7h846c48.8 0 88.7-39.9 88.7-88.7 0-48.8-39.9-88.7-88.7-88.7z" p-id="13642"></path></svg>'
|
||||
export class CustomZoom extends Zoom {
|
||||
resetButtonGroup(container) {
|
||||
DOM.clearChildren(container)
|
||||
this['zoomInButton'] = this['createButton'](
|
||||
@ -980,9 +988,8 @@ class CustomZoom extends Zoom {
|
||||
container,
|
||||
this.zoomIn
|
||||
)
|
||||
const resetBtnIconText = createL7Icon('l7-icon-round')
|
||||
this['zoomResetButton'] = this['createButton'](
|
||||
resetBtnIconText,
|
||||
this.controlOption['resetText'],
|
||||
'Reset',
|
||||
'l7-button-control',
|
||||
container,
|
||||
@ -1008,15 +1015,7 @@ class CustomZoom extends Zoom {
|
||||
container,
|
||||
this.zoomOut
|
||||
)
|
||||
const { buttonColor, buttonBackground } = this.controlOption as any
|
||||
if (buttonColor) {
|
||||
const elements = [
|
||||
this.controlOption.zoomInText,
|
||||
this.controlOption.zoomOutText,
|
||||
resetBtnIconText
|
||||
] as HTMLElement[]
|
||||
setStyle(elements, 'fill', buttonColor)
|
||||
}
|
||||
const { buttonBackground } = this.controlOption as any
|
||||
const elements = [this['zoomResetButton'], this['zoomInButton'], this['zoomOutButton']]
|
||||
if (buttonBackground) {
|
||||
setStyle(elements, 'background', buttonBackground)
|
||||
@ -1024,6 +1023,28 @@ class CustomZoom extends Zoom {
|
||||
setStyle(elements, 'border-bottom', 'none')
|
||||
this['updateDisabled']()
|
||||
}
|
||||
public getDefault(option: Partial<IZoomControlOption>) {
|
||||
const { buttonColor } = option as any
|
||||
let zoomInText = ZOOM_IN_BTN
|
||||
let zoomOutText = ZOOM_OUT_BTN
|
||||
let resetText = RESET_BTN
|
||||
if (buttonColor) {
|
||||
zoomInText = zoomInText.replace('${fill}', buttonColor)
|
||||
zoomOutText = zoomOutText.replace('${fill}', buttonColor)
|
||||
resetText = resetText.replace('${fill}', buttonColor)
|
||||
}
|
||||
return {
|
||||
...option,
|
||||
position: PositionType.BOTTOMRIGHT,
|
||||
name: 'zoom',
|
||||
zoomInText,
|
||||
zoomInTitle: 'Zoom in',
|
||||
zoomOutText,
|
||||
zoomOutTitle: 'Zoom out',
|
||||
resetText,
|
||||
showZoom: false
|
||||
} as IZoomControlOption
|
||||
}
|
||||
}
|
||||
export function configL7Zoom(chart: Chart, plot: L7Plot<PlotOptions> | Scene) {
|
||||
const { basicStyle } = parseJson(chart.customAttr)
|
||||
@ -1034,7 +1055,7 @@ export function configL7Zoom(chart: Chart, plot: L7Plot<PlotOptions> | Scene) {
|
||||
return
|
||||
}
|
||||
const plotScene = plot instanceof Scene ? plot : plot.scene
|
||||
plotScene.once('loaded', () => {
|
||||
plot.once('loaded', () => {
|
||||
const zoomOptions = {
|
||||
initZoom: plotScene.getZoom(),
|
||||
center: plotScene.getCenter(),
|
||||
|
@ -325,6 +325,18 @@ export function getStyle(chart: Chart): Style {
|
||||
p[n.fieldId] = n
|
||||
return p
|
||||
}, {}) || {}
|
||||
// 下钻字段使用入口字段的宽度
|
||||
if (chart.drill) {
|
||||
const { xAxis } = parseJson(chart)
|
||||
const curDrillField = chart.drillFields[chart.drillFilters.length]
|
||||
const drillEnterFieldIndex = xAxis.findIndex(
|
||||
item => item.id === chart.drillFilters[0].fieldId
|
||||
)
|
||||
const drillEnterField = xAxis[drillEnterFieldIndex]
|
||||
fieldMap[curDrillField.dataeaseName] = {
|
||||
width: fieldMap[drillEnterField.dataeaseName]?.width
|
||||
}
|
||||
}
|
||||
style.colCfg.width = node => {
|
||||
const width = node.spreadsheet.container.cfg.el.offsetWidth
|
||||
if (!basicStyle.tableFieldWidth?.length) {
|
||||
|
@ -475,7 +475,6 @@ export const exportExcelDownload = (chart, callBack?) => {
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
callBack('success')
|
||||
} else {
|
||||
callBack && callBack(res)
|
||||
}
|
||||
|
@ -261,6 +261,29 @@ const trackClick = trackAction => {
|
||||
if (state.pointParam.data.dimensionList.length > 1) {
|
||||
checkName = state.pointParam.data.dimensionList[0].id
|
||||
}
|
||||
// 跳转字段处理
|
||||
let jumpName = state.pointParam.data.name
|
||||
if (state.pointParam.data.dimensionList.length > 1) {
|
||||
const fieldIds = []
|
||||
// 优先下钻字段
|
||||
if (curView.drill) {
|
||||
const curFiled = curView.drillFields[curView.drillFilters.length]
|
||||
fieldIds.push(curFiled.id)
|
||||
}
|
||||
chartData.value?.fields.forEach(field => {
|
||||
if (!fieldIds.includes(field.id)) {
|
||||
fieldIds.push(field.id)
|
||||
}
|
||||
})
|
||||
for (let i = 0; i < fieldIds.length; i++) {
|
||||
const id = fieldIds[i]
|
||||
const sourceInfo = view.value.id + '#' + id
|
||||
if (nowPanelJumpInfo.value[sourceInfo]) {
|
||||
jumpName = id
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
let quotaList = state.pointParam.data.quotaList
|
||||
if (curView.type === 'bar-range') {
|
||||
quotaList = state.pointParam.data.dimensionList
|
||||
@ -276,7 +299,7 @@ const trackClick = trackAction => {
|
||||
}
|
||||
const jumpParam = {
|
||||
option: 'jump',
|
||||
name: checkName,
|
||||
name: jumpName,
|
||||
viewId: view.value.id,
|
||||
dimensionList: state.pointParam.data.dimensionList,
|
||||
quotaList: quotaList
|
||||
|
@ -3,6 +3,7 @@ import { useI18n } from '@/hooks/web/useI18n'
|
||||
import ChartComponentG2Plot from './components/ChartComponentG2Plot.vue'
|
||||
import DeIndicator from '@/custom-component/indicator/DeIndicator.vue'
|
||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
||||
import router from '@/router'
|
||||
import { useEmbedded } from '@/store/modules/embedded'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
import {
|
||||
@ -29,6 +30,7 @@ import DrillPath from '@/views/chart/components/views/components/DrillPath.vue'
|
||||
import { ElIcon, ElInput, ElMessage } from 'element-plus-secondary'
|
||||
import { useFilter } from '@/hooks/web/useFilter'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { parseUrl } from '@/utils/ParseUrl'
|
||||
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
@ -50,6 +52,7 @@ const dvMainStore = dvMainStoreWithOut()
|
||||
let innerRefreshTimer = null
|
||||
const appStore = useAppStoreWithOut()
|
||||
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
|
||||
const isIframe = computed(() => appStore.getIsIframe)
|
||||
|
||||
const emit = defineEmits(['onPointClick'])
|
||||
|
||||
@ -353,9 +356,6 @@ const windowsJump = (url, jumpType) => {
|
||||
try {
|
||||
const newWindow = window.open(url, jumpType)
|
||||
initOpenHandler(newWindow)
|
||||
if (jumpType === '_self') {
|
||||
location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
ElMessage.error(t('visualization.url_check_error') + ':' + url)
|
||||
}
|
||||
@ -388,6 +388,7 @@ const jumpClick = param => {
|
||||
param.sourceFieldId = dimension.id
|
||||
let embeddedBaseUrl = ''
|
||||
const divSelf = isDataEaseBi.value && jumpInfo.jumpType === '_self'
|
||||
const iframeSelf = isIframe.value && jumpInfo.jumpType === '_self'
|
||||
if (isDataEaseBi.value) {
|
||||
embeddedBaseUrl = embeddedStore.baseUrl
|
||||
}
|
||||
@ -410,12 +411,21 @@ const jumpClick = param => {
|
||||
const url = `${embeddedBaseUrl}#/preview?dvId=${
|
||||
jumpInfo.targetDvId
|
||||
}&jumpInfoParam=${encodeURIComponent(Base64.encode(JSON.stringify(param)))}`
|
||||
|
||||
if (isIframe.value || isDataEaseBi.value) {
|
||||
embeddedStore.clearState()
|
||||
}
|
||||
if (divSelf) {
|
||||
embeddedStore.setDvId(jumpInfo.targetDvId)
|
||||
embeddedStore.setJumpInfoParam(encodeURIComponent(Base64.encode(JSON.stringify(param))))
|
||||
divEmbedded('Preview')
|
||||
return
|
||||
}
|
||||
|
||||
if (iframeSelf) {
|
||||
router.push(parseUrl(url))
|
||||
return
|
||||
}
|
||||
windowsJump(url, jumpInfo.jumpType)
|
||||
}
|
||||
} else {
|
||||
@ -425,11 +435,16 @@ const jumpClick = param => {
|
||||
const colList = [...param.dimensionList, ...param.quotaList]
|
||||
let url = setIdValueTrans('id', 'value', jumpInfo.content, colList)
|
||||
url = checkAddHttp(url)
|
||||
|
||||
if (isIframe.value || isDataEaseBi.value) {
|
||||
embeddedStore.clearState()
|
||||
}
|
||||
if (divSelf) {
|
||||
embeddedStore.setOuterUrl(url)
|
||||
divEmbedded('Iframe')
|
||||
return
|
||||
}
|
||||
|
||||
windowsJump(url, jumpInfo.jumpType)
|
||||
}
|
||||
} else {
|
||||
|
@ -16,6 +16,7 @@ import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
const interactiveStore = interactiveStoreWithOut()
|
||||
import router from '@/router'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { parseUrl } from '@/utils/ParseUrl'
|
||||
import _ from 'lodash'
|
||||
import DeResourceCreateOptV2 from '@/views/common/DeResourceCreateOptV2.vue'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
@ -106,6 +107,7 @@ const dvSvgType = computed(() =>
|
||||
)
|
||||
|
||||
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
|
||||
const isIframe = computed(() => appStore.getIsIframe)
|
||||
|
||||
const resourceTypeList = computed(() => {
|
||||
const list = [
|
||||
@ -300,6 +302,11 @@ const operation = (cmd: string, data: BusiTreeNode, nodeType: string) => {
|
||||
return
|
||||
}
|
||||
|
||||
if (isIframe.value) {
|
||||
router.push(parseUrl(baseUrl))
|
||||
return
|
||||
}
|
||||
|
||||
const newWindow = window.open(baseUrl, '_blank')
|
||||
initOpenHandler(newWindow)
|
||||
})
|
||||
@ -331,6 +338,11 @@ const addOperation = (
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (isIframe.value) {
|
||||
router.push(parseUrl(data?.id ? baseUrl + `&pid=${data.id}` : baseUrl))
|
||||
return
|
||||
}
|
||||
if (data?.id) {
|
||||
newWindow = window.open(baseUrl + `&pid=${data.id}`, '_blank')
|
||||
} else {
|
||||
@ -368,6 +380,11 @@ const resourceEdit = resourceId => {
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (isIframe.value) {
|
||||
router.push(parseUrl(baseUrl + resourceId))
|
||||
return
|
||||
}
|
||||
const newWindow = window.open(baseUrl + resourceId, '_blank')
|
||||
initOpenHandler(newWindow)
|
||||
}
|
||||
@ -397,6 +414,13 @@ const resourceCreateFinish = templateData => {
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (isIframe.value) {
|
||||
router.push(
|
||||
parseUrl(state.templateCreatePid ? baseUrl + `&pid=${state.templateCreatePid}` : baseUrl)
|
||||
)
|
||||
return
|
||||
}
|
||||
if (state.templateCreatePid) {
|
||||
newWindow = window.open(baseUrl + `&pid=${state.templateCreatePid}`, '_blank')
|
||||
} else {
|
||||
|
@ -8,6 +8,7 @@ import { useEmbedded } from '@/store/modules/embedded'
|
||||
import { canvasSave } from '@/utils/canvasUtils'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { backCanvasData } from '@/utils/canvasUtils'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { debounce } from 'lodash-es'
|
||||
import mobileHeader from '@/assets/img/mobile-header.png'
|
||||
@ -175,6 +176,7 @@ onBeforeUnmount(() => {
|
||||
})
|
||||
|
||||
const addToMobile = com => {
|
||||
if (mobileLoading.value) return
|
||||
com.inMobile = true
|
||||
changeTimes.value++
|
||||
mobileStatusChange('addToMobile', JSON.parse(JSON.stringify(unref(com))))
|
||||
@ -194,7 +196,10 @@ const handleBack = () => {
|
||||
showClose: false
|
||||
}).then(() => {
|
||||
setTimeout(() => {
|
||||
mobileStatusChange('mobilePatch', undefined)
|
||||
backCanvasData(dvInfo.value.id, 'dashboard', () => {
|
||||
changeTimes.value = 0
|
||||
emits('pcMode')
|
||||
})
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
@ -274,7 +279,11 @@ const save = () => {
|
||||
:scale="80"
|
||||
/>
|
||||
</div>
|
||||
<div class="mobile-com-mask" @click="addToMobile(item)"></div>
|
||||
<div class="mobile-com-mask" @click="addToMobile(item)">
|
||||
<span v-show="item.component === 'DeStreamMedia'" style="color: #909399"
|
||||
>IOS可能无法显示</span
|
||||
>
|
||||
</div>
|
||||
<div class="pc-select-to-mobile" @click="addToMobile(item)" v-if="!mobileLoading"></div>
|
||||
</div>
|
||||
</template>
|
||||
@ -506,6 +515,9 @@ const save = () => {
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pc-select-to-mobile {
|
||||
|
@ -73,7 +73,6 @@ const loadCanvasDataAsync = async (dvId, dvType) => {
|
||||
ElMessage.error(t('visualization.outer_param_decode_error'))
|
||||
}
|
||||
}
|
||||
|
||||
initCanvasData(
|
||||
dvId,
|
||||
dvType,
|
||||
|
@ -79,7 +79,7 @@ const dvLayout = ref(null)
|
||||
const canvasCenterRef = ref(null)
|
||||
const state = reactive({
|
||||
datasetTree: [],
|
||||
scaleHistory: 100,
|
||||
scaleHistory: null,
|
||||
canvasId: 'canvas-main',
|
||||
canvasInitStatus: false,
|
||||
sourcePid: null,
|
||||
@ -204,10 +204,10 @@ const doUseCache = flag => {
|
||||
}
|
||||
}
|
||||
|
||||
const initLocalCanvasData = () => {
|
||||
const initLocalCanvasData = async () => {
|
||||
const { opt, sourcePid, resourceId } = state
|
||||
const busiFlg = opt === 'copy' ? 'dataV-copy' : 'dataV'
|
||||
initCanvasData(resourceId, busiFlg, function () {
|
||||
await initCanvasData(resourceId, busiFlg, function () {
|
||||
state.canvasInitStatus = true
|
||||
// afterInit
|
||||
nextTick(() => {
|
||||
@ -238,7 +238,9 @@ watch(
|
||||
() => editMode.value,
|
||||
val => {
|
||||
if (val === 'edit') {
|
||||
canvasStyleData.value.scale = state.scaleHistory
|
||||
if (state.scaleHistory) {
|
||||
canvasStyleData.value.scale = state.scaleHistory
|
||||
}
|
||||
initScroll()
|
||||
} else {
|
||||
previewScaleChange()
|
||||
@ -288,7 +290,7 @@ onMounted(async () => {
|
||||
if (canvasCache) {
|
||||
canvasCacheOutRef.value?.dialogInit({ canvasType: 'dataV', resourceId: dvId })
|
||||
} else {
|
||||
initLocalCanvasData()
|
||||
await initLocalCanvasData()
|
||||
}
|
||||
} else if (opt && opt === 'create') {
|
||||
state.canvasInitStatus = false
|
||||
@ -303,7 +305,7 @@ onMounted(async () => {
|
||||
}
|
||||
let deTemplateData
|
||||
if (createType === 'template') {
|
||||
const templateParamsApply = JSON.parse(decodeURIComponent(Base64.decode(templateParams + '')))
|
||||
const templateParamsApply = JSON.parse(Base64.decode(decodeURIComponent(templateParams + '')))
|
||||
await decompressionPre(templateParamsApply, result => {
|
||||
deTemplateData = result
|
||||
})
|
||||
|
@ -117,8 +117,12 @@ const handleLogin = () => {
|
||||
if (!xpackLoadFail.value && xpackInvalidPwd.value?.invokeMethod) {
|
||||
const param = {
|
||||
methodName: 'init',
|
||||
args: () => {
|
||||
duringLogin.value = false
|
||||
args: r => {
|
||||
duringLogin.value = !!r
|
||||
if (r) {
|
||||
const queryRedirectPath = getCurLocation()
|
||||
router.push({ path: queryRedirectPath })
|
||||
}
|
||||
}
|
||||
}
|
||||
xpackInvalidPwd?.value.invokeMethod(param)
|
||||
|
9
core/core-frontend/src/views/share/link/IframeError.vue
Normal file
9
core/core-frontend/src/views/share/link/IframeError.vue
Normal file
@ -0,0 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
|
||||
</script>
|
||||
<template>
|
||||
<EmptyBackground
|
||||
img-type="noneWhite"
|
||||
description="仅嵌入式版和企业版支持iframe方式内嵌公共链接"
|
||||
/>
|
||||
</template>
|
@ -1,5 +1,6 @@
|
||||
import request from '@/config/axios'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { isInIframe } from '@/utils/utils'
|
||||
const { wsCache } = useCache()
|
||||
export interface ProxyInfo {
|
||||
resourceId: string
|
||||
@ -7,6 +8,7 @@ export interface ProxyInfo {
|
||||
exp?: boolean
|
||||
pwdValid?: boolean
|
||||
type: string
|
||||
inIframeError: boolean
|
||||
}
|
||||
class ShareProxy {
|
||||
uuid: string
|
||||
@ -28,7 +30,8 @@ class ShareProxy {
|
||||
}
|
||||
const uuid = this.uuid
|
||||
const url = '/share/proxyInfo'
|
||||
const param = { uuid, ciphertext: null }
|
||||
const inIframe = isInIframe()
|
||||
const param = { uuid, ciphertext: null, inIframe }
|
||||
const ciphertext = wsCache.get(`link-${uuid}`)
|
||||
if (ciphertext) {
|
||||
param['ciphertext'] = ciphertext
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="link-container" v-loading="loading">
|
||||
<LinkError v-if="!loading && !linkExist" />
|
||||
<IframeError v-if="!loading && iframeError" />
|
||||
<LinkError v-else-if="!loading && !linkExist" />
|
||||
<Exp v-else-if="!loading && linkExp" />
|
||||
<PwdTips v-else-if="!loading && !pwdValid" />
|
||||
<PreviewCanvas
|
||||
@ -18,13 +19,21 @@ import { ProxyInfo, shareProxy } from './ShareProxy'
|
||||
import Exp from './exp.vue'
|
||||
import LinkError from './error.vue'
|
||||
import PwdTips from './pwd.vue'
|
||||
import IframeError from './IframeError.vue'
|
||||
const pcanvas = ref(null)
|
||||
const iframeError = ref(true)
|
||||
const linkExist = ref(false)
|
||||
const loading = ref(true)
|
||||
const linkExp = ref(false)
|
||||
const pwdValid = ref(false)
|
||||
onMounted(async () => {
|
||||
const proxyInfo = (await shareProxy.loadProxy()) as ProxyInfo
|
||||
if (proxyInfo?.inIframeError) {
|
||||
loading.value = false
|
||||
iframeError.value = true
|
||||
return
|
||||
}
|
||||
iframeError.value = false
|
||||
if (!proxyInfo?.resourceId) {
|
||||
loading.value = false
|
||||
return
|
||||
|
@ -1,23 +1,33 @@
|
||||
<template>
|
||||
<div class="mobile-link-container" v-loading="loading">
|
||||
<div
|
||||
:class="curType === 'dashboard' ? 'mobile-link-container' : 'link-container'"
|
||||
v-loading="loading"
|
||||
>
|
||||
<LinkError v-if="!loading && !linkExist" />
|
||||
<Exp v-else-if="!loading && linkExp" />
|
||||
<PwdTips v-else-if="!loading && !pwdValid" />
|
||||
<de-preview
|
||||
ref="dashboardPreview"
|
||||
v-else-if="state.canvasStylePreview && dataInitState"
|
||||
v-else-if="state.canvasStylePreview && dataInitState && curType === 'dashboard'"
|
||||
:component-data="state.canvasDataPreview"
|
||||
:canvas-style-data="state.canvasStylePreview"
|
||||
:canvas-view-info="state.canvasViewInfoPreview"
|
||||
:dv-info="state.dvInfo"
|
||||
:cur-gap="state.curPreviewGap"
|
||||
></de-preview>
|
||||
<PreviewCanvas
|
||||
v-else-if="curType !== 'dashboard'"
|
||||
:class="{ 'hidden-link': loading }"
|
||||
ref="pcanvas"
|
||||
public-link-status="true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, nextTick, ref, reactive } from 'vue'
|
||||
import { initCanvasDataMobile } from '@/utils/canvasUtils'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import PreviewCanvas from '@/views/data-visualization/PreviewCanvas.vue'
|
||||
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
||||
import { ProxyInfo, shareProxy } from './ShareProxy'
|
||||
import Exp from './exp.vue'
|
||||
@ -71,9 +81,14 @@ const loadCanvasData = (dvId, weight?) => {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const curType = ref('')
|
||||
const pcanvas = ref(null)
|
||||
|
||||
onMounted(async () => {
|
||||
dvMainStore.setMobileInPc(true)
|
||||
const proxyInfo = (await shareProxy.loadProxy()) as ProxyInfo
|
||||
curType.value = proxyInfo.type || 'dashboard'
|
||||
dvMainStore.setMobileInPc(curType.value === 'dashboard')
|
||||
if (!proxyInfo?.resourceId) {
|
||||
loading.value = false
|
||||
return
|
||||
@ -82,9 +97,17 @@ onMounted(async () => {
|
||||
linkExp.value = !!proxyInfo.exp
|
||||
pwdValid.value = !!proxyInfo.pwdValid
|
||||
nextTick(() => {
|
||||
loadCanvasData(proxyInfo.resourceId, proxyInfo.type)
|
||||
dvMainStore.setPublicLinkStatus(true)
|
||||
loading.value = false
|
||||
if (curType.value === 'dashboard') {
|
||||
loadCanvasData(proxyInfo.resourceId, proxyInfo.type)
|
||||
dvMainStore.setPublicLinkStatus(true)
|
||||
loading.value = false
|
||||
} else {
|
||||
const method = pcanvas?.value?.loadCanvasDataAsync
|
||||
if (method) {
|
||||
method(proxyInfo.resourceId, proxyInfo.type, null)
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@ -96,3 +119,15 @@ onMounted(async () => {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scoped>
|
||||
.link-container {
|
||||
position: absolute !important;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
.hidden-link {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
|
@ -125,6 +125,15 @@ const edit = (list, orgOptions, roleOptions) => {
|
||||
}
|
||||
]
|
||||
}
|
||||
if (pkey === 'basic.exportFileLiveTime') {
|
||||
rule[pkey.split('.')[1]] = [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.require'),
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
]
|
||||
}
|
||||
item['label'] = `setting_${pkey}`
|
||||
item['pkey'] = pkey.split('.')[1]
|
||||
let pval = item.pval
|
||||
@ -301,6 +310,19 @@ defineExpose({
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div v-else-if="item.pkey === 'exportFileLiveTime'">
|
||||
<el-input-number
|
||||
v-model="state.form[item.pkey]"
|
||||
autocomplete="off"
|
||||
step-strictly
|
||||
class="text-left edit-all-line"
|
||||
:min="1"
|
||||
:max="4000"
|
||||
:placeholder="t('common.inputText')"
|
||||
controls-position="right"
|
||||
type="number"
|
||||
/>
|
||||
</div>
|
||||
<v-else />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -169,7 +169,9 @@ import { nextTick, reactive, watch, onMounted, ref, computed } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import router from '@/router'
|
||||
import MarketPreviewV2 from '@/views/template-market/component/MarketPreviewV2.vue'
|
||||
import { parseUrl } from '@/utils/ParseUrl'
|
||||
import { imgUrlTrans } from '@/utils/imgUtils'
|
||||
import CategoryTemplateV2 from '@/views/template-market/component/CategoryTemplateV2.vue'
|
||||
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
@ -192,6 +194,7 @@ const close = () => {
|
||||
|
||||
const title = computed(() => (state.curPosition === 'branch' ? '模板中心' : '使用模板新建'))
|
||||
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
|
||||
const isIframe = computed(() => appStore.getIsIframe)
|
||||
const state = reactive({
|
||||
initReady: true,
|
||||
curPosition: 'branch',
|
||||
@ -283,8 +286,8 @@ const state = reactive({
|
||||
const createAuth = computed(() => {
|
||||
const authMap = interactiveStore.getData
|
||||
return {
|
||||
PANEL: authMap['0'].menuAuth && authMap['0'].anyManage,
|
||||
SCREEN: authMap['1'].menuAuth && authMap['1'].anyManage
|
||||
PANEL: authMap['0']?.menuAuth && authMap['0']?.anyManage,
|
||||
SCREEN: authMap['1']?.menuAuth && authMap['1']?.anyManage
|
||||
}
|
||||
})
|
||||
|
||||
@ -454,6 +457,11 @@ const apply = template => {
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (isIframe.value) {
|
||||
router.push(parseUrl(state.pid ? baseUrl + `&pid=${state.pid}` : baseUrl))
|
||||
return
|
||||
}
|
||||
if (state.pid) {
|
||||
newWindow = window.open(baseUrl + `&pid=${state.pid}`, '_blank')
|
||||
} else {
|
||||
|
@ -65,8 +65,6 @@ const handleClick = tab => {
|
||||
} else {
|
||||
description.value = t('data_export.no_task')
|
||||
}
|
||||
|
||||
tableData.value = []
|
||||
drawerLoading.value = true
|
||||
exportTasks(activeName.value)
|
||||
.then(res => {
|
||||
@ -348,7 +346,7 @@ defineExpose({
|
||||
<el-tab-pane v-for="tab in tabList" :key="tab.name" :label="tab.label" :name="tab.name" />
|
||||
</el-tabs>
|
||||
<el-button
|
||||
v-show="activeName === 'SUCCESS' && multipleSelection.length === 0"
|
||||
v-if="activeName === 'SUCCESS' && multipleSelection.length === 0"
|
||||
secondary
|
||||
@click="downLoadAll"
|
||||
>
|
||||
@ -358,15 +356,15 @@ defineExpose({
|
||||
{{ $t('data_export.download_all') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-show="activeName === 'SUCCESS' && multipleSelection.length !== 0"
|
||||
v-if="activeName === 'SUCCESS' && multipleSelection.length !== 0"
|
||||
secondary
|
||||
@click="downLoadAll"
|
||||
><template #icon> <Icon name="de-delete"></Icon> </template>{{ $t('data_export.download') }}
|
||||
</el-button>
|
||||
<el-button v-show="multipleSelection.length === 0" secondary @click="delAll"
|
||||
<el-button v-if="multipleSelection.length === 0" secondary @click="delAll"
|
||||
><template #icon> <Icon name="de-delete"></Icon> </template>{{ $t('data_export.del_all') }}
|
||||
</el-button>
|
||||
<el-button v-show="multipleSelection.length !== 0" secondary @click="delAll"
|
||||
<el-button v-if="multipleSelection.length !== 0" secondary @click="delAll"
|
||||
><template #icon> <Icon name="de-delete"></Icon> </template>{{ $t('commons.delete') }}
|
||||
</el-button>
|
||||
<div class="table-container" :class="!tableData.length && 'hidden-bottom'">
|
||||
|
@ -1327,10 +1327,10 @@ const getDsIconName = data => {
|
||||
</el-icon>
|
||||
<span class="label">自定义SQL</span>
|
||||
</div>
|
||||
<template v-for="ele in state.tableData" :key="ele.name">
|
||||
<template v-for="ele in state.tableData" :key="ele.tableName">
|
||||
<div
|
||||
class="list-item_primary"
|
||||
:title="ele.name"
|
||||
:title="ele.tableName"
|
||||
@dragstart="$event => dragstart($event, ele)"
|
||||
@dragend="maskShow = false"
|
||||
:draggable="true"
|
||||
|
@ -35,7 +35,9 @@ import type { TabPaneName } from 'element-plus-secondary'
|
||||
import { timestampFormatDate } from './form/util'
|
||||
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
const interactiveStore = interactiveStoreWithOut()
|
||||
const { wsCache } = useCache()
|
||||
interface Field {
|
||||
fieldShortName: string
|
||||
name: string
|
||||
@ -86,6 +88,7 @@ let originResourceTree = []
|
||||
const sortTypeChange = sortType => {
|
||||
state.datasetTree = treeSort(originResourceTree, sortType)
|
||||
state.curSortType = sortType
|
||||
wsCache.set('TreeSort-dataset', state.curSortType)
|
||||
}
|
||||
|
||||
const resourceCreate = (pid, name) => {
|
||||
@ -211,10 +214,12 @@ const getData = () => {
|
||||
rootManage.value = nodeData[0]['weight'] >= 7
|
||||
state.datasetTree = nodeData[0]['children'] || []
|
||||
originResourceTree = cloneDeep(unref(state.datasetTree))
|
||||
sortTypeChange(state.curSortType)
|
||||
return
|
||||
}
|
||||
state.datasetTree = nodeData
|
||||
originResourceTree = cloneDeep(unref(state.datasetTree))
|
||||
sortTypeChange(state.curSortType)
|
||||
})
|
||||
.finally(() => {
|
||||
dtLoading.value = false
|
||||
@ -252,6 +257,7 @@ const dfsDatasetTree = (ds, id) => {
|
||||
|
||||
onBeforeMount(() => {
|
||||
nodeInfo.id = (route.params.id as string) || ''
|
||||
loadInit()
|
||||
getData()
|
||||
})
|
||||
|
||||
@ -471,6 +477,13 @@ const sortList = [
|
||||
}
|
||||
]
|
||||
|
||||
const loadInit = () => {
|
||||
const historyTreeSort = wsCache.get('TreeSort-dataset')
|
||||
if (historyTreeSort) {
|
||||
state.curSortType = historyTreeSort
|
||||
}
|
||||
}
|
||||
|
||||
const sortTypeTip = computed(() => {
|
||||
return sortList.find(ele => ele.value === state.curSortType).name
|
||||
})
|
||||
|
@ -458,7 +458,7 @@ defineExpose({
|
||||
</div>
|
||||
<el-form-item :label="$t('datasource.query_timeout')" prop="apiQueryTimeout">
|
||||
<el-input v-model="apiItem.apiQueryTimeout" autocomplete="off" type="number" :min="0">
|
||||
<template v-slot:append>{{ $t('panel.second') }}</template>
|
||||
<template v-slot:append>{{ $t('chart.second') }}</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<div class="title-form_primary request-info">
|
||||
|
@ -73,8 +73,8 @@ const selectDsType = (type: string) => {
|
||||
currentDsType.value = type
|
||||
activeStep.value = 1
|
||||
activeApiStep.value = 1
|
||||
detail.value.initForm(type)
|
||||
nextTick(() => {
|
||||
detail.value.initForm(type)
|
||||
if (!dsTree.value) return
|
||||
currentTypeList.value
|
||||
.map(ele => ele.dbList)
|
||||
@ -493,7 +493,9 @@ const init = (nodeInfo: Form | Param, id?: string, res?: object) => {
|
||||
excel.value.appendReplaceExcel(res)
|
||||
})
|
||||
}
|
||||
detail.value.clearForm()
|
||||
nextTick(() => {
|
||||
detail.value.clearForm()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -653,7 +655,7 @@ defineExpose({
|
||||
:form="form"
|
||||
:editDs="editDs"
|
||||
:active-step="activeApiStep"
|
||||
v-show="activeStep !== 0 && currentDsType && currentDsType !== 'Excel'"
|
||||
v-if="activeStep !== 0 && currentDsType && currentDsType !== 'Excel' && visible"
|
||||
></editor-detail>
|
||||
<template v-if="activeStep !== 0 && currentDsType == 'Excel'">
|
||||
<excel-detail :editDs="editDs" ref="excel" :param="form2"></excel-detail>
|
||||
|
@ -8,7 +8,7 @@ import ArrowSide from '@/views/common/DeResourceArrow.vue'
|
||||
import { HandleMore } from '@/components/handle-more'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import { fieldType } from '@/utils/attr'
|
||||
import { listSyncRecord, uploadFile } from '@/api/datasource'
|
||||
import { getHidePwById, listSyncRecord, uploadFile } from '@/api/datasource'
|
||||
import CreatDsGroup from './form/CreatDsGroup.vue'
|
||||
import type { Tree } from '../dataset/form/CreatDsGroup.vue'
|
||||
import { previewData, getById } from '@/api/datasource'
|
||||
@ -42,6 +42,7 @@ import { useMoveLine } from '@/hooks/web/useMoveLine'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
import treeSort from '@/utils/treeSortUtils'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
const route = useRoute()
|
||||
const interactiveStore = interactiveStoreWithOut()
|
||||
interface Field {
|
||||
@ -51,7 +52,7 @@ interface Field {
|
||||
originName: string
|
||||
deType: number
|
||||
}
|
||||
|
||||
const { wsCache } = useCache()
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
const appStore = useAppStoreWithOut()
|
||||
@ -165,6 +166,7 @@ let originResourceTree = []
|
||||
const sortTypeChange = sortType => {
|
||||
state.datasourceTree = treeSort(originResourceTree, sortType)
|
||||
state.curSortType = sortType
|
||||
wsCache.set('TreeSort-datasource', state.curSortType)
|
||||
}
|
||||
const handleSizeChange = pageSize => {
|
||||
state.paginationConfig.currentPage = 1
|
||||
@ -391,10 +393,12 @@ const listDs = () => {
|
||||
rootManage.value = nodeData[0]['weight'] >= 7
|
||||
state.datasourceTree = nodeData[0]['children'] || []
|
||||
originResourceTree = cloneDeep(unref(state.datasourceTree))
|
||||
sortTypeChange(state.curSortType)
|
||||
return
|
||||
}
|
||||
originResourceTree = cloneDeep(unref(state.datasourceTree))
|
||||
state.datasourceTree = nodeData
|
||||
sortTypeChange(state.curSortType)
|
||||
})
|
||||
.finally(() => {
|
||||
mounted.value = true
|
||||
@ -455,7 +459,7 @@ const handleNodeClick = data => {
|
||||
dsListTree.value.setCurrentKey(null)
|
||||
return
|
||||
}
|
||||
return getById(data.id).then(res => {
|
||||
return getHidePwById(data.id).then(res => {
|
||||
let {
|
||||
name,
|
||||
createBy,
|
||||
@ -571,7 +575,48 @@ const editDatasource = (editType?: number) => {
|
||||
if (nodeInfo.type === 'Excel') {
|
||||
nodeInfo.editType = editType
|
||||
}
|
||||
datasourceEditor.value.init(nodeInfo)
|
||||
return getById(nodeInfo.id).then(res => {
|
||||
let {
|
||||
name,
|
||||
createBy,
|
||||
id,
|
||||
createTime,
|
||||
creator,
|
||||
type,
|
||||
pid,
|
||||
configuration,
|
||||
syncSetting,
|
||||
apiConfigurationStr,
|
||||
fileName,
|
||||
size,
|
||||
description,
|
||||
lastSyncTime
|
||||
} = res.data
|
||||
if (configuration) {
|
||||
configuration = JSON.parse(Base64.decode(configuration))
|
||||
}
|
||||
if (apiConfigurationStr) {
|
||||
apiConfigurationStr = JSON.parse(Base64.decode(apiConfigurationStr))
|
||||
}
|
||||
let datasource = reactive<Node>(cloneDeep(defaultInfo))
|
||||
Object.assign(datasource, {
|
||||
name,
|
||||
pid,
|
||||
description,
|
||||
fileName,
|
||||
size,
|
||||
createTime,
|
||||
creator,
|
||||
createBy,
|
||||
id,
|
||||
type,
|
||||
configuration,
|
||||
syncSetting,
|
||||
apiConfiguration: apiConfigurationStr,
|
||||
lastSyncTime
|
||||
})
|
||||
datasourceEditor.value.init(datasource)
|
||||
})
|
||||
}
|
||||
|
||||
const handleEdit = async data => {
|
||||
@ -693,8 +738,17 @@ const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'name'
|
||||
}
|
||||
|
||||
const loadInit = () => {
|
||||
const historyTreeSort = wsCache.get('TreeSort-datasource')
|
||||
if (historyTreeSort) {
|
||||
state.curSortType = historyTreeSort
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
nodeInfo.id = (route.params.id as string) || ''
|
||||
loadInit()
|
||||
listDs()
|
||||
const { opt } = router.currentRoute.value.query
|
||||
if (opt && opt === 'create') {
|
||||
|
@ -22,7 +22,7 @@ export default {
|
||||
}
|
||||
]
|
||||
function isLoginStatus() {
|
||||
return wsCache.get('user.token')
|
||||
return wsCache.get('user.token') && wsCache.get('user.uid')
|
||||
}
|
||||
|
||||
function connection() {
|
||||
|
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
||||
Subproject commit 448c319f8e519be5f4b47663258136bcb6fc3faa
|
||||
Subproject commit a12eea394d8d5edf2941988819b08676e512a11e
|
@ -138,6 +138,7 @@ curl http://127.0.0.1:9180/apisix/admin/routes -X POST -H "X-API-KEY: $DE_APISIX
|
||||
]
|
||||
],
|
||||
"upstream_id": "1",
|
||||
"enable_websocket": true,
|
||||
"status": 1
|
||||
}'
|
||||
|
||||
@ -173,4 +174,4 @@ curl http://127.0.0.1:9180/apisix/admin/routes -X POST -H "X-API-KEY: $DE_APISIX
|
||||
],
|
||||
"service_id": "10",
|
||||
"status": 1
|
||||
}'
|
||||
}'
|
||||
|
@ -67,7 +67,7 @@ function _check_apisix_init() {
|
||||
function _prepare_apisix() {
|
||||
if [[ -z $DE_APISIX_KEY ]];then
|
||||
need_init_apisix=true
|
||||
DE_APISIX_KEY=$(uuidgen | sed 's/-//g')
|
||||
DE_APISIX_KEY=$(head -c 32 /dev/urandom | base64)
|
||||
export DE_APISIX_KEY=$DE_APISIX_KEY
|
||||
cd $DE_RUNNING_BASE
|
||||
env | grep DE_ >.env
|
||||
|
@ -53,6 +53,7 @@ function check_and_prepare_env_params() {
|
||||
fi
|
||||
|
||||
set -a
|
||||
source ${CURRENT_DIR}/install.conf
|
||||
if [[ -d $DE_BASE ]] && [[ -f $DE_BASE/dataease2.0/.env ]]; then
|
||||
source $DE_BASE/dataease2.0/.env
|
||||
INSTALL_TYPE='upgrade'
|
||||
@ -64,7 +65,6 @@ function check_and_prepare_env_params() {
|
||||
fi
|
||||
log_content "升级安装"
|
||||
else
|
||||
source ${CURRENT_DIR}/install.conf
|
||||
INSTALL_TYPE='install'
|
||||
mkdir -p ${DE_BASE}
|
||||
log_content "全新安装"
|
||||
|
@ -43,4 +43,12 @@ public interface ChartViewApi {
|
||||
@Operation(summary = "查询仪表板下视图项")
|
||||
@GetMapping("/viewOption/{resourceId}")
|
||||
List<ViewSelectorVO> viewOption(@PathVariable("resourceId") Long resourceId);
|
||||
|
||||
@Operation(summary = "视图复制字段")
|
||||
@PostMapping("copyField/{id}/{chartId}")
|
||||
void copyField(@PathVariable Long id, @PathVariable Long chartId);
|
||||
|
||||
@Operation(summary = "视图删除字段")
|
||||
@PostMapping("deleteField/{id}")
|
||||
void deleteField(@PathVariable Long id);
|
||||
}
|
||||
|
@ -71,6 +71,11 @@ public interface DatasourceApi {
|
||||
@GetMapping("/get/{datasourceId}")
|
||||
DatasourceDTO get(@PathVariable("datasourceId") Long datasourceId) throws DEException;
|
||||
|
||||
@DePermit({"#p0+':read'"})
|
||||
@GetMapping("/hidePw/{datasourceId}")
|
||||
DatasourceDTO hidePw(@PathVariable("datasourceId") Long datasourceId) throws DEException;
|
||||
|
||||
|
||||
@PostMapping("/getTableField")
|
||||
List<TableField> getTableField(@RequestBody Map<String, String> req) throws DEException;
|
||||
|
||||
|
@ -30,4 +30,6 @@ public class ExportTaskDTO {
|
||||
private String exportMachineName;
|
||||
|
||||
private String exportFromName;
|
||||
|
||||
private String orgName;
|
||||
}
|
||||
|
@ -19,4 +19,5 @@ public class XpackShareProxyRequest implements Serializable {
|
||||
private String uuid;
|
||||
@Schema(description = "密钥", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String ciphertext;
|
||||
private boolean inIframe;
|
||||
}
|
||||
|
@ -31,4 +31,5 @@ public class XpackShareProxyVO implements Serializable {
|
||||
private boolean pwdValid;
|
||||
@Schema(description = "类型")
|
||||
private String type;
|
||||
private boolean inIframeError = true;
|
||||
}
|
||||
|
@ -10,7 +10,9 @@ public class SysVariableDto {
|
||||
private Long id;
|
||||
private String type;
|
||||
private String name;
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long min;
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long max;
|
||||
private String startTime;
|
||||
private String endTime;
|
||||
|
@ -8,7 +8,6 @@ import java.util.List;
|
||||
|
||||
@Data
|
||||
public class SysVariableValueItem {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private String variableValue;
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private String variableValue2;
|
||||
|
@ -4,7 +4,7 @@ import java.util.Arrays;
|
||||
|
||||
public enum MessageEnum {
|
||||
|
||||
INNER(0), EMAIL(1), WECOM(2), DINGTALK(3), LARK(4), LARKSUITE(5);
|
||||
INNER(0), EMAIL(1), WECOM(2), DINGTALK(3), LARK(4), LARKSUITE(5), LARKGROUP(6);
|
||||
private Integer flag;
|
||||
|
||||
public Integer getFlag() {
|
||||
|
@ -65,6 +65,7 @@ public class WhitelistUtils {
|
||||
|| StringUtils.startsWithAny(requestURI, "/xpackComponent/content/")
|
||||
|| StringUtils.startsWithAny(requestURI, "/geo/")
|
||||
|| StringUtils.startsWithAny(requestURI, "/websocket")
|
||||
|| StringUtils.startsWithAny(requestURI, "/map/");
|
||||
|| StringUtils.startsWithAny(requestURI, "/map/")
|
||||
|| StringUtils.startsWithAny(requestURI, "/communicate/down/");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user