提交 49bb1f18 authored 作者: taojinlong's avatar taojinlong

Merge branch 'main' of github.com:dataease/dataease into main

package io.dataease.dto.chart;
import io.dataease.base.domain.DatasetTableField;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* @Author gin
* @Date 2021/5/21 4:24 下午
*/
@Getter
@Setter
public class ChartCustomFilterDTO implements Serializable {
private String fieldId;
private String term;
private String value;
private DatasetTableField field;
}
......@@ -2,6 +2,7 @@ package io.dataease.provider;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import io.dataease.dto.chart.ChartCustomFilterDTO;
import io.dataease.dto.chart.ChartViewFieldDTO;
import java.util.List;
......@@ -27,9 +28,9 @@ public abstract class QueryProvider {
public abstract String createQuerySQLAsTmpWithPage(String sql, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize);
public abstract String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartExtFilterRequest> extFilterRequestList);
public abstract String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList);
public abstract String getSQLAsTmp(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartExtFilterRequest> extFilterRequestList);
public abstract String getSQLAsTmp(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList);
public abstract String searchTable(String table);
}
......@@ -2,6 +2,7 @@ package io.dataease.provider.doris;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import io.dataease.dto.chart.ChartCustomFilterDTO;
import io.dataease.dto.chart.ChartViewFieldDTO;
import io.dataease.provider.QueryProvider;
import org.apache.commons.collections4.CollectionUtils;
......@@ -9,7 +10,9 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
......@@ -108,7 +111,7 @@ public class DorisQueryProvider extends QueryProvider {
}
@Override
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartExtFilterRequest> extFilterRequestList) {
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
// 字段汇总 排序等
String[] field = yAxis.stream().map(y -> {
StringBuilder f = new StringBuilder();
......@@ -178,7 +181,7 @@ public class DorisQueryProvider extends QueryProvider {
StringUtils.join(groupField, ","),
StringUtils.join(field, ","),
table,
xFilter.length > 0 ? StringUtils.join(xFilter, " ") : "" + transMysqlExtFilter(extFilterRequestList),// origin field filter and panel field filter
(xFilter.length > 0 ? StringUtils.join(xFilter, " ") : "") + transCustomFilter(customFilter) + transExtFilter(extFilterRequestList),// origin field filter and panel field filter
StringUtils.join(group, ","),
StringUtils.join(order, ","));
if (sql.endsWith(",")) {
......@@ -220,8 +223,8 @@ public class DorisQueryProvider extends QueryProvider {
}
@Override
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL(" (" + sql + ") AS tmp ", xAxis, yAxis, extFilterRequestList);
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL(" (" + sql + ") AS tmp ", xAxis, yAxis, customFilter, extFilterRequestList);
}
@Override
......@@ -255,12 +258,43 @@ public class DorisQueryProvider extends QueryProvider {
return " IS NULL ";
case "not_null":
return " IS NOT NULL ";
case "between":
return " BETWEEN ";
default:
return "";
}
}
public String transMysqlExtFilter(List<ChartExtFilterRequest> requestList) {
public String transCustomFilter(List<ChartCustomFilterDTO> requestList) {
if (CollectionUtils.isEmpty(requestList)) {
return "";
}
StringBuilder filter = new StringBuilder();
for (ChartCustomFilterDTO request : requestList) {
String value = request.getValue();
DatasetTableField field = request.getField();
if (field.getDeType() == 1 && field.getDeExtractType() != 1) {
filter.append(" AND FROM_UNIXTIME(cast(")
.append(field.getDataeaseName())
.append(" AS decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') ");
} else {
filter.append(" AND ").append(field.getDataeaseName());
}
filter.append(" ")
.append(transMysqlFilterTerm(request.getTerm()))
.append(" ");
if (StringUtils.containsIgnoreCase(request.getTerm(), "in")) {
filter.append("('").append(StringUtils.join(value, "','")).append("')");
} else if (StringUtils.containsIgnoreCase(request.getTerm(), "like")) {
filter.append("'%").append(value).append("%'");
} else {
filter.append("'").append(value).append("'");
}
}
return filter.toString();
}
public String transExtFilter(List<ChartExtFilterRequest> requestList) {
if (CollectionUtils.isEmpty(requestList)) {
return "";
}
......@@ -285,6 +319,11 @@ public class DorisQueryProvider extends QueryProvider {
filter.append("('").append(StringUtils.join(value, "','")).append("')");
} else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) {
filter.append("'%").append(value.get(0)).append("%'");
} else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String startTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(0))));
String endTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(1))));
filter.append("'").append(startTime).append("' AND '").append(endTime).append("'");
} else {
filter.append("'").append(value.get(0)).append("'");
}
......
......@@ -2,6 +2,7 @@ package io.dataease.provider.mysql;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import io.dataease.dto.chart.ChartCustomFilterDTO;
import io.dataease.dto.chart.ChartViewFieldDTO;
import io.dataease.provider.QueryProvider;
import org.apache.commons.collections4.CollectionUtils;
......@@ -9,7 +10,9 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
......@@ -108,7 +111,7 @@ public class MysqlQueryProvider extends QueryProvider {
}
@Override
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartExtFilterRequest> extFilterRequestList) {
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
// 字段汇总 排序等
String[] field = yAxis.stream().map(y -> {
StringBuilder f = new StringBuilder();
......@@ -184,7 +187,7 @@ public class MysqlQueryProvider extends QueryProvider {
StringUtils.join(groupField, ","),
StringUtils.join(field, ","),
table,
(xFilter.length > 0 ? StringUtils.join(xFilter, " ") : "") + transMysqlExtFilter(extFilterRequestList),// origin field filter and panel field filter
(xFilter.length > 0 ? StringUtils.join(xFilter, " ") : "") + transCustomFilter(customFilter) + transExtFilter(extFilterRequestList),// origin field filter and panel field filter
StringUtils.join(group, ","),
StringUtils.join(order, ","));
if (sql.endsWith(",")) {
......@@ -227,8 +230,8 @@ public class MysqlQueryProvider extends QueryProvider {
}
@Override
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL(" (" + sqlFix(sql) + ") AS tmp ", xAxis, yAxis, extFilterRequestList);
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL(" (" + sqlFix(sql) + ") AS tmp ", xAxis, yAxis, customFilter, extFilterRequestList);
}
@Override
......@@ -262,12 +265,43 @@ public class MysqlQueryProvider extends QueryProvider {
return " IS NULL ";
case "not_null":
return " IS NOT NULL ";
case "between":
return " BETWEEN ";
default:
return "";
}
}
public String transMysqlExtFilter(List<ChartExtFilterRequest> requestList) {
public String transCustomFilter(List<ChartCustomFilterDTO> requestList) {
if (CollectionUtils.isEmpty(requestList)) {
return "";
}
StringBuilder filter = new StringBuilder();
for (ChartCustomFilterDTO request : requestList) {
String value = request.getValue();
DatasetTableField field = request.getField();
if (field.getDeType() == 1 && field.getDeExtractType() != 1) {
filter.append(" AND FROM_UNIXTIME(cast(")
.append(field.getDataeaseName())
.append(" AS decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') ");
} else {
filter.append(" AND ").append(field.getDataeaseName());
}
filter.append(" ")
.append(transMysqlFilterTerm(request.getTerm()))
.append(" ");
if (StringUtils.containsIgnoreCase(request.getTerm(), "in")) {
filter.append("('").append(StringUtils.join(value, "','")).append("')");
} else if (StringUtils.containsIgnoreCase(request.getTerm(), "like")) {
filter.append("'%").append(value).append("%'");
} else {
filter.append("'").append(value).append("'");
}
}
return filter.toString();
}
public String transExtFilter(List<ChartExtFilterRequest> requestList) {
if (CollectionUtils.isEmpty(requestList)) {
return "";
}
......@@ -292,6 +326,11 @@ public class MysqlQueryProvider extends QueryProvider {
filter.append("('").append(StringUtils.join(value, "','")).append("')");
} else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) {
filter.append("'%").append(value.get(0)).append("%'");
} else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String startTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(0))));
String endTime = simpleDateFormat.format(new Date(Long.parseLong(value.get(1))));
filter.append("'").append(startTime).append("' AND '").append(endTime).append("'");
} else {
filter.append("'").append(value.get(0)).append("'");
}
......
......@@ -2,6 +2,7 @@ package io.dataease.provider.sqlserver;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import io.dataease.dto.chart.ChartCustomFilterDTO;
import io.dataease.dto.chart.ChartViewFieldDTO;
import io.dataease.provider.QueryProvider;
import org.apache.commons.collections4.CollectionUtils;
......@@ -111,7 +112,7 @@ public class SqlserverQueryProvider extends QueryProvider {
}
@Override
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartExtFilterRequest> extFilterRequestList) {
public String getSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
// 字段汇总 排序等
String[] field = yAxis.stream().map(y -> {
StringBuilder f = new StringBuilder();
......@@ -187,7 +188,7 @@ public class SqlserverQueryProvider extends QueryProvider {
StringUtils.join(groupField, ","),
StringUtils.join(field, ","),
table,
(xFilter.length > 0 ? StringUtils.join(xFilter, " ") : "") + transMysqlExtFilter(extFilterRequestList),// origin field filter and panel field filter
(xFilter.length > 0 ? StringUtils.join(xFilter, " ") : "") + transCustomFilter(customFilter) + transExtFilter(extFilterRequestList),// origin field filter and panel field filter
StringUtils.join(group, ","),
StringUtils.join(order, ","));
if (sql.endsWith(",")) {
......@@ -230,8 +231,8 @@ public class SqlserverQueryProvider extends QueryProvider {
}
@Override
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL(" (" + sqlFix(sql) + ") AS tmp ", xAxis, yAxis, extFilterRequestList);
public String getSQLAsTmp(String sql, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartCustomFilterDTO> customFilter, List<ChartExtFilterRequest> extFilterRequestList) {
return getSQL(" (" + sqlFix(sql) + ") AS tmp ", xAxis, yAxis, customFilter, extFilterRequestList);
}
@Override
......@@ -270,7 +271,36 @@ public class SqlserverQueryProvider extends QueryProvider {
}
}
public String transMysqlExtFilter(List<ChartExtFilterRequest> requestList) {
public String transCustomFilter(List<ChartCustomFilterDTO> requestList) {
if (CollectionUtils.isEmpty(requestList)) {
return "";
}
StringBuilder filter = new StringBuilder();
for (ChartCustomFilterDTO request : requestList) {
String value = request.getValue();
DatasetTableField field = request.getField();
if (field.getDeType() == 1 && field.getDeExtractType() != 1) {
filter.append(" AND FROM_UNIXTIME(cast(")
.append(field.getDataeaseName())
.append(" AS decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') ");
} else {
filter.append(" AND ").append(field.getDataeaseName());
}
filter.append(" ")
.append(transMysqlFilterTerm(request.getTerm()))
.append(" ");
if (StringUtils.containsIgnoreCase(request.getTerm(), "in")) {
filter.append("('").append(StringUtils.join(value, "','")).append("')");
} else if (StringUtils.containsIgnoreCase(request.getTerm(), "like")) {
filter.append("'%").append(value).append("%'");
} else {
filter.append("'").append(value).append("'");
}
}
return filter.toString();
}
public String transExtFilter(List<ChartExtFilterRequest> requestList) {
if (CollectionUtils.isEmpty(requestList)) {
return "";
}
......
......@@ -15,6 +15,7 @@ import io.dataease.datasource.provider.DatasourceProvider;
import io.dataease.datasource.provider.ProviderFactory;
import io.dataease.datasource.request.DatasourceRequest;
import io.dataease.datasource.service.DatasourceService;
import io.dataease.dto.chart.ChartCustomFilterDTO;
import io.dataease.dto.chart.ChartViewDTO;
import io.dataease.dto.chart.ChartViewFieldDTO;
import io.dataease.dto.chart.Series;
......@@ -31,6 +32,7 @@ import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Author gin
......@@ -89,6 +91,9 @@ public class ChartViewService {
}.getType());
List<ChartViewFieldDTO> yAxis = new Gson().fromJson(view.getYAxis(), new TypeToken<List<ChartViewFieldDTO>>() {
}.getType());
List<ChartCustomFilterDTO> customFilter = new Gson().fromJson(view.getCustomFilter(), new TypeToken<List<ChartCustomFilterDTO>>() {
}.getType());
customFilter.forEach(ele -> ele.setField(dataSetTableFieldsService.get(ele.getFieldId())));
if (CollectionUtils.isEmpty(xAxis) || CollectionUtils.isEmpty(yAxis)) {
ChartViewDTO dto = new ChartViewDTO();
......@@ -127,9 +132,9 @@ public class ChartViewService {
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
if (StringUtils.equalsIgnoreCase(table.getType(), "db")) {
datasourceRequest.setTable(dataTableInfoDTO.getTable());
datasourceRequest.setQuery(qp.getSQL(dataTableInfoDTO.getTable(), xAxis, yAxis, extFilterList));
datasourceRequest.setQuery(qp.getSQL(dataTableInfoDTO.getTable(), xAxis, yAxis, customFilter, extFilterList));
} else if (StringUtils.equalsIgnoreCase(table.getType(), "sql")) {
datasourceRequest.setQuery(qp.getSQLAsTmp(dataTableInfoDTO.getSql(), xAxis, yAxis, extFilterList));
datasourceRequest.setQuery(qp.getSQLAsTmp(dataTableInfoDTO.getSql(), xAxis, yAxis, customFilter, extFilterList));
}
data = datasourceProvider.getData(datasourceRequest);
} else if (table.getMode() == 1) {// 抽取
......@@ -141,7 +146,7 @@ public class ChartViewService {
String tableName = "ds_" + table.getId().replaceAll("-", "_");
datasourceRequest.setTable(tableName);
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, extFilterList));
datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList));
data = datasourceProvider.getData(datasourceRequest);
}
......
package io.dataease.service.dataset.impl.direct;
import com.google.gson.Gson;
import io.dataease.base.domain.DatasetTable;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.base.domain.Datasource;
import io.dataease.commons.utils.CommonBeanFactory;
import io.dataease.datasource.provider.DatasourceProvider;
import io.dataease.datasource.provider.ProviderFactory;
import io.dataease.datasource.request.DatasourceRequest;
import io.dataease.datasource.service.DatasourceService;
import io.dataease.dto.dataset.DataTableInfoDTO;
import io.dataease.provider.QueryProvider;
import io.dataease.service.dataset.DataSetFieldService;
import io.dataease.service.dataset.DataSetTableFieldsService;
......@@ -53,15 +56,34 @@ public class DirectFieldService implements DataSetFieldService {
if (ObjectUtils.isEmpty(datasetTable) || StringUtils.isEmpty(datasetTable.getName())) return null;
String tableName = datasetTable.getName();
String dataSourceId = datasetTable.getDataSourceId();
if (StringUtils.isEmpty(dataSourceId)) return null;
Datasource ds = datasourceService.get(dataSourceId);
DatasourceProvider datasourceProvider = ProviderFactory.getProvider(ds.getType());
DatasourceRequest datasourceRequest = new DatasourceRequest();
datasourceRequest.setDatasource(ds);
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
String querySQL = qp.createQuerySQL(tableName, Collections.singletonList(field));
datasourceRequest.setQuery(querySQL);
DatasourceProvider datasourceProvider = null;
if (datasetTable.getMode() == 0) {// 直连
if (StringUtils.isEmpty(datasetTable.getDataSourceId())) return null;
Datasource ds = datasourceService.get(datasetTable.getDataSourceId());
datasourceProvider = ProviderFactory.getProvider(ds.getType());
datasourceRequest = new DatasourceRequest();
datasourceRequest.setDatasource(ds);
DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(datasetTable.getInfo(), DataTableInfoDTO.class);
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "db")) {
datasourceRequest.setTable(dataTableInfoDTO.getTable());
datasourceRequest.setQuery(qp.createQuerySQL(dataTableInfoDTO.getTable(), Collections.singletonList(field)));
} else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql")) {
datasourceRequest.setQuery(qp.createQuerySQLAsTmp(dataTableInfoDTO.getSql(), Collections.singletonList(field)));
}
} else if (datasetTable.getMode() == 1) {// 抽取
// 连接doris,构建doris数据源查询
Datasource ds = (Datasource) CommonBeanFactory.getBean("DorisDatasource");
datasourceProvider = ProviderFactory.getProvider(ds.getType());
datasourceRequest = new DatasourceRequest();
datasourceRequest.setDatasource(ds);
tableName = "ds_" + datasetTable.getId().replaceAll("-", "_");
datasourceRequest.setTable(tableName);
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
datasourceRequest.setQuery(qp.createQuerySQL(tableName, Collections.singletonList(field)));
}
try {
List<String[]> rows = datasourceProvider.getData(datasourceRequest);
List<Object> results = rows.stream().map(row -> row[0]).distinct().collect(Collectors.toList());
......
......@@ -42,9 +42,9 @@ INSERT INTO `sys_menu` VALUES (36, 1, 0, 1, '菜单表单', 'system-menu-form',
INSERT INTO `sys_menu` VALUES (37, 1, 0, 1, '组织表单', 'system-dept-form', 'system/dept/form', 12, '', 'dept-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (38, 1, 0, 1, '角色表单', 'system-role-form', 'system/role/form', 13, '', 'role-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (39, 0, 0, 1, '数据源表单', 'datasource-form', 'system/datasource/form', 5, NULL, '/ds-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (40, 1, 0, 1, '模板管理', 'system-template', 'panel/template/index', 13, 'dashboard', 'panel/template/index', NULL, b'0', b'0', 'sysparam:read', NULL, NULL, NULL, 1620444227389);
INSERT INTO `sys_menu` VALUES (41, 1, 0, 1, '权限管理', 'system-auth', 'system/authority/index', 14, 'password', 'system/authority/index', b'0', b'0', b'0', 'sysparam:read', NULL, NULL, NULL, 1620447312657);
INSERT INTO `sys_menu` VALUES (42, 1, 0, 1, '插件管理', 'system-plugin', 'system/plugin/index', 15, 'sys-tools', '/plugin', b'0', b'0', b'0', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (40, 1, 0, 1, '模板管理', 'system-template', 'panel/template/index', 13, 'dashboard', 'panel/template/index', NULL, b'0', b'0', 'template:read', NULL, NULL, NULL, 1620444227389);
INSERT INTO `sys_menu` VALUES (41, 1, 0, 1, '权限管理', 'system-auth', 'system/authority/index', 14, 'password', 'system/authority/index', b'0', b'0', b'0', 'auth:read', NULL, NULL, NULL, 1620447312657);
INSERT INTO `sys_menu` VALUES (42, 1, 0, 1, '插件管理', 'system-plugin', 'system/plugin/index', 15, 'sys-tools', '/plugin', b'0', b'0', b'0', 'plugin:read', NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (50, 0, 0, 1, '个人信息', 'person-info', 'system/user/privateForm', 999, NULL, '/person-info', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (51, 0, 0, 1, '重置密码', 'person-pwd-reset', 'system/user/personPwd', 999, NULL, '/person-pwd', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (52, 0, 0, 1, '关于', 'about', 'system/about/index', 16, 'system', '/about', b'0', b'0', b'1', NULL, NULL, NULL, NULL, 1620897406691);
......
<template>
<div id="canvasInfo" :style="customStyle" class="bg">
<el-row v-if="componentDataShow.length===0" style="height: 100%;" class="custom-position">
<!-- {{ $t('panel.panel_null') }} -->
{{ $t('panel.panelNull') }}
</el-row>
<ComponentWrapper
v-for="(item, index) in componentDataInfo"
......
......@@ -148,6 +148,7 @@ export default {
<style lang="scss" scoped>
.bg {
height: 100vh!important;
min-width: 800px;
min-height: 600px;
width: 100%;
......
<template>
<div style="width: 100%;height: 100vh;">
<span style="line-height: 35px; position: absolute; top:10px;right: 20px;z-index:100000">
<el-button size="mini" @click="toDir">
<el-button size="mini" @click="close">
关闭
</el-button>
</span>
......@@ -18,9 +18,8 @@ export default {
components: { Preview },
methods: {
toDir() {
this.$router.replace('/panel/index')
bus.$emit('PanelSwitchComponent', { name: 'PanelEdit' })
close() {
bus.$emit('previewFullScreenClose')
}
}
}
......
......@@ -221,8 +221,7 @@ export default {
},
clickPreview() {
// 编辑时临时保存 当前修改的画布
this.$router.replace('/PreviewFullScreen')
this.$emit('previewFullScreen')
}
}
}
......
......@@ -12,6 +12,7 @@ const dialogPanel = {
attrs: {
multiple: false,
placeholder: '请选择',
viewIds: [],
datas: [],
key: 'id',
label: 'text',
......
......@@ -672,7 +672,9 @@ export default {
only_one_result: 'Only show first result',
dimension_show: 'Dimension Show',
quota_show: 'Quota Show',
title_limit: 'Title cannot be greater than 50 characters'
title_limit: 'Title cannot be greater than 50 characters',
filter_condition: 'Filter Condition',
filter_field_can_null: 'Filter field must choose'
},
dataset: {
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',
......@@ -887,7 +889,7 @@ export default {
insert_picture: 'Insert Picture',
redo: 'Redo',
undo: 'Undo',
panel_null: 'This is a Empty Panel,You Can Edit and Enrich It'
panelNull: 'This is a Empty Panel,You Can Edit and Enrich It'
},
plugin: {
local_install: 'Local installation',
......
......@@ -671,7 +671,9 @@ export default {
only_one_result: '僅顯示第1個計算結果',
dimension_show: '維度顯示',
quota_show: '指標顯示',
title_limit: '標題不能大於50個字符'
title_limit: '標題不能大於50個字符',
filter_condition: '過濾條件',
filter_field_can_null: '過濾字段必填'
},
dataset: {
sheet_warn: '有多個sheet頁面,默認抽取第一個',
......@@ -886,7 +888,7 @@ export default {
insert_picture: '插入圖片',
redo: '重做',
undo: '撤銷',
panel_null: '这是个空的儀表盤,可以通过编辑来丰富内容'
panelNull: '这是个空的儀表盤,可以通过编辑来丰富内容'
},
plugin: {
local_install: '本地安裝',
......
......@@ -673,7 +673,9 @@ export default {
only_one_result: '仅显示第1个计算结果',
dimension_show: '维度显示',
quota_show: '指标显示',
title_limit: '标题不能大于50个字符'
title_limit: '标题不能大于50个字符',
filter_condition: '过滤条件',
filter_field_can_null: '过滤字段必填'
},
dataset: {
sheet_warn: '有多个Sheet页,默认抽取第一个',
......@@ -888,7 +890,7 @@ export default {
insert_picture: '插入图片',
redo: '重做',
undo: '撤销',
panel_null: '这是个空的仪表板,可以通过编辑来丰富内容'
panelNull: '这是个空的仪表板,可以通过编辑来丰富内容'
},
plugin: {
local_install: '本地安装',
......
......@@ -21,5 +21,6 @@ Vue.use(ElementUI, {
new Vue({
router,
store,
i18n,
render: h => h(Link)
}).$mount('#link')
......@@ -99,6 +99,22 @@ div:focus {
}
}
.preview-dialog {
padding: 0px!important;
.el-dialog--center{
padding: 0px!important;
}
.el-dialog__header{
display:none!important;
}
.el-dialog__body{
padding: 0px!important;
height: 100vh!important;
}
}
.de-search-header {
.el-tabs__header{
display: none !important;;
......
<template>
<el-col>
<el-button icon="el-icon-plus" circle size="mini" style="margin-bottom: 10px;" @click="addFilter" />
<el-row v-for="(f,index) in item.filter" :key="index" class="filter-item">
<el-col :span="4">
<span>{{ item.name }}</span>
</el-col>
<el-col :span="8">
<el-select v-model="f.term" size="mini">
<el-option-group
v-for="(group,idx) in options"
:key="idx"
:label="group.label"
>
<el-option
v-for="opt in group.options"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-option-group>
</el-select>
</el-col>
<el-col :span="6">
<el-input v-model="f.value" class="value-item" :placeholder="$t('chart.no_limit')" size="mini" clearable />
</el-col>
<el-col :span="6">
<el-button type="text" icon="el-icon-delete" circle style="float: right" @click="removeFilter(index)" />
</el-col>
</el-row>
<div style="max-height: 50vh;overflow-y: auto;">
<el-row v-for="(f,index) in item.filter" :key="index" class="filter-item">
<el-col :span="4">
<span>{{ item.name }}</span>
</el-col>
<el-col :span="8">
<el-select v-model="f.term" size="mini">
<el-option-group
v-for="(group,idx) in options"
:key="idx"
:label="group.label"
>
<el-option
v-for="opt in group.options"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-option-group>
</el-select>
</el-col>
<el-col :span="6">
<el-input v-model="f.value" class="value-item" :placeholder="$t('chart.no_limit')" size="mini" clearable />
</el-col>
<el-col :span="6">
<el-button type="text" icon="el-icon-delete" circle style="float: right" @click="removeFilter(index)" />
</el-col>
</el-row>
</div>
</el-col>
</template>
......
<template>
<el-col>
<el-button icon="el-icon-plus" circle size="mini" style="margin-bottom: 10px;" @click="addFilter" />
<el-row v-for="(f,index) in item.filter" :key="index" class="filter-item">
<el-col :span="4">
<span>{{ item.name }} ({{ $t('chart.'+item.summary) }})</span>
</el-col>
<el-col :span="8">
<el-select v-model="f.term" size="mini">
<el-option-group
v-for="(group,idx) in options"
:key="idx"
:label="group.label"
>
<el-option
v-for="opt in group.options"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-option-group>
</el-select>
</el-col>
<el-col :span="6">
<el-input v-model="f.value" class="value-item" :placeholder="$t('chart.no_limit')" size="mini" clearable />
</el-col>
<el-col :span="6">
<el-button type="text" icon="el-icon-delete" circle style="float: right" @click="removeFilter(index)" />
</el-col>
</el-row>
<div style="max-height: 50vh;overflow-y: auto;">
<el-row v-for="(f,index) in item.filter" :key="index" class="filter-item">
<el-col :span="4">
<span>{{ item.name }} ({{ $t('chart.'+item.summary) }})</span>
</el-col>
<el-col :span="8">
<el-select v-model="f.term" size="mini">
<el-option-group
v-for="(group,idx) in options"
:key="idx"
:label="group.label"
>
<el-option
v-for="opt in group.options"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-option-group>
</el-select>
</el-col>
<el-col :span="6">
<el-input v-model="f.value" class="value-item" :placeholder="$t('chart.no_limit')" size="mini" clearable />
</el-col>
<el-col :span="6">
<el-button type="text" icon="el-icon-delete" circle style="float: right" @click="removeFilter(index)" />
</el-col>
</el-row>
</div>
</el-col>
</template>
......
<template>
<el-col>
<el-button icon="el-icon-plus" circle size="mini" style="margin-bottom: 10px;" @click="addFilter" />
<div style="max-height: 50vh;overflow-y: auto;">
<el-row v-for="(f,index) in chart.customFilter" :key="index" class="filter-item">
<el-col :span="6">
<el-select v-model="f.fieldId" size="mini" filterable>
<el-option
v-for="item in fields"
:key="item.id"
:label="item.name"
:value="item.id"
>
<span style="float: left">
<svg-icon v-if="item.deType === 0" icon-class="field_text" class="field-icon-text" />
<svg-icon v-if="item.deType === 1" icon-class="field_time" class="field-icon-time" />
<svg-icon v-if="item.deType === 2 || item.deType === 3" icon-class="field_value" class="field-icon-value" />
</span>
<span style="float: left; color: #8492a6; font-size: 12px">{{ item.name }}</span>
</el-option>
</el-select>
</el-col>
<el-col :span="6">
<el-select v-model="f.term" size="mini">
<el-option-group
v-for="(group,idx) in options"
:key="idx"
:label="group.label"
>
<el-option
v-for="opt in group.options"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-option-group>
</el-select>
</el-col>
<el-col :span="6">
<el-input v-model="f.value" class="value-item" :placeholder="$t('chart.no_limit')" size="mini" clearable />
</el-col>
<el-col :span="6">
<el-button type="text" icon="el-icon-delete" circle style="float: right" @click="removeFilter(index)" />
</el-col>
</el-row>
</div>
</el-col>
</template>
<script>
import { fieldList } from '../../../../api/dataset/dataset'
export default {
name: 'ResultFilterEditor',
props: {
chart: {
type: Object,
required: true
}
},
data() {
return {
options: [{
label: '',
options: [{
value: 'eq',
label: this.$t('chart.filter_eq')
}, {
value: 'not_eq',
label: this.$t('chart.filter_not_eq')
}]
}, {
label: '',
options: [{
value: 'lt',
label: this.$t('chart.filter_lt')
}, {
value: 'gt',
label: this.$t('chart.filter_gt')
}]
},
{
label: '',
options: [{
value: 'le',
label: this.$t('chart.filter_le')
}, {
value: 'ge',
label: this.$t('chart.filter_ge')
}]
},
{
label: '',
options: [{
value: 'null',
label: this.$t('chart.filter_null')
}, {
value: 'not_null',
label: this.$t('chart.filter_not_null')
}]
}],
fields: []
}
},
mounted() {
fieldList(this.chart.tableId).then(response => {
this.fields = response.data
})
},
methods: {
addFilter() {
this.chart.customFilter.push({
fieldId: '',
term: 'eq',
value: ''
})
},
removeFilter(index) {
this.chart.customFilter.splice(index, 1)
}
}
}
</script>
<style scoped>
.filter-item{
width: 100%;
border-radius: 4px;
border: 1px solid #DCDFE6;
padding: 4px 14px;
margin-bottom: 10px;
display: flex;
justify-content: left;
align-items: center;
}
.form-item>>>.el-form-item__label{
font-size: 12px;
}
span{
font-size: 12px;
}
.value-item>>>.el-input{
position: relative;
display: inline-block;
width: 80px!important;
}
.el-select-dropdown__item{
padding: 0 20px;
font-size: 12px;
}
</style>
......@@ -13,9 +13,6 @@
<span slot="reference" style="line-height: 40px;cursor: pointer;">{{ view.name }}</span>
</el-popover>
<span style="float: right;line-height: 40px;">
<el-button size="mini" :loading="loading" @click="saveSnapshot">
{{ $t('chart.save_snapshot') }}
</el-button>
<el-button size="mini" @click="closeEdit">
{{ $t('commons.save') }}
</el-button>
......@@ -168,22 +165,11 @@
</el-tab-pane>
</el-tabs>
</div>
<div v-if="false" style="overflow:auto;border-top: 1px solid #e6e6e6" class="padding-lr filter-class">
<div style="height:60px;overflow:auto;border-top: 1px solid #e6e6e6" class="padding-lr filter-class">
<span>{{ $t('chart.result_filter') }}</span>
<div style="margin: 8px" class="filter-inner-class">
<draggable
v-model="view.customFilter"
group="drag"
animation="300"
:move="onMove"
style="height:100%;margin:0;overflow-x: auto;background-color: white;"
@end="end2"
>
<transition-group class="draggable-group">
<filter-item v-for="(item,index) in view.customFilter" :key="item.id" :index="index" :item="item" />
</transition-group>
</draggable>
</div>
<el-button size="mini" class="filter-btn-class" @click="showResultFilter">
{{ $t('chart.filter_condition') }}<i class="el-icon-setting el-icon--right" />
</el-button>
</div>
</el-col>
......@@ -191,7 +177,7 @@
<el-row style="width: 100%;height: 100%;" class="padding-lr">
<el-row style="margin-top: 10px;">
<el-row style="display:flex;height: 32px;">
<span style="line-height: 32px;width: 60px;text-align: right;">{{ $t('chart.dimension') }}</span>
<span style="line-height: 32px;width: 80px;text-align: right;">{{ $t('chart.dimension') }}</span>
<draggable
v-model="view.xaxis"
group="dimension"
......@@ -206,7 +192,7 @@
</draggable>
</el-row>
<el-row style="display:flex;height: 32px;margin-top: 10px;">
<span style="line-height: 32px;width: 60px;text-align: right;">{{ $t('chart.quota') }}</span>
<span style="line-height: 32px;width: 80px;text-align: right;">{{ $t('chart.quota') }}</span>
<draggable
v-model="view.yaxis"
group="quota"
......@@ -278,6 +264,20 @@
<el-button type="primary" size="mini" @click="saveDimensionFilter">{{ $t('chart.confirm') }}</el-button>
</div>
</el-dialog>
<el-dialog
v-dialogDrag
:title="$t('chart.add_filter')"
:visible="resultFilterEdit"
:show-close="false"
width="800px"
class="dialog-css"
>
<result-filter-editor :chart="chartForFilter" />
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="closeResultFilter">{{ $t('chart.cancel') }}</el-button>
<el-button type="primary" size="mini" @click="saveResultFilter">{{ $t('chart.confirm') }}</el-button>
</div>
</el-dialog>
</el-row>
</template>
......@@ -286,7 +286,7 @@ import { post, ajaxGetData } from '@/api/chart/chart'
import draggable from 'vuedraggable'
import DimensionItem from '../components/drag-item/DimensionItem'
import QuotaItem from '../components/drag-item/QuotaItem'
import FilterItem from '../components/drag-item/FilterItem'
import ResultFilterEditor from '../components/filter/ResultFilterEditor'
import ChartComponent from '../components/ChartComponent'
import bus from '@/utils/bus'
import DatasetChartDetail from '../../dataset/common/DatasetChartDetail'
......@@ -320,7 +320,7 @@ import html2canvas from 'html2canvas'
export default {
name: 'ChartEdit',
components: { LabelNormal, DimensionFilterEditor, TableNormal, DatasetChartDetail, QuotaFilterEditor, BackgroundColorSelector, FilterItem, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable },
components: { ResultFilterEditor, LabelNormal, DimensionFilterEditor, TableNormal, DatasetChartDetail, QuotaFilterEditor, BackgroundColorSelector, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable },
props: {
param: {
type: Object,
......@@ -362,6 +362,8 @@ export default {
dimensionItem: {},
quotaFilterEdit: false,
quotaItem: {},
resultFilterEdit: false,
chartForFilter: {},
renameItem: false,
itemForm: {
name: ''
......@@ -787,6 +789,30 @@ export default {
this.closeQuotaFilter()
},
showResultFilter() {
this.chartForFilter = JSON.parse(JSON.stringify(this.view))
this.resultFilterEdit = true
},
closeResultFilter() {
this.resultFilterEdit = false
},
saveResultFilter() {
for (let i = 0; i < this.chartForFilter.customFilter.length; i++) {
const f = this.chartForFilter.customFilter[i]
if (!f.fieldId || f.fieldId === '') {
this.$message({
message: this.$t('chart.filter_field_can_null'),
type: 'error',
showClose: true
})
return
}
}
this.view.customFilter = this.chartForFilter.customFilter
this.save(true)
this.closeResultFilter()
},
showRename(val) {
this.itemForm = JSON.parse(JSON.stringify(val))
this.renameItem = true
......@@ -951,7 +977,7 @@ export default {
}
.attr-style{
height: calc(100vh - 56px - 25vh - 40px - 62px - 10px);
height: calc(100vh - 56px - 25vh - 40px - 62px - 10px - 60px);
}
.attr-selector{
......@@ -995,4 +1021,13 @@ export default {
.dialog-css >>> .el-dialog__body {
padding: 10px 20px 20px;
}
.filter-btn-class{
padding: 6px;
border: none;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
......@@ -42,14 +42,14 @@
</span>
</el-tree>
</el-row>
<el-row v-if="detailItem&&detailItem.snapshot" class="detail-class">
<el-card class="filter-card-class">
<div slot="header" class="button-div-class">
<span>{{ detailItem.name }}</span>
</div>
<img draggable="false" class="view-list-thumbnails" :src="detailItem.snapshot" alt="">
</el-card>
</el-row>
<!-- <el-row v-if="detailItem&&detailItem.snapshot" class="detail-class">-->
<!-- <el-card class="filter-card-class">-->
<!-- <div slot="header" class="button-div-class">-->
<!-- <span>{{ detailItem.name }}</span>-->
<!-- </div>-->
<!-- <img draggable="false" class="view-list-thumbnails" :src="detailItem.snapshot" alt="">-->
<!-- </el-card>-->
<!-- </el-row>-->
</el-row>
</el-col>
</template>
......
......@@ -8,7 +8,7 @@
</el-col>
<!--横向工具栏-->
<el-col :span="16">
<Toolbar @showPanel="showPanel" @close-left-panel="closeLeftPanel" />
<Toolbar @showPanel="showPanel" @close-left-panel="closeLeftPanel" @previewFullScreen="previewFullScreen" />
</el-col>
</el-header>
<de-container>
......@@ -110,6 +110,15 @@
</span>
</div>
</el-dialog>
<el-dialog
v-if="previewVisible"
:visible.sync="previewVisible"
:fullscreen="true"
custom-class="preview-dialog"
>
<PreviewFullScreen />
</el-dialog>
</el-row>
</template>
......@@ -130,6 +139,7 @@ import { mapState } from 'vuex'
import { uuid } from 'vue-uuid'
import Toolbar from '@/components/canvas/components/Toolbar'
import { get } from '@/api/panel/panel'
import PreviewFullScreen from '@/components/canvas/components/Editor/PreviewFullScreen'
// 引入样式
import '@/components/canvas/assets/iconfont/iconfont.css'
......@@ -149,7 +159,8 @@ export default {
Editor,
Toolbar,
FilterDialog,
SubjectSetting
SubjectSetting,
PreviewFullScreen
},
data() {
return {
......@@ -164,7 +175,8 @@ export default {
filterVisible: false,
currentWidget: null,
currentFilterCom: null,
subjectVisible: false
subjectVisible: false,
previewVisible: false
}
},
......@@ -211,6 +223,10 @@ export default {
bus.$on('component-dialog-edit', () => {
this.eidtDialog()
})
bus.$on('previewFullScreenClose', () => {
this.previewVisible = false
})
},
beforeDestroy() {
const elx = this.$refs.rightPanel
......@@ -375,7 +391,11 @@ export default {
debugger
this.show = false
// this.beforeDestroy()
},
previewFullScreen() {
this.previewVisible = true
}
}
}
</script>
......
......@@ -28,6 +28,7 @@
import { deleteEnshrine, enshrineList } from '@/api/panel/enshrine'
import { uuid } from 'vue-uuid'
import { get } from '@/api/panel/panel'
import bus from '@/utils/bus'
export default {
name: 'Enshrine',
data() {
......@@ -35,7 +36,13 @@ export default {
starDatas: []
}
},
computed: {
panelInfo() {
return this.$store.state.panel.panelInfo
}
},
created() {
bus.$on('panle_start_list_refresh', this.refreshStarts)
this.initData()
},
methods: {
......@@ -62,12 +69,20 @@ export default {
remove(row) {
deleteEnshrine(row.storeId).then(res => {
this.initData()
this.panelInfo && this.panelInfo.id && row.panelGroupId === this.panelInfo.id && this.setMainNull()
})
},
initData() {
enshrineList({}).then(res => {
this.starDatas = res.data
})
},
setMainNull() {
this.$store.dispatch('panel/setPanelInfo', { id: null, name: '', preStyle: null })
},
refreshStarts(isStar) {
this.initData()
!isStar && this.setMainNull()
}
}
}
......
......@@ -51,6 +51,7 @@
</el-col>
<el-dialog
v-if="templateSaveShow"
:title="templateSaveTitle"
:visible.sync="templateSaveShow"
custom-class="de-dialog"
......@@ -66,6 +67,7 @@ import { mapState } from 'vuex'
import html2canvas from 'html2canvas'
import FileSaver from 'file-saver'
import { enshrineList, saveEnshrine, deleteEnshrine } from '@/api/panel/enshrine'
import bus from '@/utils/bus'
export default {
name: 'PanelViewShow',
components: { Preview, SaveToTemplate },
......@@ -160,11 +162,13 @@ export default {
star() {
this.panelInfo && saveEnshrine(this.panelInfo.id).then(res => {
this.hasStar = true
this.refreshStarList(true)
})
},
unstar() {
this.panelInfo && deleteEnshrine(this.panelInfo.id).then(res => {
this.hasStar = false
this.refreshStarList(false)
})
},
initHasStar() {
......@@ -172,6 +176,9 @@ export default {
enshrineList(param).then(res => {
this.hasStar = res.data && res.data.some(item => item.panelGroupId === this.panelInfo.id)
})
},
refreshStarList(isStar) {
bus.$emit('panle_start_list_refresh', isStar)
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论