Merge branch 'dev' into pr@dev_one_dot_x
This commit is contained in:
commit
44eac3c9dd
@ -7,6 +7,11 @@
|
||||
<a href="https://github.com/dataease/dataease"><img src="https://img.shields.io/github/stars/dataease/dataease?color=%231890FF&style=flat-square" alt="Stars"></a>
|
||||
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2F1dataease%2Fdataease?ref=badge_shield"><img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2Fdataease%2Fdataease.svg?type=shield" alt="FOSSA Status"></a>
|
||||
</p>
|
||||
|
||||
|说明|
|
||||
|------------------|
|
||||
|此分支为 DataEase v1.18 版本的开发分支。[DataEase v2.0.0](https://github.com/dataease/dataease/releases/tag/v2.0.0) 也已经正式发布,v2 版本的开发分支为 [dev-v2](https://github.com/dataease/dataease/tree/dev-v2)。v2 版本正在快速迭代中,如是在生产环境部署 DataEase,建议继续使用 v1.18.* 的最新稳定版本。|
|
||||
|
||||
<hr/>
|
||||
|
||||
## 什么是 DataEase?
|
||||
|
||||
@ -67,6 +67,10 @@ public class IndexController {
|
||||
if (StringUtils.isNotEmpty(attachParams)) {
|
||||
url = url + "&attachParams=" + attachParams;
|
||||
}
|
||||
String fromLink = request.getParameter("fromLink");
|
||||
if (StringUtils.isNotEmpty(fromLink)) {
|
||||
url = url + "&fromLink=" + fromLink;
|
||||
}
|
||||
response.sendRedirect(url);
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e.getMessage());
|
||||
|
||||
@ -53,6 +53,7 @@ public class SysLogController {
|
||||
@ApiOperation("导出操作日志")
|
||||
@PostMapping("/export")
|
||||
@ApiImplicitParam(name = "request", value = "查询条件", required = true)
|
||||
@SqlInjectValidator(value = {"time"})
|
||||
public void export(@RequestBody LogGridRequest request) throws Exception {
|
||||
logService.exportExcel(request);
|
||||
}
|
||||
|
||||
@ -653,7 +653,7 @@ public class DorisQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
@ -1187,7 +1187,7 @@ public class DorisQueryProvider extends QueryProvider {
|
||||
} else if (StringUtils.containsIgnoreCase(request.getOperator(), "between")) {
|
||||
if (request.getDatasetTableField().getDeType() == 1) {
|
||||
if (request.getDatasetTableField().getDeExtractType() == 1) {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
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))));
|
||||
whereValue = String.format(DorisConstants.WHERE_BETWEEN, startTime, endTime);
|
||||
|
||||
@ -602,7 +602,7 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -633,7 +633,7 @@ public class CKQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -621,7 +621,7 @@ public class Db2QueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -627,7 +627,7 @@ public class EsQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -586,7 +586,7 @@ public class HiveQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -573,7 +573,7 @@ public class ImpalaQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -557,7 +557,7 @@ public class MongoQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -7,6 +7,7 @@ import io.dataease.plugins.common.base.domain.DatasetTableFieldExample;
|
||||
import io.dataease.plugins.common.base.domain.Datasource;
|
||||
import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper;
|
||||
import io.dataease.plugins.common.constants.DeTypeConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.DorisConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.MySQLConstants;
|
||||
import io.dataease.plugins.common.constants.datasource.SQLConstants;
|
||||
import io.dataease.plugins.common.constants.engine.MysqlConstants;
|
||||
@ -160,6 +161,19 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 0))
|
||||
.build();
|
||||
List<SQLObj> xFields = new ArrayList<>();
|
||||
int originSize = fields.size();
|
||||
List<String> fieldList = fields.stream().map(DatasetTableField::getId).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(sortFields)) {
|
||||
sortFields.forEach(item -> {
|
||||
int indexOf = fieldList.indexOf(item.getId());
|
||||
if (indexOf == -1) {
|
||||
fields.add(item);
|
||||
} else {
|
||||
fields.set(indexOf, item);
|
||||
}
|
||||
});
|
||||
}
|
||||
List<SQLObj> xOrders = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(fields)) {
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
DatasetTableField f = fields.get(i);
|
||||
@ -212,6 +226,14 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
.fieldName(fieldName)
|
||||
.fieldAlias(fieldAlias)
|
||||
.build());
|
||||
if (f instanceof DeSortField) {
|
||||
DeSortField x = (DeSortField) f;
|
||||
xOrders.add(SQLObj.builder()
|
||||
.orderField(originField)
|
||||
.orderAlias(fieldAlias)
|
||||
.orderDirection(x.getOrderDirection())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,20 +251,27 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
if (whereTrees != null) wheres.add(whereTrees);
|
||||
if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres);
|
||||
|
||||
List<SQLObj> xOrders = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(sortFields)) {
|
||||
int step = fields.size();
|
||||
for (int i = step; i < (step + sortFields.size()); i++) {
|
||||
DeSortField deSortField = sortFields.get(i - step);
|
||||
SQLObj order = buildSortField(deSortField, tableObj, i);
|
||||
xOrders.add(order);
|
||||
}
|
||||
}
|
||||
if (ObjectUtils.isNotEmpty(xOrders)) {
|
||||
st_sql.add("orders", xOrders);
|
||||
}
|
||||
String sql = st_sql.render();
|
||||
ST st = stg.getInstanceOf("previewSql");
|
||||
st.add("isGroup", false);
|
||||
SQLObj tableSQL = SQLObj.builder()
|
||||
.tableName(String.format(DorisConstants.BRACKETS, sql))
|
||||
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 1))
|
||||
.build();
|
||||
st.add("table", tableSQL);
|
||||
|
||||
return st_sql.render();
|
||||
List<SQLObj> outFieldList = new ArrayList<>();
|
||||
for (int i = 0; i < originSize; i++) {
|
||||
SQLObj fieldObj = xFields.get(i);
|
||||
String outFieldAlias = tableSQL.getTableAlias() + "." + fieldObj.getFieldAlias();
|
||||
outFieldList.add(SQLObj.builder().fieldName(outFieldAlias).fieldAlias(fieldObj.getFieldAlias()).build());
|
||||
}
|
||||
st.add("groups", outFieldList);
|
||||
if (CollectionUtils.isNotEmpty(xOrders)) {
|
||||
st.add("orders", xOrders);
|
||||
return st.render() + " LIMIT 0, 10000000";
|
||||
}
|
||||
return st.render();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -611,7 +640,7 @@ public class MysqlQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -676,7 +676,7 @@ public class OracleQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -614,7 +614,7 @@ public class PgQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -621,7 +621,7 @@ public class RedshiftQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -623,7 +623,7 @@ public class SqlserverQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -913,6 +913,9 @@ public class ChartViewService {
|
||||
ChartDrillRequest head = drillRequestList.get(0);
|
||||
Map<String, String> dimValMap = new HashMap<>();
|
||||
head.getDimensionList().forEach(item -> dimValMap.put(item.getId(), item.getValue()));
|
||||
|
||||
boolean isAntVScatterNumberXAxis = CollectionUtils.isNotEmpty(xAxis) && StringUtils.equals(xAxis.get(0).getGroupType(), "q") && StringUtils.equalsIgnoreCase(view.getRender(), "antv");
|
||||
|
||||
for (int i = 0; i < drillRequestList.size(); i++) {
|
||||
ChartDrillRequest request = drillRequestList.get(i);
|
||||
ChartViewFieldDTO chartViewFieldDTO = drill.get(i);
|
||||
@ -924,14 +927,23 @@ public class ChartViewService {
|
||||
dimValMap.put(requestDimension.getId(), requestDimension.getValue());
|
||||
if (!checkDrillExist(xAxis, extStack, requestDimension.getId(), view)) {
|
||||
chartFieldMap.put(chartViewFieldDTO.getId(), chartViewFieldDTO);
|
||||
xAxis.add(chartViewFieldDTO);
|
||||
|
||||
if (isAntVScatterNumberXAxis) {
|
||||
extStack.add(chartViewFieldDTO);
|
||||
} else {
|
||||
xAxis.add(chartViewFieldDTO);
|
||||
}
|
||||
}
|
||||
if (i == drillRequestList.size() - 1) {
|
||||
ChartViewFieldDTO nextDrillField = drill.get(i + 1);
|
||||
if (!checkDrillExist(xAxis, extStack, nextDrillField.getId(), view)) {
|
||||
// get drill list first element's sort,then assign to nextDrillField
|
||||
nextDrillField.setSort(getDrillSort(xAxis, drill.get(0)));
|
||||
xAxis.add(nextDrillField);
|
||||
if (isAntVScatterNumberXAxis) {
|
||||
extStack.add(nextDrillField);
|
||||
} else {
|
||||
xAxis.add(nextDrillField);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1250,8 +1262,15 @@ public class ChartViewService {
|
||||
// 同比/环比计算,通过对比类型和数据设置,计算出对应指标的结果,然后替换结果data数组中的对应元素
|
||||
// 如果因维度变化(如时间字段缺失,时间字段的展示格式变化)导致无法计算结果的,则结果data数组中的对应元素全置为null
|
||||
// 根据不同图表类型,获得需要替换的指标index array
|
||||
for (int i = 0; i < yAxis.size(); i++) {
|
||||
ChartViewFieldDTO chartViewFieldDTO = yAxis.get(i);
|
||||
List<ChartViewFieldDTO> tempYAxis = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(xAxis) && StringUtils.equals(xAxis.get(0).getGroupType(), "q") && StringUtils.equalsIgnoreCase(view.getRender(), "antv")) {
|
||||
//针对散点图scatter处理
|
||||
tempYAxis.add(xAxis.get(0));
|
||||
}
|
||||
tempYAxis.addAll(yAxis);
|
||||
|
||||
for (int i = 0; i < tempYAxis.size(); i++) {
|
||||
ChartViewFieldDTO chartViewFieldDTO = tempYAxis.get(i);
|
||||
ChartFieldCompareDTO compareCalc = chartViewFieldDTO.getCompareCalc();
|
||||
if (ObjectUtils.isEmpty(compareCalc)) {
|
||||
continue;
|
||||
@ -1649,6 +1668,20 @@ public class ChartViewService {
|
||||
}
|
||||
|
||||
private boolean checkDrillExist(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> extStack, String fieldId, ChartViewWithBLOBs view) {
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxis)) {
|
||||
//针对判断 antv 散点图
|
||||
if (StringUtils.equals(xAxis.get(0).getGroupType(), "q") && StringUtils.equalsIgnoreCase(view.getRender(), "antv")) {
|
||||
if (CollectionUtils.isNotEmpty(extStack)) {
|
||||
for (ChartViewFieldDTO x : extStack) {
|
||||
if (StringUtils.equalsIgnoreCase(x.getId(), fieldId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxis)) {
|
||||
for (ChartViewFieldDTO x : xAxis) {
|
||||
if (StringUtils.equalsIgnoreCase(x.getId(), fieldId)) {
|
||||
@ -2122,7 +2155,7 @@ public class ChartViewService {
|
||||
JSONObject jsonObject = JSONObject.parseObject(senior);
|
||||
List<ChartSeniorAssistDTO> list = new ArrayList<>();
|
||||
JSONObject threshold = jsonObject.getJSONObject("threshold");
|
||||
if (ObjectUtils.isEmpty(threshold) || StringUtils.isBlank(threshold.toJSONString())){
|
||||
if (ObjectUtils.isEmpty(threshold) || StringUtils.isBlank(threshold.toJSONString())) {
|
||||
return list;
|
||||
}
|
||||
JSONArray tableThreshold = threshold.getJSONArray("tableThreshold");
|
||||
@ -2154,7 +2187,7 @@ public class ChartViewService {
|
||||
return list;
|
||||
}
|
||||
|
||||
private boolean solveThresholdCondition(ChartSeniorAssistDTO fieldDTO, String tableId){
|
||||
private boolean solveThresholdCondition(ChartSeniorAssistDTO fieldDTO, String tableId) {
|
||||
String fieldId = fieldDTO.getFieldId();
|
||||
String summary = fieldDTO.getSummary();
|
||||
if (StringUtils.isEmpty(fieldId) || StringUtils.isEmpty(summary)) {
|
||||
@ -2170,7 +2203,7 @@ public class ChartViewService {
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<ChartSeniorAssistDTO> getConditionFields(ChartSeniorThresholdDTO condition){
|
||||
private List<ChartSeniorAssistDTO> getConditionFields(ChartSeniorThresholdDTO condition) {
|
||||
List<ChartSeniorAssistDTO> list = new ArrayList<>();
|
||||
if (StringUtils.equalsIgnoreCase(condition.getField(), "0")) {
|
||||
return list;
|
||||
|
||||
@ -313,7 +313,7 @@ public class ChartDataBuild {
|
||||
String[] row = data.get(i1);
|
||||
|
||||
StringBuilder a = new StringBuilder();
|
||||
if (isDrill) {
|
||||
if (isDrill && !xIsNumber) {
|
||||
a.append(row[extGroupList.size() + xAxis.size() - 1]);
|
||||
} else {
|
||||
for (int i = extGroupList.size(); i < extGroupList.size() + xAxis.size(); i++) {
|
||||
@ -329,7 +329,12 @@ public class ChartDataBuild {
|
||||
AxisChartDataAntVDTO axisChartDataDTO = new AxisChartDataAntVDTO();
|
||||
|
||||
if (xIsNumber) {
|
||||
axisChartDataDTO.setX(new BigDecimal(a.toString()));
|
||||
Object v = a.toString();
|
||||
try {
|
||||
v = new BigDecimal(a.toString());
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
axisChartDataDTO.setX(v);
|
||||
} else {
|
||||
axisChartDataDTO.setX(a.toString());
|
||||
}
|
||||
@ -340,11 +345,20 @@ public class ChartDataBuild {
|
||||
List<ChartDimensionDTO> dimensionList = new ArrayList<>();
|
||||
List<ChartQuotaDTO> quotaList = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < xAxis.size(); j++) {
|
||||
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
|
||||
chartDimensionDTO.setId(xAxis.get(j).getId());
|
||||
chartDimensionDTO.setValue(row[j]);
|
||||
dimensionList.add(chartDimensionDTO);
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroupList)) {
|
||||
for (int j = 0; j < extGroupList.size(); j++) {
|
||||
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
|
||||
chartDimensionDTO.setId(extGroupList.get(j).getId());
|
||||
chartDimensionDTO.setValue(row[j]);
|
||||
dimensionList.add(chartDimensionDTO);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < xAxis.size(); j++) {
|
||||
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
|
||||
chartDimensionDTO.setId(xAxis.get(j).getId());
|
||||
chartDimensionDTO.setValue(row[j]);
|
||||
dimensionList.add(chartDimensionDTO);
|
||||
}
|
||||
}
|
||||
axisChartDataDTO.setDimensionList(dimensionList);
|
||||
|
||||
@ -360,7 +374,11 @@ public class ChartDataBuild {
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(extGroup) && xIsNumber) { //有分组时其实就是第一个
|
||||
axisChartDataDTO.setCategory(row[0]);
|
||||
if (isDrill) {
|
||||
axisChartDataDTO.setCategory(row[extGroupList.size() - 1]);
|
||||
} else {
|
||||
axisChartDataDTO.setCategory(row[0]);
|
||||
}
|
||||
} else {
|
||||
axisChartDataDTO.setCategory(yAxis.get(j).getName());
|
||||
}
|
||||
@ -983,7 +1001,7 @@ public class ChartDataBuild {
|
||||
}
|
||||
}
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extStack)) {
|
||||
fields.add(extStack.get(0));
|
||||
fields.addAll(extStack);
|
||||
}
|
||||
|
||||
if (xIsNumber) {
|
||||
@ -1051,30 +1069,18 @@ public class ChartDataBuild {
|
||||
|
||||
// 表格
|
||||
public static Map<String, Object> transTableNormal(Map<String, List<ChartViewFieldDTO>> fieldMap, ChartViewWithBLOBs view, List<String[]> data, Map<String, ColumnPermissionItem> desensitizationList) {
|
||||
String[] keys = new String[]{"labelAxis", "tooltipAxis"};
|
||||
|
||||
List<ChartViewFieldDTO> fields = new ArrayList<>();
|
||||
List<ChartViewFieldDTO> yfields = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(fieldMap.get("xAxis"))) fields.addAll(fieldMap.get("xAxis"));
|
||||
if (CollectionUtils.isNotEmpty(fieldMap.get("tooltipAxis"))) {
|
||||
fieldMap.get("tooltipAxis").forEach(field -> {
|
||||
Integer deType = field.getDeType();
|
||||
if (deType == 2 || deType == 3) {
|
||||
yfields.add(field);
|
||||
} else {
|
||||
fields.add(field);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(fieldMap.get("labelAxis"))) {
|
||||
fieldMap.get("labelAxis").forEach(field -> {
|
||||
Integer deType = field.getDeType();
|
||||
if (deType == 2 || deType == 3) {
|
||||
yfields.add(field);
|
||||
} else {
|
||||
fields.add(field);
|
||||
}
|
||||
});
|
||||
|
||||
for (Map.Entry<String, List<ChartViewFieldDTO>> entry : fieldMap.entrySet()) {
|
||||
if (StringUtils.equalsAny(entry.getKey(), keys)) {
|
||||
fields.addAll(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(fieldMap.get("yAxis"))) fields.addAll(fieldMap.get("yAxis"));
|
||||
if (CollectionUtils.isNotEmpty(yfields)) fields.addAll(yfields);
|
||||
return transTableNormal(fields, view, data, desensitizationList);
|
||||
|
||||
@ -60,16 +60,15 @@ public class StaticResourceService {
|
||||
}
|
||||
|
||||
private boolean isImage(MultipartFile file) {
|
||||
BufferedImage image = null;
|
||||
try (InputStream input = file.getInputStream()) {
|
||||
image = ImageIO.read(input);
|
||||
ImageIO.read(input);
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
Pattern pattern = Pattern.compile("\\.(png|jpg|jpeg|gif)$");
|
||||
Pattern pattern = Pattern.compile("\\.(png|jpg|jpeg|gif|svg)$");
|
||||
Matcher matcher = pattern.matcher(file.getOriginalFilename().toLowerCase());
|
||||
if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0 || !matcher.find()) {
|
||||
if (!matcher.find()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -26,8 +26,17 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g2plot": "^2.4.9",
|
||||
"@antv/l7": "^2.15.0",
|
||||
"@antv/s2": "^1.49.1",
|
||||
"@antv/l7": "2.15.0",
|
||||
"@antv/l7-component": "2.15.0",
|
||||
"@antv/l7-core": "2.15.0",
|
||||
"@antv/l7-layers": "2.15.0",
|
||||
"@antv/l7-maps": "2.15.0",
|
||||
"@antv/l7-renderer": "2.15.0",
|
||||
"@antv/l7-scene": "2.15.0",
|
||||
"@antv/l7-source": "2.15.0",
|
||||
"@antv/l7-utils": "2.15.0",
|
||||
"@antv/s2": "1.49.1",
|
||||
"@antv/util": "^2.0.17",
|
||||
"@riophae/vue-treeselect": "0.4.0",
|
||||
"@tinymce/tinymce-vue": "^3.2.8",
|
||||
"axios": "^0.21.3",
|
||||
@ -63,6 +72,7 @@
|
||||
"svgo": "1.2.2",
|
||||
"tinymce": "^5.8.2",
|
||||
"umy-ui": "^1.1.6",
|
||||
"vant": "^2.13.2",
|
||||
"vue": "2.6.10",
|
||||
"vue-clipboard2": "0.3.1",
|
||||
"vue-codemirror": "^4.0.6",
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
const user = getQueryVariable('user')
|
||||
const terminal = getQueryVariable('terminal')
|
||||
const attachParams = getQueryVariable('attachParams')
|
||||
const fromLink = getQueryVariable('fromLink')
|
||||
const baseUrl = window.location.pathname.replace('link.html', '')
|
||||
let url = baseUrl + "#/delink?link=" + encodeURIComponent(link)
|
||||
if (terminal) {
|
||||
@ -44,6 +45,9 @@
|
||||
if (attachParams) {
|
||||
url += '&attachParams=' + encodeURIComponent(attachParams)
|
||||
}
|
||||
if (fromLink) {
|
||||
url += '&fromLink=' + fromLink
|
||||
}
|
||||
window.location.href = url
|
||||
</script>
|
||||
|
||||
|
||||
16
core/frontend/public/mobile.html
Normal file
16
core/frontend/public/mobile.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover"
|
||||
/>
|
||||
<meta http-equiv="Cache-Control" content="no-cache" />
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app-mobile"></div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
44
core/frontend/public/vendor/vendor.dll.js
vendored
44
core/frontend/public/vendor/vendor.dll.js
vendored
File diff suppressed because one or more lines are too long
@ -134,6 +134,16 @@
|
||||
@change="showGridChange"
|
||||
/>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>
|
||||
<span class="icon iconfont icon-adaptor icon16" />
|
||||
<span class="text14 margin-left8">{{ $t('panel.auto_size_adaptor') }}</span>
|
||||
<el-switch
|
||||
v-model="autoSizeAdaptorSwitch"
|
||||
:class="[{['grid-active']: autoSizeAdaptorSwitch},'margin-left8']"
|
||||
size="mini"
|
||||
@change="showSizeAdaptorSwitchChange"
|
||||
/>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="openOuterParamsSet">
|
||||
<span class="icon iconfont icon-icon-quicksetting icon16" />
|
||||
<span class="text14 margin-left8">{{ $t('panel.params_setting') }}</span>
|
||||
@ -192,7 +202,7 @@
|
||||
@click="batchOption"
|
||||
><span
|
||||
class="icon-font-margin"
|
||||
>{{ batchOptStatus?$t('panel.cancel_batch_opt'):$t('panel.batch_opt') }}</span></span>
|
||||
>{{ batchOptStatus ? $t('panel.cancel_batch_opt') : $t('panel.batch_opt') }}</span></span>
|
||||
<span style="float: right;margin-right: 24px">
|
||||
<el-button
|
||||
size="mini"
|
||||
@ -264,6 +274,7 @@ import { getPanelAllLinkageInfo, saveLinkage } from '@/api/panel/linkage'
|
||||
import bus from '@/utils/bus'
|
||||
import { queryPanelJumpInfo } from '@/api/panel/linkJump'
|
||||
import { inOtherPlatform } from '@/utils/index'
|
||||
|
||||
export default {
|
||||
name: 'Toolbar',
|
||||
props: {
|
||||
@ -274,6 +285,7 @@ export default {
|
||||
return {
|
||||
showPageLine: false,
|
||||
showGridSwitch: false,
|
||||
autoSizeAdaptorSwitch: true,
|
||||
mobileLayoutInitStatus: false,
|
||||
isShowPreview: false,
|
||||
needToChange: [
|
||||
@ -330,13 +342,16 @@ export default {
|
||||
eventBus.$on('checkAndSave', this.checkAndSave)
|
||||
eventBus.$on('clearCanvas', this.clearCanvas)
|
||||
bus.$on('onSubjectChange', this.editPanelInit)
|
||||
bus.$on('editSave', this.mobileLayoutSave)
|
||||
this.scale = this.canvasStyleData.scale
|
||||
this.mobileLayoutInitStatus = this.mobileLayoutStatus
|
||||
this.showGridSwitch = this.canvasStyleData.aidedDesign.showGrid
|
||||
this.autoSizeAdaptorSwitch = this.canvasStyleData.autoSizeAdaptor || true
|
||||
this.showPageLine = this.canvasStyleData.pdfPageLine?.showPageLine
|
||||
this.autoCache()
|
||||
},
|
||||
beforeDestroy() {
|
||||
bus.$off('editSave', this.mobileLayoutSave)
|
||||
eventBus.$off('preview', this.preview)
|
||||
eventBus.$off('checkAndSave', this.checkAndSave)
|
||||
eventBus.$off('clearCanvas', this.clearCanvas)
|
||||
@ -623,6 +638,11 @@ export default {
|
||||
this.$store.commit('canvasChange')
|
||||
this.canvasStyleData.aidedDesign.showGrid = !this.canvasStyleData.aidedDesign.showGrid
|
||||
},
|
||||
showSizeAdaptorSwitchChange() {
|
||||
this.$store.commit('canvasChange')
|
||||
this.canvasStyleData.autoSizeAdaptor = !this.canvasStyleData.autoSizeAdaptor
|
||||
eventBus.$emit('componentSizeAdaptorChange')
|
||||
},
|
||||
showPageLineChange() {
|
||||
this.$store.commit('canvasChange')
|
||||
this.canvasStyleData.pdfPageLine.showPageLine = !this.canvasStyleData.pdfPageLine.showPageLine
|
||||
@ -636,13 +656,14 @@ export default {
|
||||
openMobileLayout(switchVal) {
|
||||
if (switchVal) {
|
||||
this.$store.commit('openMobileLayout')
|
||||
bus.$emit('mobile-status-change', 'openMobileLayout', this.componentData)
|
||||
} else {
|
||||
this.mobileLayoutSave()
|
||||
}
|
||||
},
|
||||
editSave() {
|
||||
if (this.mobileLayoutStatus) {
|
||||
this.mobileLayoutSave()
|
||||
bus.$emit('mobile-status-change', 'editSave')
|
||||
} else {
|
||||
this.saveLinkage()
|
||||
}
|
||||
@ -651,6 +672,9 @@ export default {
|
||||
this.$store.commit('setComponentData', JSON.parse(this.componentDataCache))
|
||||
this.$store.commit('setMobileLayoutStatus', false)
|
||||
this.$store.commit('openMobileLayout')
|
||||
if (this.mobileLayoutStatus) {
|
||||
bus.$emit('mobile-status-change', 'reset', JSON.parse(this.componentDataCache))
|
||||
}
|
||||
},
|
||||
editCancel() {
|
||||
if (this.mobileLayoutStatus) {
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
>
|
||||
<el-button-group size="mini">
|
||||
<el-button
|
||||
v-if="!isNewBlank"
|
||||
v-if="fromLink"
|
||||
size="mini"
|
||||
type="button"
|
||||
@click="back2Last"
|
||||
@ -89,8 +89,8 @@ export default {
|
||||
isPublicLink() {
|
||||
return this.$router.currentRoute.path === '/delink'
|
||||
},
|
||||
isNewBlank() {
|
||||
return window.history.length === 1
|
||||
fromLink() {
|
||||
return this.$route.query.fromLink === 'true'
|
||||
},
|
||||
containerClass() {
|
||||
return this.isPublicLink ? 'trans-pc' : 'bar-main'
|
||||
|
||||
@ -40,6 +40,7 @@
|
||||
:style="getComponentStyleDefault(config.style)"
|
||||
style="overflow: hidden"
|
||||
:out-style="config.style"
|
||||
:terminal="terminal"
|
||||
:is-relation="isRelation"
|
||||
:element="config"
|
||||
:in-screen="inScreen"
|
||||
|
||||
@ -150,13 +150,13 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import {mapState} from 'vuex'
|
||||
import Shape from './Shape'
|
||||
import DeDrag from '@/components/deDrag'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { getComponentRotatedStyle, getStyle } from '@/components/canvas/utils/style'
|
||||
import { _$, imgUrlTrans } from '@/components/canvas/utils/utils'
|
||||
import {getComponentRotatedStyle, getStyle} from '@/components/canvas/utils/style'
|
||||
import {_$, imgUrlTrans} from '@/components/canvas/utils/utils'
|
||||
import ContextMenu from './ContextMenu'
|
||||
import MarkLine from './MarkLine'
|
||||
import Area from './Area'
|
||||
@ -164,13 +164,13 @@ import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import Grid from './Grid'
|
||||
import PageLineEditor from './PageLineEditor'
|
||||
import PGrid from './PGrid'
|
||||
import { changeStyleWithScale } from '@/components/canvas/utils/translate'
|
||||
import {changeStyleWithScale} from '@/components/canvas/utils/translate'
|
||||
import UserViewDialog from '@/components/canvas/customComponent/UserViewDialog'
|
||||
import DeOutWidget from '@/components/dataease/DeOutWidget'
|
||||
import DragShadow from '@/components/deDrag/Shadow'
|
||||
import bus from '@/utils/bus'
|
||||
import LinkJumpSet from '@/views/panel/linkJumpSet'
|
||||
import { buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch } from '@/utils/conditionUtil'
|
||||
import {buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch} from '@/utils/conditionUtil'
|
||||
// 挤占式画布
|
||||
import _ from 'lodash'
|
||||
import _jq from 'jquery'
|
||||
@ -190,11 +190,11 @@ let itemMaxX = 0
|
||||
|
||||
function debounce(func, time) {
|
||||
if (!isOverlay) {
|
||||
(function(t) {
|
||||
(function (t) {
|
||||
isOverlay = true
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
t()
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
isOverlay = false
|
||||
if (lastTask !== undefined) {
|
||||
debounce(lastTask, time)
|
||||
@ -319,10 +319,10 @@ function init() {
|
||||
resetPositionBox.call(this)
|
||||
initPosition(this)
|
||||
let i = 0
|
||||
const timeid = setInterval(function() {
|
||||
const timeid = setInterval(function () {
|
||||
if (i >= vm.yourList.length) {
|
||||
clearInterval(timeid)
|
||||
vm.$nextTick(function() {
|
||||
vm.$nextTick(function () {
|
||||
vm.moveAnimate = true
|
||||
})
|
||||
} else {
|
||||
@ -339,7 +339,7 @@ function resizePlayer(item, newSize) {
|
||||
removeItemFromPositionBox.call(vm, item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
_.forEach(belowItems, function(upItem) {
|
||||
_.forEach(belowItems, function (upItem) {
|
||||
const canGoUpRows = canItemGoUp.call(vm, upItem)
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(vm, upItem, canGoUpRows)
|
||||
@ -426,7 +426,7 @@ function movePlayer(item, position) {
|
||||
removeItemFromPositionBox.call(vm, item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
_.forEach(belowItems, function(upItem) {
|
||||
_.forEach(belowItems, function (upItem) {
|
||||
const canGoUpRows = canItemGoUp.call(vm, upItem)
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(vm, upItem, canGoUpRows)
|
||||
@ -452,7 +452,7 @@ function removeItem(index) {
|
||||
removeItemFromPositionBox.call(vm, item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
_.forEach(belowItems, function(upItem) {
|
||||
_.forEach(belowItems, function (upItem) {
|
||||
const canGoUpRows = canItemGoUp.call(vm, upItem)
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(vm, upItem, canGoUpRows)
|
||||
@ -544,7 +544,7 @@ function findClosetCoords(item, tCoord) {
|
||||
y: collisionsItem[0].coord.el.y
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
isOverlay = false
|
||||
}, 200)
|
||||
}
|
||||
@ -592,7 +592,7 @@ function changeItemCoord(item) {
|
||||
el: item
|
||||
}
|
||||
|
||||
const index = _.findIndex(vm.coordinates, function(o) {
|
||||
const index = _.findIndex(vm.coordinates, function (o) {
|
||||
return o.el._dragId === item._dragId
|
||||
})
|
||||
if (index !== -1) {
|
||||
@ -609,7 +609,7 @@ function emptyTargetCell(item) {
|
||||
const vm = this
|
||||
const belowItems = findBelowItems.call(vm, item)
|
||||
|
||||
_.forEach(belowItems, function(downItem, index) {
|
||||
_.forEach(belowItems, function (downItem, index) {
|
||||
if (downItem._dragId === item._dragId) return
|
||||
const moveSize = item.y + item.sizey - downItem.y
|
||||
if (moveSize > 0) {
|
||||
@ -649,7 +649,7 @@ function moveItemDown(item, size) {
|
||||
const vm = this
|
||||
removeItemFromPositionBox.call(vm, item)
|
||||
const belowItems = findBelowItems.call(vm, item)
|
||||
_.forEach(belowItems, function(downItem, index) {
|
||||
_.forEach(belowItems, function (downItem, index) {
|
||||
if (downItem._dragId === item._dragId) return
|
||||
const moveSize = calcDiff.call(vm, item, downItem, size)
|
||||
if (moveSize > 0) {
|
||||
@ -722,7 +722,7 @@ function moveItemUp(item, size) {
|
||||
|
||||
changeItemCoord.call(this, item)
|
||||
|
||||
_.forEach(belowItems, function(upItem, index) {
|
||||
_.forEach(belowItems, function (upItem, index) {
|
||||
const moveSize = canItemGoUp.call(vm, upItem)
|
||||
if (moveSize > 0) {
|
||||
moveItemUp.call(vm, upItem, moveSize)
|
||||
@ -806,19 +806,19 @@ export default {
|
||||
dragStart: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {
|
||||
default: function () {
|
||||
}
|
||||
},
|
||||
dragging: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {
|
||||
default: function () {
|
||||
}
|
||||
},
|
||||
dragEnd: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {
|
||||
default: function () {
|
||||
}
|
||||
},
|
||||
resizable: {
|
||||
@ -829,19 +829,19 @@ export default {
|
||||
resizeStart: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {
|
||||
default: function () {
|
||||
}
|
||||
},
|
||||
resizing: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {
|
||||
default: function () {
|
||||
}
|
||||
},
|
||||
resizeEnd: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {
|
||||
default: function () {
|
||||
}
|
||||
},
|
||||
matrixCount: {
|
||||
@ -1004,6 +1004,7 @@ export default {
|
||||
return this.curCanvasScaleMap[this.canvasId]
|
||||
},
|
||||
...mapState([
|
||||
'canvasStyleData',
|
||||
'curComponent',
|
||||
'editor',
|
||||
'linkageSettingStatus',
|
||||
@ -1116,6 +1117,7 @@ export default {
|
||||
this.$store.commit('getEditor')
|
||||
const _this = this
|
||||
eventBus.$on('hideArea', this.hideArea)
|
||||
eventBus.$on('componentSizeAdaptorChange', this.changeScale)
|
||||
eventBus.$on('startMoveIn', this.startMoveIn)
|
||||
bus.$on('onRemoveLastItem', this.removeLastItem)
|
||||
bus.$on('trigger-search-button', this.triggerSearchButton)
|
||||
@ -1132,6 +1134,7 @@ export default {
|
||||
beforeDestroy() {
|
||||
eventBus.$off('hideArea', this.hideArea)
|
||||
eventBus.$off('startMoveIn', this.startMoveIn)
|
||||
eventBus.$off('componentSizeAdaptorChange', this.changeScale)
|
||||
bus.$off('onRemoveLastItem', this.removeLastItem)
|
||||
bus.$off('trigger-search-button', this.triggerSearchButton)
|
||||
bus.$off('refresh-button-info', this.refreshButtonInfo)
|
||||
@ -1287,7 +1290,7 @@ export default {
|
||||
}
|
||||
return -1
|
||||
},
|
||||
pluginEditHandler({ e, id }) {
|
||||
pluginEditHandler({e, id}) {
|
||||
let index = -1
|
||||
for (let i = 0; i < this.componentData.length; i++) {
|
||||
const item = this.componentData[i]
|
||||
@ -1397,12 +1400,12 @@ export default {
|
||||
getSelectArea() {
|
||||
const result = []
|
||||
// 区域起点坐标
|
||||
const { x, y } = this.start
|
||||
const {x, y} = this.start
|
||||
// 计算所有的组件数据,判断是否在选中区域内
|
||||
this.componentData.forEach(component => {
|
||||
if (component.isLock) return
|
||||
|
||||
const { left, top, width, height } = component.style
|
||||
const {left, top, width, height} = component.style
|
||||
if (x <= left && y <= top && (left + width <= x + this.width) && (top + height <= y + this.height)) {
|
||||
result.push(component)
|
||||
}
|
||||
@ -1458,7 +1461,7 @@ export default {
|
||||
|
||||
getTextareaHeight(element, text) {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { lineHeight, fontSize, height } = element.style
|
||||
let {lineHeight, fontSize, height} = element.style
|
||||
if (lineHeight === '') {
|
||||
lineHeight = 1.5
|
||||
}
|
||||
@ -1523,8 +1526,8 @@ export default {
|
||||
})
|
||||
if (this.canvasId === 'canvas-main') {
|
||||
this.$store.commit('setPreviewCanvasScale', {
|
||||
scaleWidth: this.scalePointWidth,
|
||||
scaleHeight: this.scalePointHeight
|
||||
scaleWidth: this.canvasStyleData.autoSizeAdaptor ? this.scalePointWidth : 1,
|
||||
scaleHeight: this.canvasStyleData.autoSizeAdaptor ? this.scalePointHeight : 1
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1549,7 +1552,7 @@ export default {
|
||||
}
|
||||
},
|
||||
getRefLineParams(params) {
|
||||
const { vLine, hLine } = params
|
||||
const {vLine, hLine} = params
|
||||
this.vLine = vLine
|
||||
this.hLine = hLine
|
||||
},
|
||||
@ -1702,8 +1705,8 @@ export default {
|
||||
newX = newX > 0 ? newX : 1
|
||||
newY = newY > 0 ? newY : 1
|
||||
if (item.sizex !== nowX || item.sizey !== nowY) {
|
||||
debounce((function(newX, oldX, newY, oldY) {
|
||||
return function() {
|
||||
debounce((function (newX, oldX, newY, oldY) {
|
||||
return function () {
|
||||
if (newX !== oldX || oldY !== newY) {
|
||||
movePlayer.call(vm, resizeItem, {
|
||||
x: newX,
|
||||
@ -1739,8 +1742,8 @@ export default {
|
||||
return
|
||||
}
|
||||
if (newX !== oldX || oldY !== newY) {
|
||||
debounce((function(newX, oldX, newY, oldY) {
|
||||
return function() {
|
||||
debounce((function (newX, oldX, newY, oldY) {
|
||||
return function () {
|
||||
if (newX !== oldX || oldY !== newY) {
|
||||
movePlayer.call(vm, moveItem, {
|
||||
x: newX,
|
||||
@ -1778,7 +1781,7 @@ export default {
|
||||
// 不使用copy 保持原有对象
|
||||
const finalList = []
|
||||
const _this = this
|
||||
_.forEach(this.componentData, function(item, index) {
|
||||
_.forEach(this.componentData, function (item, index) {
|
||||
if (_.isEmpty(item)) return
|
||||
if (_this.canvasId === item.canvasId) {
|
||||
delete item['_dragId']
|
||||
@ -1820,7 +1823,7 @@ export default {
|
||||
addItemBox(item) {
|
||||
this.yourList.push(item)
|
||||
|
||||
this.$nextTick(function() {
|
||||
this.$nextTick(function () {
|
||||
addItem.call(this, item, this.yourList.length - 1)
|
||||
})
|
||||
},
|
||||
@ -1851,7 +1854,7 @@ export default {
|
||||
// 调整父级组件边界
|
||||
resizeParentBoundsRef() {
|
||||
const _this = this
|
||||
_this.componentData.forEach(function(data, index) {
|
||||
_this.componentData.forEach(function (data, index) {
|
||||
_this.$refs.deDragRef && _this.$refs.deDragRef[index] && _this.$refs.deDragRef[index].checkParentSize()
|
||||
})
|
||||
},
|
||||
|
||||
@ -153,6 +153,7 @@
|
||||
v-if="chart && showMapLayerController"
|
||||
:chart="chart"
|
||||
:series-id-map="seriesIdMap"
|
||||
:show-edit-position="showEditPosition"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
<script>
|
||||
|
||||
import { mapState } from 'vuex'
|
||||
import bus from '@/utils/bus'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@ -29,7 +30,8 @@ export default {
|
||||
computed: {
|
||||
...mapState([
|
||||
'pcComponentData',
|
||||
'pcComponentGap'
|
||||
'pcComponentGap',
|
||||
'mobileLayoutStatus'
|
||||
])
|
||||
},
|
||||
mounted() {
|
||||
@ -49,6 +51,7 @@ export default {
|
||||
this.element.y = 200
|
||||
this.element.auxiliaryMatrix = true
|
||||
this.$store.commit('addComponent', { component: this.element })
|
||||
bus.$emit('mobile-status-change', 'addComponent', { component: this.element })
|
||||
} else {
|
||||
this.deleteComponent()
|
||||
}
|
||||
@ -58,6 +61,9 @@ export default {
|
||||
this.$emit('amRemoveItem')
|
||||
this.$store.commit('deleteComponentWithId', this.element.id)
|
||||
this.$store.commit('setCurComponent', { component: null, index: null })
|
||||
if (this.mobileLayoutStatus) {
|
||||
window.top.postMessage({ type: 'deleteComponentWithId', value: this.element.id }, '*')
|
||||
}
|
||||
},
|
||||
updateMobileSelected(id, mobileSelected) {
|
||||
this.pcComponentData.forEach(item => {
|
||||
|
||||
@ -145,32 +145,31 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getStyle} from '@/components/canvas/utils/style'
|
||||
import {mapState} from 'vuex'
|
||||
import { getStyle } from '@/components/canvas/utils/style'
|
||||
import { mapState } from 'vuex'
|
||||
import ComponentWrapper from './ComponentWrapper'
|
||||
import {changeStyleWithScale} from '@/components/canvas/utils/translate'
|
||||
import {uuid} from 'vue-uuid'
|
||||
import {deepCopy, imgUrlTrans} from '@/components/canvas/utils/utils'
|
||||
import { changeStyleWithScale } from '@/components/canvas/utils/translate'
|
||||
import { uuid } from 'vue-uuid'
|
||||
import { deepCopy, imgUrlTrans } from '@/components/canvas/utils/utils'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
import CanvasOptBar from '@/components/canvas/components/editor/CanvasOptBar'
|
||||
import bus from '@/utils/bus'
|
||||
import {buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch} from '@/utils/conditionUtil'
|
||||
import {hasDataPermission} from '@/utils/permission'
|
||||
import {activeWatermark} from '@/components/canvas/tools/watermark'
|
||||
import {proxyUserLoginInfo, userLoginInfo} from '@/api/systemInfo/userLogin'
|
||||
import { buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch } from '@/utils/conditionUtil'
|
||||
import { hasDataPermission } from '@/utils/permission'
|
||||
import { activeWatermark } from '@/components/canvas/tools/watermark'
|
||||
import { proxyUserLoginInfo, userLoginInfo } from '@/api/systemInfo/userLogin'
|
||||
import html2canvas from 'html2canvasde'
|
||||
import {queryAll} from '@/api/panel/pdfTemplate'
|
||||
import { queryAll } from '@/api/panel/pdfTemplate'
|
||||
import PDFPreExport from '@/views/panel/export/PDFPreExport'
|
||||
import {listenGlobalKeyDownPreview} from '@/components/canvas/utils/shortcutKey'
|
||||
import { listenGlobalKeyDownPreview } from '@/components/canvas/utils/shortcutKey'
|
||||
import UserViewDialog from '@/components/canvas/customComponent/UserViewDialog'
|
||||
import {hexColorToRGBA} from "@/views/chart/chart/util";
|
||||
import {isMobile} from '@/utils/index'
|
||||
|
||||
import { hexColorToRGBA } from '@/views/chart/chart/util'
|
||||
import { isMobile } from '@/utils/index'
|
||||
|
||||
const erd = elementResizeDetectorMaker()
|
||||
export default {
|
||||
components: {UserViewDialog, ComponentWrapper, CanvasOptBar, PDFPreExport},
|
||||
components: { UserViewDialog, ComponentWrapper, CanvasOptBar, PDFPreExport },
|
||||
model: {
|
||||
prop: 'show',
|
||||
event: 'change'
|
||||
@ -207,14 +206,14 @@ export default {
|
||||
componentData: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: function () {
|
||||
default: function() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
canvasStyleData: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: function () {
|
||||
default: function() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
@ -261,7 +260,9 @@ export default {
|
||||
],
|
||||
needToChangeWidth: [
|
||||
'left',
|
||||
'width',
|
||||
'width'
|
||||
],
|
||||
needToChangeInnerWidth: [
|
||||
'fontSize',
|
||||
'activeFontSize',
|
||||
'borderWidth',
|
||||
@ -371,6 +372,7 @@ export default {
|
||||
return this.componentDataShow || []
|
||||
},
|
||||
...mapState([
|
||||
'previewCanvasScale',
|
||||
'isClickComponent'
|
||||
]),
|
||||
|
||||
@ -463,7 +465,7 @@ export default {
|
||||
return this.$refs['viewWrapperChild']
|
||||
},
|
||||
getAllWrapperChildRefs() {
|
||||
let allChildRefs = []
|
||||
const allChildRefs = []
|
||||
const currentChildRefs = this.getWrapperChildRefs()
|
||||
if (currentChildRefs && currentChildRefs.length > 0) {
|
||||
allChildRefs.push.apply(allChildRefs, currentChildRefs)
|
||||
@ -649,7 +651,7 @@ export default {
|
||||
},
|
||||
clearAllLinkage() {
|
||||
this.$store.commit('clearPanelLinkageInfo')
|
||||
bus.$emit('clear_panel_linkage', {viewId: 'all'})
|
||||
bus.$emit('clear_panel_linkage', { viewId: 'all' })
|
||||
},
|
||||
changeStyleWithScale,
|
||||
getStyle,
|
||||
@ -665,8 +667,8 @@ export default {
|
||||
}
|
||||
if (this.isMainCanvas()) {
|
||||
this.$store.commit('setPreviewCanvasScale', {
|
||||
scaleWidth: (this.scaleWidth / 100),
|
||||
scaleHeight: (this.scaleHeight / 100)
|
||||
scaleWidth: this.canvasStyleData.autoSizeAdaptor ? (this.scaleWidth / 100) : 1,
|
||||
scaleHeight: this.canvasStyleData.autoSizeAdaptor ? (this.scaleHeight / 100) : 1
|
||||
})
|
||||
}
|
||||
this.handleScaleChange()
|
||||
@ -682,6 +684,10 @@ export default {
|
||||
format(value, scale) {
|
||||
return value * scale / 100
|
||||
},
|
||||
|
||||
formatPoint(value, pointScale) {
|
||||
return value * pointScale
|
||||
},
|
||||
handleScaleChange() {
|
||||
if (this.componentData) {
|
||||
const componentData = deepCopy(this.componentData)
|
||||
@ -691,10 +697,13 @@ export default {
|
||||
component.style[key] = this.format(component.style[key], this.scaleHeight)
|
||||
}
|
||||
if (this.needToChangeWidth.includes(key)) {
|
||||
component.style[key] = this.format(component.style[key], this.scaleWidth)
|
||||
}
|
||||
if (this.needToChangeInnerWidth.includes(key)) {
|
||||
if ((key === 'fontSize' || key === 'activeFontSize') && (this.terminal === 'mobile' || ['custom', 'v-text'].includes(component.type))) {
|
||||
// do nothing 移动端字符大小无需按照比例缩放,当前保持不变(包括 v-text 和 过滤组件)
|
||||
} else {
|
||||
component.style[key] = this.format(component.style[key], this.scaleWidth)
|
||||
component.style[key] = this.formatPoint(component.style[key], this.previewCanvasScale.scalePointWidth)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -714,7 +723,7 @@ export default {
|
||||
},
|
||||
deselectCurComponent(e) {
|
||||
if (!this.isClickComponent) {
|
||||
this.$store.commit('setCurComponent', {component: null, index: null})
|
||||
this.$store.commit('setCurComponent', { component: null, index: null })
|
||||
if (this.$refs?.['canvas-opt-bar']) {
|
||||
this.$refs['canvas-opt-bar'].setWidgetStatus()
|
||||
}
|
||||
|
||||
@ -1038,7 +1038,7 @@ export default {
|
||||
if (this.publicLinkStatus) {
|
||||
// 判断是否有公共链接ID
|
||||
if (jumpInfo.publicJumpId) {
|
||||
const url = '/link/' + jumpInfo.publicJumpId
|
||||
const url = '/link/' + jumpInfo.publicJumpId + '?fromLink=true'
|
||||
const currentUrl = window.location.href
|
||||
localStorage.setItem('beforeJumpUrl', currentUrl)
|
||||
this.windowsJump(url, jumpInfo.jumpType)
|
||||
|
||||
@ -50,10 +50,32 @@ const unlockMap = {
|
||||
|
||||
let isCtrlOrCommandDown = false
|
||||
|
||||
|
||||
// 检查当前页面是否有弹框
|
||||
const checkDialog = () => {
|
||||
let haveDialog = false
|
||||
document.querySelectorAll('.el-dialog__wrapper').forEach(element => {
|
||||
if (window.getComputedStyle(element).getPropertyValue('display') !== 'none') {
|
||||
haveDialog = true
|
||||
}
|
||||
})
|
||||
document.querySelectorAll('.el-popover').forEach(element => {
|
||||
if (window.getComputedStyle(element).getPropertyValue('display') !== 'none') {
|
||||
haveDialog = true
|
||||
}
|
||||
})
|
||||
// 富文本单框
|
||||
if (document.querySelector('.tox-dialog-wrap')) {
|
||||
haveDialog = true
|
||||
}
|
||||
|
||||
return haveDialog
|
||||
}
|
||||
|
||||
// Monitor key operations globally and execute corresponding commands
|
||||
export function listenGlobalKeyDown() {
|
||||
window.onkeydown = (e) => {
|
||||
if (!store.state.isInEditor) return
|
||||
if (!store.state.isInEditor || checkDialog()) return
|
||||
const { keyCode } = e
|
||||
if (keyCode === ctrlKey || keyCode === commandKey) {
|
||||
isCtrlOrCommandDown = true
|
||||
|
||||
@ -86,6 +86,7 @@ export function panelInit(componentData, componentStyle) {
|
||||
|
||||
export function panelDataPrepare(componentData, componentStyle, callback) {
|
||||
// style初始化
|
||||
componentStyle.autoSizeAdaptor = (componentStyle.autoSizeAdaptor === undefined ? true : componentStyle.autoSizeAdaptor)
|
||||
componentStyle.refreshTime = (componentStyle.refreshTime || 5)
|
||||
componentStyle.refreshViewLoading = (componentStyle.refreshViewLoading || false)
|
||||
componentStyle.refreshUnit = (componentStyle.refreshUnit || 'minute')
|
||||
@ -350,7 +351,7 @@ export function insertTreeNode(nodeInfo, tree) {
|
||||
if (!nodeInfo) {
|
||||
return
|
||||
}
|
||||
if (nodeInfo.pid === 0 || nodeInfo.pid === '0') {
|
||||
if (nodeInfo.pid === 0 || nodeInfo.pid === '0' || nodeInfo.pid === 'panel_list') {
|
||||
tree.push(nodeInfo)
|
||||
return
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
ref="deOutWidget"
|
||||
:canvas-id="canvasId"
|
||||
class="component-custom"
|
||||
:terminal="terminal"
|
||||
:out-style="element.style"
|
||||
:is-relation="isRelation"
|
||||
:element="element"
|
||||
@ -101,6 +102,10 @@ export default {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0
|
||||
},
|
||||
terminal: {
|
||||
type: String,
|
||||
default: 'pc'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
||||
@ -1,34 +1,67 @@
|
||||
<template>
|
||||
<el-date-picker
|
||||
v-if="element.options!== null && element.options.attrs!==null && show"
|
||||
ref="dateRef"
|
||||
v-model="values"
|
||||
:popper-class="'coustom-date-picker' + ' ' + extPoperClass"
|
||||
:type="componentType"
|
||||
:range-separator="$t(element.options.attrs.rangeSeparator)"
|
||||
:start-placeholder="$t(element.options.attrs.startPlaceholder)"
|
||||
:end-placeholder="$t(element.options.attrs.endPlaceholder)"
|
||||
:placeholder="$t(element.options.attrs.placeholder)"
|
||||
:append-to-body="inScreen"
|
||||
value-format="timestamp"
|
||||
:format="labelFormat"
|
||||
:size="size"
|
||||
:editable="false"
|
||||
:picker-options="pickerOptions"
|
||||
:default-time="defaultRangeTime"
|
||||
@change="dateChange"
|
||||
@focus="toFocus"
|
||||
@blur="onBlur"
|
||||
/>
|
||||
<div class="date-picker-vant">
|
||||
<el-date-picker
|
||||
v-if="element.options!== null && element.options.attrs!==null && show"
|
||||
ref="dateRef"
|
||||
v-model="values"
|
||||
:popper-class="'coustom-date-picker' + ' ' + extPoperClass"
|
||||
:type="componentType"
|
||||
:range-separator="$t(element.options.attrs.rangeSeparator)"
|
||||
:start-placeholder="$t(element.options.attrs.startPlaceholder)"
|
||||
:end-placeholder="$t(element.options.attrs.endPlaceholder)"
|
||||
:placeholder="$t(element.options.attrs.placeholder)"
|
||||
:append-to-body="inScreen"
|
||||
value-format="timestamp"
|
||||
:format="labelFormat"
|
||||
:size="size"
|
||||
:editable="false"
|
||||
:picker-options="pickerOptions"
|
||||
:default-time="defaultRangeTime"
|
||||
@change="dateChange"
|
||||
@focus="toFocus"
|
||||
@blur="onBlur"
|
||||
/>
|
||||
<div v-if="isMobileStatus" class="vant-mobile" :class="isRange && 'wl50'" @click="showPopup"/>
|
||||
<div v-if="isMobileStatus && isRange" class="vant-mobile" :class="['datetimerange', 'datetime', 'daterange'].includes(componentType) && 'wr50'" @click="showPopupRight"/>
|
||||
<van-popup get-container="body" v-if="isMobileStatus" v-model="showDate" position="bottom" style="height: auto">
|
||||
<van-datetime-picker
|
||||
v-if="showdDatetimePicker"
|
||||
@confirm="confirm"
|
||||
@cancel="cancel"
|
||||
v-model="currentDate"
|
||||
:type="componentTypeVant"
|
||||
title="选择时间"
|
||||
:min-date="minDate"
|
||||
:max-date="maxDate"
|
||||
/>
|
||||
<van-picker
|
||||
v-else
|
||||
title="选择时间"
|
||||
:default-index="defaultIndex"
|
||||
show-toolbar
|
||||
:columns="columns"
|
||||
@confirm="onConfirm"
|
||||
@cancel="onCancel"
|
||||
/>
|
||||
</van-popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ApplicationContext } from '@/utils/ApplicationContext'
|
||||
import { timeSection } from '@/utils'
|
||||
import bus from '@/utils/bus'
|
||||
import customInput from '@/components/widget/deWidget/customInput'
|
||||
import customInput from '@/components/widget/deWidget/customInput'
|
||||
import { dateMap, years, seconds } from '@/components/widget/deWidget/serviceNameFn'
|
||||
import { mapState } from 'vuex'
|
||||
import vanPopup from 'vant/lib/popup'
|
||||
import vanDatetimePicker from 'vant/lib/datetime-picker'
|
||||
import vanPicker from 'vant/lib/picker'
|
||||
import 'vant/lib/popup/style'
|
||||
import 'vant/lib/datetime-picker/style'
|
||||
import 'vant/lib/picker/style'
|
||||
export default {
|
||||
components: { vanPopup, vanDatetimePicker, vanPicker },
|
||||
mixins: [customInput],
|
||||
props: {
|
||||
canvasId: {
|
||||
@ -52,19 +85,60 @@ export default {
|
||||
isRelation: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
terminal: {
|
||||
type: String,
|
||||
default: 'pc'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showDate: false,
|
||||
minDate: new Date(1980, 0, 1),
|
||||
maxDate: new Date(2025, 10, 1),
|
||||
currentDate: new Date(),
|
||||
operator: 'between',
|
||||
defaultIndex: 2,
|
||||
columns: years,
|
||||
values: null,
|
||||
onFocus: false,
|
||||
show: true,
|
||||
selectSecondInput: false,
|
||||
selectSecond: false,
|
||||
outTimer: null,
|
||||
innerTimer: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isMobileStatus() {
|
||||
return this.mobileStatus || this.terminal === 'mobile'
|
||||
},
|
||||
isRange() {
|
||||
if (!this.isMobileStatus) return false
|
||||
return ['datetimerange', 'daterange'].includes(this.componentType)
|
||||
},
|
||||
showdDatetimePicker() {
|
||||
if (!this.isMobileStatus) return false
|
||||
if (this.showSecond && this.selectSecond) return false
|
||||
return this.componentTypeVant !== 'year'
|
||||
},
|
||||
showSecond() {
|
||||
if (!this.isMobileStatus) return false
|
||||
return this.labelFormat?.endsWith('ss')
|
||||
},
|
||||
componentTypeVant() {
|
||||
if (!this.isMobileStatus) return ''
|
||||
if (this.showSecond) {
|
||||
return 'datetime'
|
||||
}
|
||||
if (this.labelFormat?.endsWith('mm')) {
|
||||
return 'datetime'
|
||||
}
|
||||
if (this.labelFormat?.endsWith('HH')) {
|
||||
return 'datehour'
|
||||
}
|
||||
return dateMap[this.componentType]
|
||||
},
|
||||
extPoperClass() {
|
||||
if (this.labelFormat && this.labelFormat.includes('HH') && !this.labelFormat.includes('HH:mm')) {
|
||||
return 'de-no-minite'
|
||||
@ -130,7 +204,8 @@ export default {
|
||||
return null
|
||||
},
|
||||
...mapState([
|
||||
'canvasStyleData'
|
||||
'canvasStyleData',
|
||||
'mobileStatus'
|
||||
])
|
||||
|
||||
},
|
||||
@ -186,6 +261,86 @@ export default {
|
||||
bus.$off('reset-default-value', this.resetDefaultValue)
|
||||
},
|
||||
methods: {
|
||||
showPopupRight() {
|
||||
const [_, end] = this.values || []
|
||||
!!end && (this.currentDate = new Date(end))
|
||||
this.selectSecondInput = true
|
||||
this.showDate = true
|
||||
},
|
||||
cancel() {
|
||||
this.showDate = false
|
||||
},
|
||||
confirm() {
|
||||
this.setArrValue()
|
||||
if (this.showSecond) {
|
||||
this.columns = seconds
|
||||
this.selectSecond = true
|
||||
}
|
||||
if (this.selectSecond || this.componentTypeVant === 'year') {
|
||||
return
|
||||
}
|
||||
this.showDate = false
|
||||
this.mobileDateChange()
|
||||
},
|
||||
onCancel() {
|
||||
this.showDate = false
|
||||
if (this.showSecond) {
|
||||
this.selectSecond = false
|
||||
}
|
||||
},
|
||||
setArrValue(val) {
|
||||
if (!this.isRange) {
|
||||
if (this.selectSecond) {
|
||||
this.values = this.values + val * 1000
|
||||
return
|
||||
}
|
||||
this.values = val ? +new Date(val) : +new Date(this.currentDate)
|
||||
return
|
||||
}
|
||||
const [start, end] = this.values || []
|
||||
if (this.selectSecond) {
|
||||
if (this.selectSecondInput) {
|
||||
this.values = [start, +new Date(this.currentDate) + val * 1000]
|
||||
} else {
|
||||
this.values = [+new Date(this.currentDate) + val * 1000, end]
|
||||
}
|
||||
return
|
||||
}
|
||||
if (this.selectSecondInput) {
|
||||
this.values = [start, +new Date(this.currentDate)]
|
||||
} else {
|
||||
this.values = [+new Date(this.currentDate), end]
|
||||
}
|
||||
},
|
||||
onConfirm(val) {
|
||||
this.showDate = false
|
||||
this.setArrValue(val)
|
||||
if (this.showSecond) {
|
||||
this.columns = years
|
||||
this.selectSecond = false
|
||||
}
|
||||
this.mobileDateChange()
|
||||
},
|
||||
mobileDateChange() {
|
||||
if (this.isRange) {
|
||||
const [start, end] = this.values || []
|
||||
if (!start || !end) return
|
||||
}
|
||||
this.dateChange(this.values)
|
||||
},
|
||||
showPopup() {
|
||||
if (this.isRange) {
|
||||
const [start] = this.values || []
|
||||
!!start && (this.currentDate = new Date(start))
|
||||
} else {
|
||||
this.currentDate = new Date(this.values)
|
||||
if (this.componentTypeVant === 'year') {
|
||||
this.defaultIndex = years.findIndex(ele => `${this.currentDate.getFullYear()}` === ele)
|
||||
}
|
||||
}
|
||||
this.selectSecondInput = false
|
||||
this.showDate = true
|
||||
},
|
||||
loadInit() {
|
||||
this.clearTime()
|
||||
if (this.refreshHandler()) {
|
||||
@ -340,6 +495,28 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.date-picker-vant {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
.el-date-editor {
|
||||
width: 100% !important;
|
||||
}
|
||||
.vant-mobile {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
&.wl50 {
|
||||
width: 50%;
|
||||
}
|
||||
&.wr50 {
|
||||
left: auto;
|
||||
right: 0;
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.coustom-date-picker {
|
||||
right: 0px;
|
||||
border: 1px solid var(--BrDateColor, #dfe4ed) !important;
|
||||
|
||||
@ -79,6 +79,18 @@ function handlerInputStyle(node, style) {
|
||||
})
|
||||
}
|
||||
|
||||
const dateMap = {
|
||||
year: 'year',
|
||||
month: 'year-month',
|
||||
date: 'date',
|
||||
datetime: 'datetime',
|
||||
datetimerange: 'datetime',
|
||||
daterange: 'date'
|
||||
}
|
||||
|
||||
const years = Array(60).fill(1).map((_, index) => `${index + 1980}`)
|
||||
const seconds = Array(60).fill(1).map((_, index) => index)
|
||||
|
||||
export {
|
||||
attrsMap,
|
||||
styleAttrs,
|
||||
@ -87,5 +99,8 @@ export {
|
||||
textSelectGridWidget,
|
||||
textSelectTreeWidget,
|
||||
textSelectWidget,
|
||||
handlerInputStyle
|
||||
handlerInputStyle,
|
||||
dateMap,
|
||||
years,
|
||||
seconds
|
||||
}
|
||||
|
||||
1
core/frontend/src/icons/svg/icon_auto-adaptor.svg
Normal file
1
core/frontend/src/icons/svg/icon_auto-adaptor.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="1698901715032" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4099" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M960.605 932.345v-240.231c0.045-7.2-2.723-14.445-8.213-19.98-11.115-11.047-29.002-11.047-40.071 0-5.535 5.535-8.303 12.757-8.303 19.98v171.923l-351.99-352.035 351.99-352.013v171.855c0 7.245 2.767 14.49 8.303 20.002 11.070 11.070 28.957 11.070 40.071 0 5.49-5.511 8.257-12.78 8.213-20.002v-240.187c0.045-7.223-2.723-14.468-8.213-20.003-5.58-5.511-12.803-8.279-20.025-8.302h-240.233c-7.222 0-14.467 2.79-19.98 8.302-11.115 11.049-11.115 28.957 0 40.050 5.511 5.535 12.735 8.302 19.98 8.279h171.9l-352.013 352.013-352.012-352.035h171.855c7.268 0.022 14.49-2.745 20.025-8.279 11.070-11.047 11.070-29.002 0-40.050-5.49-5.511-12.758-8.279-20.025-8.303h-240.187c-7.268 0-14.513 2.79-20.025 8.303-5.513 5.558-8.279 12.803-8.279 20.048v240.165c0 7.245 2.79 14.512 8.279 20.002 11.070 11.070 28.98 11.070 40.028 0 5.513-5.511 8.279-12.713 8.279-20.002v-171.855l352.058 352.012-352.035 352.035v-171.922c0-7.2-2.745-14.445-8.279-19.98-11.070-11.047-29.002-11.047-40.028 0-5.558 5.535-8.279 12.757-8.279 19.98v240.231c0 7.223 2.79 14.468 8.279 20.048 5.535 5.468 12.757 8.279 20.025 8.279h240.188c7.268 0 14.49-2.745 20.025-8.279 11.070-11.047 11.070-29.002 0-40.050-5.535-5.535-12.78-8.257-20.025-8.257h-171.877l352.012-352.035 352.013 352.035h-171.9c-7.222 0-14.467 2.768-19.98 8.257-11.115 11.049-11.115 29.002 0 40.050 5.511 5.468 12.735 8.279 19.98 8.279h240.255c7.2 0 14.445-2.813 20.025-8.279 5.467-5.602 8.19-12.825 8.19-20.048z" p-id="4100" fill="#646A73"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@ -2064,7 +2064,7 @@ export default {
|
||||
panel_cache_use_tips: 'It was checked that the last dashboard could not be saved normally. Do you want to use the panel that was not saved last time?',
|
||||
template_name_tips: 'Panel\'s name should not be null',
|
||||
panel_background_item: 'Customize panel background',
|
||||
panel_background_image_tips: 'Currently.Jpeg,.Jpg,.Png,.Gif files are supported, and the size should not exceed 15m',
|
||||
panel_background_image_tips: 'Currently Jpeg,Jpg,Png,Gif,Svg files are supported, and the size should not exceed 15m',
|
||||
reUpload: 'reUpload',
|
||||
create_by: 'Create By',
|
||||
create_time: 'Create Time',
|
||||
@ -2313,6 +2313,7 @@ export default {
|
||||
suspension: 'suspension',
|
||||
new_element_distribution: 'Element Distribution',
|
||||
aided_grid: 'Aided Grid',
|
||||
auto_size_adaptor: 'Component Adaptor',
|
||||
aided_grid_open: 'Open',
|
||||
aided_grid_close: 'Close',
|
||||
export_pdf_page: 'Pagination Line',
|
||||
|
||||
@ -2058,7 +2058,7 @@ export default {
|
||||
panel_cache_use_tips: '檢查到上次有儀表板未能正常保存,是否使用上次未保存的儀表板?',
|
||||
template_name_tips: '儀表板名稱必填',
|
||||
panel_background_item: '自定義儀表板背景',
|
||||
panel_background_image_tips: '當前支持.jpeg,.jpg,.png,.gif文件,大小不要超過15M',
|
||||
panel_background_image_tips: '當前支持jpeg,jpg,png,gif,svg文件,大小15M内',
|
||||
reUpload: '重新上傳',
|
||||
create_by: '創建人',
|
||||
create_time: '創建時間',
|
||||
@ -2307,6 +2307,7 @@ export default {
|
||||
suspension: '懸浮',
|
||||
new_element_distribution: '元素移入分佈方式',
|
||||
aided_grid: '輔助設計網格',
|
||||
auto_size_adaptor: '組件自適應',
|
||||
aided_grid_open: '打開',
|
||||
aided_grid_close: '關閉',
|
||||
export_pdf_page: '分頁線',
|
||||
|
||||
@ -2058,7 +2058,7 @@ export default {
|
||||
panel_cache_use_tips: '检查到上次有仪表板未能正常保存,是否使用上次未保存的仪表板?',
|
||||
template_name_tips: '仪表板名称必填',
|
||||
panel_background_item: '自定义仪表板背景',
|
||||
panel_background_image_tips: '当前支持.jpeg,.jpg,.png,.gif文件,大小不要超过15M',
|
||||
panel_background_image_tips: '当前支持jpeg,jpg,png,gif,svg文件,大小15M内',
|
||||
reUpload: '重新上传',
|
||||
create_by: '创建人',
|
||||
create_time: '创建时间',
|
||||
@ -2307,6 +2307,7 @@ export default {
|
||||
suspension: '悬浮',
|
||||
new_element_distribution: '元素移入分布方式',
|
||||
aided_grid: '辅助设计网格',
|
||||
auto_size_adaptor: '组件自适应',
|
||||
aided_grid_open: '打开',
|
||||
aided_grid_close: '关闭',
|
||||
export_pdf_page: '分页线',
|
||||
|
||||
9
core/frontend/src/mobile/App.vue
Normal file
9
core/frontend/src/mobile/App.vue
Normal file
@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AppMobile'
|
||||
}
|
||||
</script>
|
||||
155
core/frontend/src/mobile/main.js
Normal file
155
core/frontend/src/mobile/main.js
Normal file
@ -0,0 +1,155 @@
|
||||
import Vue from 'vue'
|
||||
import Cookies from 'js-cookie'
|
||||
import '@/styles/index.scss' // global css
|
||||
import ElementUI from 'element-ui'
|
||||
import Vuetify from 'vuetify'
|
||||
import Fit2CloudUI from 'fit2cloud-ui'
|
||||
|
||||
import i18n from '../lang' // internationalization
|
||||
import App from './App'
|
||||
import store from '../store'
|
||||
import router from '../router/mobile.js'
|
||||
import message from '../utils/message'
|
||||
import '@/icons' // icon
|
||||
import '@/permission' // permission control
|
||||
import api from '@/api/index.js'
|
||||
import filter from '@/filter/filter'
|
||||
import directives from '../directive'
|
||||
import VueClipboard from 'vue-clipboard2'
|
||||
import widgets from '@/components/widget'
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||
import '../utils/dialog'
|
||||
import DeComplexInput from '@/components/business/conditionTable/DeComplexInput'
|
||||
import DeComplexSelect from '@/components/business/conditionTable/DeComplexSelect'
|
||||
import DeViewSelect from '@/components/deViewSelect'
|
||||
import RemarkEditor from '@/views/chart/components/componentStyle/dialog/RemarkEditor'
|
||||
import TitleRemark from '@/views/chart/view/TitleRemark'
|
||||
import '@/components/canvas/customComponent' // 注册自定义组件
|
||||
import deBtn from '@/components/deCustomCm/DeBtn.vue'
|
||||
|
||||
import '@/utils/DateUtil'
|
||||
import draggable from 'vuedraggable'
|
||||
import deWebsocket from '@/websocket'
|
||||
import { GaodeMap } from '@antv/l7-maps'
|
||||
import * as echarts from 'echarts'
|
||||
import UmyUi from 'umy-ui'
|
||||
// 全屏插件
|
||||
import fullscreen from 'vue-fullscreen'
|
||||
import VueFriendlyIframe from 'vue-friendly-iframe'
|
||||
import vueToPdf from 'vue-to-pdf'
|
||||
import VueVideoPlayer from 'vue-video-player'
|
||||
import 'video.js/dist/video-js.css'
|
||||
import '@antv/s2/dist/style.min.css'
|
||||
// 控制标签宽高成比例的指令
|
||||
import proportion from 'vue-proportion-directive'
|
||||
|
||||
import xss from 'xss'
|
||||
// 定义全局XSS解决方法
|
||||
Object.defineProperty(Vue.prototype, '$xss', {
|
||||
value: xss
|
||||
})
|
||||
|
||||
Vue.config.productionTip = false
|
||||
Vue.use(VueClipboard)
|
||||
Vue.use(widgets)
|
||||
Vue.component('Draggable', draggable)
|
||||
Vue.prototype.$api = api
|
||||
|
||||
Vue.prototype.$echarts = echarts
|
||||
Vue.prototype.$gaodeMap = GaodeMap
|
||||
|
||||
Vue.use(UmyUi)
|
||||
|
||||
Vue.use(fullscreen)
|
||||
|
||||
Vue.use(VueFriendlyIframe)
|
||||
Vue.use(Vuetify)
|
||||
// import TEditor from '@/components/Tinymce/index.vue'
|
||||
// Vue.component('TEditor', TEditor)
|
||||
|
||||
/**
|
||||
* If you don't want to use mock-server
|
||||
* you want to use MockJs for mock api
|
||||
* you can execute: mockXHR()
|
||||
*
|
||||
* Currently MockJs will be used in the production environment,
|
||||
* please remove it before going online ! ! !
|
||||
*/
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// const { mockXHR } = require('.../mock')
|
||||
// mockXHR()
|
||||
}
|
||||
|
||||
// set ElementUI lang to EN
|
||||
// Vue.use(ElementUI, { locale })
|
||||
// 如果想要中文版 element-ui,按如下方式声明
|
||||
ElementUI.Dialog.props.closeOnClickModal.default = false
|
||||
ElementUI.Dialog.props.closeOnPressEscape.default = false
|
||||
Vue.use(ElementUI, {
|
||||
size: Cookies.get('size') || 'medium', // set element-ui default size
|
||||
i18n: (key, value) => i18n.t(key, value)
|
||||
})
|
||||
Vue.use(Fit2CloudUI, {
|
||||
i18n: (key, value) => i18n.t(key, value)
|
||||
})
|
||||
// Vue.use(VueAxios, axios)
|
||||
Vue.use(filter)
|
||||
Vue.use(directives)
|
||||
Vue.use(message)
|
||||
Vue.component('Treeselect', Treeselect)
|
||||
Vue.component('DeComplexInput', DeComplexInput)
|
||||
Vue.component('DeComplexSelect', DeComplexSelect)
|
||||
Vue.component('DeViewSelect', DeViewSelect)
|
||||
Vue.component('RemarkEditor', RemarkEditor)
|
||||
Vue.component('TitleRemark', TitleRemark)
|
||||
Vue.component('DeBtn', deBtn)
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.use(vueToPdf)
|
||||
|
||||
Vue.use(VueVideoPlayer)
|
||||
|
||||
Vue.use(proportion)
|
||||
|
||||
Vue.prototype.hasDataPermission = function(pTarget, pSource) {
|
||||
if (this.$store.state.user.user.isAdmin || pSource === 'ignore') {
|
||||
return true
|
||||
}
|
||||
if (pSource && pTarget) {
|
||||
return pSource.indexOf(pTarget) > -1
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Vue.prototype.checkPermission = function(pers) {
|
||||
const permissions = store.getters.permissions
|
||||
const hasPermission = pers.every(needP => {
|
||||
const result = permissions.includes(needP)
|
||||
return result
|
||||
})
|
||||
return hasPermission
|
||||
}
|
||||
Vue.use(deWebsocket)
|
||||
|
||||
Vue.prototype.$currentHttpRequestList = new Map()
|
||||
Vue.prototype.$cancelRequest = function(cancelkey) {
|
||||
if (cancelkey) {
|
||||
if (cancelkey.indexOf('/**') > -1) {
|
||||
Vue.prototype.$currentHttpRequestList.forEach((item, key) => {
|
||||
key.indexOf(cancelkey.split('/**')[0]) > -1 && item('Operation canceled by the user.')
|
||||
})
|
||||
} else {
|
||||
Vue.prototype.$currentHttpRequestList.get(cancelkey) && Vue.prototype.$currentHttpRequestList.get(cancelkey)('Operation canceled by the user.')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new Vue({
|
||||
|
||||
router,
|
||||
store,
|
||||
i18n,
|
||||
render: h => h(App)
|
||||
}).$mount('#app-mobile')
|
||||
19
core/frontend/src/router/mobile.js
Normal file
19
core/frontend/src/router/mobile.js
Normal file
@ -0,0 +1,19 @@
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
|
||||
Vue.use(Router)
|
||||
export const constantRoutes = [
|
||||
{
|
||||
path: '/',
|
||||
component: () => import('@/views/mobile/index.vue'),
|
||||
}
|
||||
]
|
||||
|
||||
const createRouter = () => new Router({
|
||||
mode: 'hash',
|
||||
scrollBehavior: () => ({ y: 0 }),
|
||||
routes: constantRoutes
|
||||
})
|
||||
|
||||
const router = createRouter()
|
||||
export default router
|
||||
@ -92,6 +92,8 @@ const data = {
|
||||
componentGap: 5,
|
||||
// 移动端布局状态
|
||||
mobileLayoutStatus: false,
|
||||
// 是否是mobile
|
||||
mobileStatus: false,
|
||||
// 公共链接状态(当前是否是公共链接打开)
|
||||
publicLinkStatus: false,
|
||||
pcTabMatrixCount: {
|
||||
@ -574,6 +576,9 @@ const data = {
|
||||
setMobileLayoutStatus(state, status) {
|
||||
state.mobileLayoutStatus = status
|
||||
},
|
||||
setMobileStatus(state, status) {
|
||||
state.mobileStatus = status
|
||||
},
|
||||
setPublicLinkStatus(state, status) {
|
||||
state.publicLinkStatus = status
|
||||
},
|
||||
|
||||
@ -54,6 +54,18 @@
|
||||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">adaptor</div>
|
||||
<div class="code-name">&#xe63e;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">颜色</div>
|
||||
<div class="code-name">&#xe886;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">command</div>
|
||||
@ -810,9 +822,9 @@
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.woff2?t=1669699377636') format('woff2'),
|
||||
url('iconfont.woff?t=1669699377636') format('woff'),
|
||||
url('iconfont.ttf?t=1669699377636') format('truetype');
|
||||
src: url('iconfont.woff2?t=1698903637839') format('woff2'),
|
||||
url('iconfont.woff?t=1698903637839') format('woff'),
|
||||
url('iconfont.ttf?t=1698903637839') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
@ -838,6 +850,24 @@
|
||||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-adaptor"></span>
|
||||
<div class="name">
|
||||
adaptor
|
||||
</div>
|
||||
<div class="code-name">.icon-adaptor
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-yanse"></span>
|
||||
<div class="name">
|
||||
颜色
|
||||
</div>
|
||||
<div class="code-name">.icon-yanse
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-command"></span>
|
||||
<div class="name">
|
||||
@ -1972,6 +2002,22 @@
|
||||
<div class="content symbol">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-adaptor"></use>
|
||||
</svg>
|
||||
<div class="name">adaptor</div>
|
||||
<div class="code-name">#icon-adaptor</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-yanse"></use>
|
||||
</svg>
|
||||
<div class="name">颜色</div>
|
||||
<div class="code-name">#icon-yanse</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-command"></use>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2459092 */
|
||||
src: url('iconfont.woff2?t=1669699377636') format('woff2'),
|
||||
url('iconfont.woff?t=1669699377636') format('woff'),
|
||||
url('iconfont.ttf?t=1669699377636') format('truetype');
|
||||
src: url('iconfont.woff2?t=1698903637839') format('woff2'),
|
||||
url('iconfont.woff?t=1698903637839') format('woff'),
|
||||
url('iconfont.ttf?t=1698903637839') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,14 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-adaptor:before {
|
||||
content: "\e63e";
|
||||
}
|
||||
|
||||
.icon-yanse:before {
|
||||
content: "\e886";
|
||||
}
|
||||
|
||||
.icon-command:before {
|
||||
content: "\e644";
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -5,6 +5,20 @@
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "34289857",
|
||||
"name": "adaptor",
|
||||
"font_class": "adaptor",
|
||||
"unicode": "e63e",
|
||||
"unicode_decimal": 58942
|
||||
},
|
||||
{
|
||||
"icon_id": "9626971",
|
||||
"name": "颜色",
|
||||
"font_class": "yanse",
|
||||
"unicode": "e886",
|
||||
"unicode_decimal": 59526
|
||||
},
|
||||
{
|
||||
"icon_id": "1567487",
|
||||
"name": "command",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -110,7 +110,7 @@
|
||||
<el-col style="width: 130px!important;">
|
||||
<el-upload
|
||||
action=""
|
||||
accept=".jpeg,.jpg,.png,.gif"
|
||||
accept=".jpeg,.jpg,.png,.gif,.svg"
|
||||
class="avatar-uploader"
|
||||
list-type="picture-card"
|
||||
:class="{disabled:uploadDisabled}"
|
||||
|
||||
@ -158,8 +158,13 @@ export function getLabel(chart) {
|
||||
// label value formatter
|
||||
if (chart.type && chart.type !== 'waterfall') {
|
||||
label.formatter = function(param) {
|
||||
let yAxis, extStack, xaxisExt
|
||||
let xAxis, yAxis, extStack, xaxisExt
|
||||
let res = param.value
|
||||
try {
|
||||
xAxis = JSON.parse(chart.xaxis)
|
||||
} catch (e) {
|
||||
xAxis = JSON.parse(JSON.stringify(chart.xaxis))
|
||||
}
|
||||
try {
|
||||
yAxis = JSON.parse(chart.yaxis)
|
||||
} catch (e) {
|
||||
@ -244,38 +249,46 @@ export function getLabel(chart) {
|
||||
} else {
|
||||
for (let i = 0; i < yAxis.length; i++) {
|
||||
const f = yAxis[i]
|
||||
if (f.name === param.category) {
|
||||
let formatterCfg = formatterItem
|
||||
if (f.formatterCfg) {
|
||||
formatterCfg = f.formatterCfg
|
||||
}
|
||||
// 饼图和环形图格式优化
|
||||
if (equalsAny(chart.type, 'pie', 'pie-donut')) {
|
||||
// 这边默认值取指标是为了兼容存量的视图
|
||||
const labelContent = l.labelContent ?? ['quota']
|
||||
const contentItems = []
|
||||
if (labelContent.includes('dimension')) {
|
||||
contentItems.push(param.field)
|
||||
}
|
||||
if (labelContent.includes('quota')) {
|
||||
contentItems.push(valueFormatter(param.value, formatterCfg))
|
||||
}
|
||||
if (labelContent.includes('proportion')) {
|
||||
const percentage = `${(Math.round(param.percent * 10000) / 100).toFixed(l.reserveDecimalCount)}%`
|
||||
if (labelContent.length === 3) {
|
||||
contentItems.push(`(${percentage})`)
|
||||
} else {
|
||||
contentItems.push(percentage)
|
||||
}
|
||||
}
|
||||
res = contentItems.join(' ')
|
||||
} else if (equalsAny(chart.type, 'pie-rose', 'pie-donut-rose')) {
|
||||
const quotaValue = valueFormatter(param.value, formatterCfg)
|
||||
res = [param.field, quotaValue].join(' ')
|
||||
} else {
|
||||
let formatterCfg = formatterItem
|
||||
if (f.formatterCfg) {
|
||||
formatterCfg = f.formatterCfg
|
||||
}
|
||||
|
||||
if (chart.type === 'scatter' && xAxis && xAxis.length > 0 && xAxis[0].groupType === 'q') {
|
||||
// 针对横轴为指标的散点图
|
||||
if (f.name === param.group) {
|
||||
res = valueFormatter(param.value, formatterCfg)
|
||||
}
|
||||
break
|
||||
} else {
|
||||
if (f.name === param.category) {
|
||||
// 饼图和环形图格式优化
|
||||
if (equalsAny(chart.type, 'pie', 'pie-donut')) {
|
||||
// 这边默认值取指标是为了兼容存量的视图
|
||||
const labelContent = l.labelContent ?? ['quota']
|
||||
const contentItems = []
|
||||
if (labelContent.includes('dimension')) {
|
||||
contentItems.push(param.field)
|
||||
}
|
||||
if (labelContent.includes('quota')) {
|
||||
contentItems.push(valueFormatter(param.value, formatterCfg))
|
||||
}
|
||||
if (labelContent.includes('proportion')) {
|
||||
const percentage = `${(Math.round(param.percent * 10000) / 100).toFixed(l.reserveDecimalCount)}%`
|
||||
if (labelContent.length === 3) {
|
||||
contentItems.push(`(${percentage})`)
|
||||
} else {
|
||||
contentItems.push(percentage)
|
||||
}
|
||||
}
|
||||
res = contentItems.join(' ')
|
||||
} else if (equalsAny(chart.type, 'pie-rose', 'pie-donut-rose')) {
|
||||
const quotaValue = valueFormatter(param.value, formatterCfg)
|
||||
res = [param.field, quotaValue].join(' ')
|
||||
} else {
|
||||
res = valueFormatter(param.value, formatterCfg)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
width="150"
|
||||
:append-to-body="false"
|
||||
trigger="click"
|
||||
:popper-class="showEditPosition === 'bar-main-preview' ? 'map-layer-poper' : ''"
|
||||
>
|
||||
<i
|
||||
slot="reference"
|
||||
@ -51,6 +52,10 @@ export default {
|
||||
id: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
showEditPosition: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -98,9 +103,15 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.map-layer-poper {
|
||||
top: 3px !important;
|
||||
right: 80px !important;
|
||||
left: auto !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.de-ul li {
|
||||
margin: 5px 2px;
|
||||
cursor: pointer;
|
||||
|
||||
@ -286,8 +286,11 @@
|
||||
min-width="200px"
|
||||
:prop="field.fieldName"
|
||||
:label="field.remarks"
|
||||
resizable
|
||||
/>
|
||||
resizable>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ at(scope.row, field.fieldName)[0] }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-table
|
||||
@ -303,7 +306,11 @@
|
||||
:prop="field.fieldName"
|
||||
:label="field.remarks"
|
||||
resizable
|
||||
/>
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ at(scope.row, field.fieldName)[0] }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div
|
||||
@ -623,6 +630,7 @@ import { pySort } from './util'
|
||||
import _ from 'lodash'
|
||||
import GridTable from '@/components/gridTable/index.vue'
|
||||
import { updateCacheTree } from '@/components/canvas/utils/utils'
|
||||
import { at } from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'AddSQL',
|
||||
@ -742,7 +750,8 @@ export default {
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
at
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
@ -77,7 +77,7 @@ export default {
|
||||
})
|
||||
},
|
||||
setPanelInfo() {
|
||||
loadResource(this.resourceId,this.user).then(res => {
|
||||
loadResource(this.resourceId, this.user).then(res => {
|
||||
this.show = false
|
||||
let loadingCount = 0
|
||||
const watermarkInfo = {
|
||||
|
||||
142
core/frontend/src/views/mobile/index.vue
Normal file
142
core/frontend/src/views/mobile/index.vue
Normal file
@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<el-row
|
||||
id="canvasInfoMobile"
|
||||
class="this_mobile_canvas_main"
|
||||
:style="mobileCanvasStyle"
|
||||
>
|
||||
<canvas-opt-bar/>
|
||||
<de-canvas
|
||||
ref="canvasMainRef"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:component-data="mainCanvasComponentData"
|
||||
:canvas-id="canvasId"
|
||||
:canvas-pid="'0'"
|
||||
:mobile-layout-status="true"
|
||||
/>
|
||||
</el-row>
|
||||
</template>
|
||||
<script>
|
||||
import DeCanvas from '@/components/canvas/DeCanvas'
|
||||
import CanvasOptBar from '@/components/canvas/components/editor/CanvasOptBar'
|
||||
import {
|
||||
imgUrlTrans,
|
||||
getNowCanvasComponentData,
|
||||
} from "@/components/canvas/utils/utils";
|
||||
import { mapState } from "vuex";
|
||||
import { hexColorToRGBA } from "@/views/chart/chart/util";
|
||||
export default {
|
||||
components: { DeCanvas, CanvasOptBar },
|
||||
data() {
|
||||
return {
|
||||
canvasId: "canvas-main",
|
||||
previewVisible: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["canvasStyleData", "mobileLayoutStatus", 'componentData']),
|
||||
mainCanvasComponentData() {
|
||||
return getNowCanvasComponentData(this.canvasId);
|
||||
},
|
||||
mobileCanvasStyle() {
|
||||
let style;
|
||||
if (this.canvasStyleData.openCommonStyle) {
|
||||
const styleInfo =
|
||||
this.canvasStyleData.panel.mobileSetting &&
|
||||
this.canvasStyleData.panel.mobileSetting.customSetting
|
||||
? this.canvasStyleData.panel.mobileSetting
|
||||
: this.canvasStyleData.panel;
|
||||
if (
|
||||
styleInfo.backgroundType === "image" &&
|
||||
typeof styleInfo.imageUrl === "string"
|
||||
) {
|
||||
style = {
|
||||
background: `url(${imgUrlTrans(styleInfo.imageUrl)}) no-repeat`,
|
||||
};
|
||||
} else if (styleInfo.backgroundType === "color") {
|
||||
const colorRGBA = hexColorToRGBA(
|
||||
styleInfo.color,
|
||||
styleInfo.alpha === undefined ? 100 : styleInfo.alpha,
|
||||
);
|
||||
style = {
|
||||
background: colorRGBA,
|
||||
};
|
||||
} else {
|
||||
style = {
|
||||
background: "#f7f8fa",
|
||||
};
|
||||
}
|
||||
}
|
||||
return style;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$store.commit('setMobileLayoutStatus', true)
|
||||
this.$store.commit('setMobileStatus', true)
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data.type === 'addComponent') {
|
||||
this.$store.commit('addComponent', event.data.value)
|
||||
}
|
||||
if (event.data.type === 'setCanvasStyle') {
|
||||
this.$store.commit('setCanvasStyle', event.data.value)
|
||||
}
|
||||
if (event.data.type === 'editSave') {
|
||||
window.top.postMessage({ type: 'setComponentData', value: this.componentData }, '*')
|
||||
}
|
||||
if (event.data.type === 'reset') {
|
||||
this.$store.commit('setComponentData', event.data.value)
|
||||
this.$store.commit('openMobileLayout')
|
||||
}
|
||||
|
||||
if (event.data.type === 'openMobileLayout') {
|
||||
this.$store.commit('setComponentData', event.data.value)
|
||||
this.$store.commit('openMobileLayout')
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
cancel() {
|
||||
this.show = false
|
||||
},
|
||||
confirm() {
|
||||
this.show = false
|
||||
},
|
||||
showPopup() {
|
||||
this.show = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.this_mobile_canvas_main {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
height: 100vh;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
.mobile-container {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
color: #323233;
|
||||
font-size: 16px;
|
||||
font-family:
|
||||
"Open Sans",
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Helvetica Neue",
|
||||
Helvetica,
|
||||
Segoe UI,
|
||||
Arial,
|
||||
Roboto,
|
||||
"PingFang SC",
|
||||
"miui",
|
||||
"Hiragino Sans GB",
|
||||
"Microsoft Yahei",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
height: 570px;
|
||||
box-sizing: border-box;
|
||||
width: 360px;
|
||||
min-width: 360px;
|
||||
overflow: hidden;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
@ -47,7 +47,7 @@ import { mapState } from 'vuex'
|
||||
import ComponentWaitItem from '@/views/panel/edit/ComponentWaitItem'
|
||||
import MobileBackgroundSelector from '@/views/panel/subjectSetting/panelStyle/MobileBackgroundSelector'
|
||||
import { imgUrlTrans } from '@/components/canvas/utils/utils'
|
||||
import {hexColorToRGBA} from "@/views/chart/chart/util";
|
||||
import { hexColorToRGBA } from '@/views/chart/chart/util'
|
||||
|
||||
export default {
|
||||
name: 'ComponentWait',
|
||||
|
||||
@ -188,7 +188,7 @@
|
||||
class="mobile_canvas_main"
|
||||
>
|
||||
<el-col
|
||||
:span="8"
|
||||
:span="10"
|
||||
class="this_mobile_canvas_cell"
|
||||
>
|
||||
<div
|
||||
@ -200,23 +200,8 @@
|
||||
<el-row class="this_mobile_canvas_inner_top">
|
||||
{{ panelInfo.name }}
|
||||
</el-row>
|
||||
<el-row class="this_mobile_canvas_main_outer">
|
||||
<el-row
|
||||
id="canvasInfoMobile"
|
||||
class="this_mobile_canvas_main"
|
||||
:style="mobileCanvasStyle"
|
||||
>
|
||||
<canvas-opt-bar v-if="!previewVisible&&mobileLayoutStatus"/>
|
||||
<de-canvas
|
||||
v-if="!previewVisible&&mobileLayoutStatus"
|
||||
ref="canvasMainRef"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:component-data="mainCanvasComponentData"
|
||||
:canvas-id="canvasId"
|
||||
:canvas-pid="'0'"
|
||||
:mobile-layout-status="true"
|
||||
/>
|
||||
</el-row>
|
||||
<el-row v-loading="mobileLoading" class="this_mobile_canvas_main_outer">
|
||||
<iframe src="./mobile.html" @load="handleLoad" frameborder="0" width="360" height="570"></iframe>
|
||||
</el-row>
|
||||
<el-row class="this_mobile_canvas_inner_bottom">
|
||||
<el-col :span="12">
|
||||
@ -249,7 +234,7 @@
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="16"
|
||||
:span="14"
|
||||
class="this_mobile_canvas_cell this_mobile_canvas_wait_cell"
|
||||
>
|
||||
<component-wait/>
|
||||
@ -593,6 +578,7 @@ export default {
|
||||
autoMoveOffSet: 15,
|
||||
mobileEditorShow: true,
|
||||
hasStar: false,
|
||||
mobileLoading: true,
|
||||
drawerSize: '300px',
|
||||
visible: false,
|
||||
show: false,
|
||||
@ -652,7 +638,7 @@ export default {
|
||||
{ label: '适应新主题', value: true },
|
||||
{ label: '保持源样式', value: false }
|
||||
],
|
||||
multiplexingStyleAdaptSelf : true
|
||||
multiplexingStyleAdaptSelf: true
|
||||
}
|
||||
},
|
||||
|
||||
@ -776,7 +762,7 @@ export default {
|
||||
curCanvasScaleSelf() {
|
||||
return this.curCanvasScaleMap[this.canvasId]
|
||||
},
|
||||
selectComponentCount(){
|
||||
selectComponentCount() {
|
||||
return Object.keys(this.curMultiplexingComponents).length
|
||||
},
|
||||
...mapState([
|
||||
@ -786,6 +772,7 @@ export default {
|
||||
'canvasStyleData',
|
||||
'curComponentIndex',
|
||||
'componentData',
|
||||
'pcComponentData',
|
||||
'linkageSettingStatus',
|
||||
'dragComponentInfo',
|
||||
'componentGap',
|
||||
@ -817,7 +804,8 @@ export default {
|
||||
this.recordStyleChange(this.$store.state.styleChangeTimes)
|
||||
}
|
||||
},
|
||||
mobileLayoutStatus() {
|
||||
mobileLayoutStatus(val) {
|
||||
this.mobileLoading = val
|
||||
this.restore()
|
||||
},
|
||||
previewVisible(val) {
|
||||
@ -849,6 +837,21 @@ export default {
|
||||
listenGlobalKeyDown()
|
||||
},
|
||||
mounted() {
|
||||
bus.$on('mobile-status-change', this.mobileStatusChange)
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data.type === 'deleteComponentWithId') {
|
||||
console.log('event1', event.data)
|
||||
this.$store.commit('deleteComponentWithId', event.data.value)
|
||||
this.deleteComponentWithId(event.data.value)
|
||||
}
|
||||
if (event.data.type === 'setComponentData') {
|
||||
console.log('setComponentData', event.data)
|
||||
this.$store.commit('setComponentData', event.data.value)
|
||||
setTimeout(() => {
|
||||
bus.$emit('editSave')
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
this.initWatermark()
|
||||
this.initEvents()
|
||||
const _this = this
|
||||
@ -864,6 +867,7 @@ export default {
|
||||
this.multiplexingStyleAdaptSelf = this.multiplexingStyleAdapt
|
||||
},
|
||||
beforeDestroy() {
|
||||
bus.$off('mobile-status-change', this.mobileStatusChange)
|
||||
bus.$off('component-on-drag', this.componentOnDrag)
|
||||
bus.$off('component-dialog-style', this.componentDialogStyle)
|
||||
bus.$off('previewFullScreenClose', this.previewFullScreenClose)
|
||||
@ -875,6 +879,40 @@ export default {
|
||||
elx && elx.remove()
|
||||
},
|
||||
methods: {
|
||||
handleLoad() {
|
||||
this.mobileLoading = false
|
||||
this.mobileStatusChange('openMobileLayout', this.componentData)
|
||||
},
|
||||
deleteComponentWithId(id) {
|
||||
for (let index = 0; index < this.pcComponentData.length; index++) {
|
||||
const element = this.pcComponentData[index]
|
||||
if (element.id && element.id === id) {
|
||||
element.mobileSelected = false
|
||||
if (element.type === 'de-tabs') {
|
||||
this.deleteComponentWithId(element.id)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
mobileStatusChange(type, value) {
|
||||
console.log('mobileLayoutStatustype', type, this.mobileLayoutStatus)
|
||||
if (!this.mobileLayoutStatus) return
|
||||
const iframe = document.querySelector('iframe')
|
||||
console.log('iframe', iframe)
|
||||
if (iframe) {
|
||||
iframe.contentWindow.postMessage(
|
||||
{
|
||||
type,
|
||||
value
|
||||
},
|
||||
'*'
|
||||
)
|
||||
}
|
||||
// if (['setCanvasStyle', 'addComponent'].includes(type)) {
|
||||
|
||||
// }
|
||||
},
|
||||
initWatermark() {
|
||||
if (this.panelInfo.watermarkInfo) {
|
||||
this.$nextTick(() => {
|
||||
@ -1557,14 +1595,14 @@ export default {
|
||||
.mobile_canvas_main {
|
||||
width: 80%;
|
||||
height: 90%;
|
||||
margin-left: 10%;
|
||||
margin-left: 7%;
|
||||
margin-top: 3%;
|
||||
}
|
||||
|
||||
.this_mobile_canvas {
|
||||
border-radius: 30px;
|
||||
min-width: 300px;
|
||||
max-width: 350px;
|
||||
min-width: 370px;
|
||||
max-width: 370px;
|
||||
min-height: 600px;
|
||||
max-height: 700px;
|
||||
overflow: hidden;
|
||||
|
||||
@ -75,6 +75,7 @@ export const CANVAS_STYLE = {
|
||||
showPageLine: false,
|
||||
proportion: null
|
||||
},
|
||||
autoSizeAdaptor: true, // 组件内容大小自适应(自适应时会根据画布缩放比例对内容进行缩放,关闭则显示内部文本实际大小)
|
||||
refreshViewEnable: false, // 开启视图刷新(默认关闭)
|
||||
refreshViewLoading: true, // 仪表板视图loading提示
|
||||
refreshUnit: 'minute', // 仪表板刷新时间带外 默认 分钟
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
>
|
||||
<el-upload
|
||||
action=""
|
||||
accept=".jpeg,.jpg,.png,.gif"
|
||||
accept=".jpeg,.jpg,.png,.gif,.svg"
|
||||
class="avatar-uploader"
|
||||
list-type="picture-card"
|
||||
:http-request="upload"
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
>
|
||||
<el-upload
|
||||
action=""
|
||||
accept=".jpeg,.jpg,.png,.gif"
|
||||
accept=".jpeg,.jpg,.png,.gif,.svg"
|
||||
class="avatar-uploader"
|
||||
list-type="picture-card"
|
||||
:http-request="upload"
|
||||
@ -106,6 +106,7 @@ import { mapState } from 'vuex'
|
||||
import { deepCopy, imgUrlTrans } from '@/components/canvas/utils/utils'
|
||||
import { COLOR_PANEL } from '@/views/chart/chart/chart'
|
||||
import { uploadFileResult } from '@/api/staticResource/staticResource'
|
||||
import bus from '@/utils/bus'
|
||||
|
||||
export default {
|
||||
name: 'MobileBackgroundSelector',
|
||||
@ -141,6 +142,7 @@ export default {
|
||||
const canvasStyleData = deepCopy(this.canvasStyleData)
|
||||
canvasStyleData.panel.mobileSetting = this.mobileSetting
|
||||
this.$store.commit('setCanvasStyle', canvasStyleData)
|
||||
bus.$emit('mobile-status-change', 'setCanvasStyle', canvasStyleData)
|
||||
this.$store.commit('recordSnapshot', 'commitStyle')
|
||||
},
|
||||
onChangeType() {
|
||||
|
||||
@ -41,6 +41,11 @@ module.exports = {
|
||||
entry: 'src/main.js',
|
||||
template: 'public/index.html',
|
||||
filename: 'index.html'
|
||||
},
|
||||
mobile: {
|
||||
entry: 'src/mobile/main.js',
|
||||
template: 'public/mobile.html',
|
||||
filename: 'mobile.html'
|
||||
}
|
||||
},
|
||||
configureWebpack: {
|
||||
|
||||
@ -725,7 +725,7 @@ public class DmQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -747,7 +747,7 @@ public class KingbaseQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -577,7 +577,7 @@ public class KylinQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -592,7 +592,7 @@ public class MaxcomputeQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -592,7 +592,7 @@ public class MongobiQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
@ -582,7 +582,7 @@ public class PrestoQueryProvider extends QueryProvider {
|
||||
|
||||
//然后是数值格式的情况还需要传extGroup
|
||||
if (xIsNumber && CollectionUtils.isNotEmpty(extGroup)) {
|
||||
xAxisList.add(extGroup.get(0));
|
||||
xAxisList.addAll(extGroup);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(xAxisList)) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user