diff --git a/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.xml b/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.xml index 2e572d0578..abb27c3635 100644 --- a/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.xml +++ b/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.xml @@ -124,8 +124,8 @@ and configuration = #{configuration,jdbcType=LONGVARCHAR} - - order by ${sort} + + order by #{sort} diff --git a/backend/src/main/java/io/dataease/plugins/server/XEmailTaskServer.java b/backend/src/main/java/io/dataease/plugins/server/XEmailTaskServer.java index 965889d66a..07d0736209 100644 --- a/backend/src/main/java/io/dataease/plugins/server/XEmailTaskServer.java +++ b/backend/src/main/java/io/dataease/plugins/server/XEmailTaskServer.java @@ -165,6 +165,44 @@ public class XEmailTaskServer { return xpackEmailCreate; } + @DeRateLimiter + @PostMapping(value = "/screenpdf", produces = {MediaType.APPLICATION_PDF_VALUE}) + public ResponseEntity screenpdf(@RequestBody XpackEmailViewRequest request) { + EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class); + String url = ServletUtils.domain() + "/#/previewScreenShot/" + request.getPanelId() + "/true"; + byte[] bytes = null; + try { + String currentToken = ServletUtils.getToken(); + Future future = priorityExecutor.submit(() -> { + try { + return emailXpackService.printPdf(url, currentToken, buildPixel(request.getPixel())); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + DEException.throwException("预览失败,请联系管理员"); + } + return null; + }, 0); + Object object = future.get(); + if (ObjectUtils.isNotEmpty(object)) { + bytes = (byte[]) object; + if (ArrayUtil.isNotEmpty(bytes)) { + String fileName = request.getPanelId() + ".pdf"; + ByteArrayResource bar = new ByteArrayResource(bytes); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_PDF); + ContentDisposition contentDisposition = ContentDisposition.parse("attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")); + headers.setContentDisposition(contentDisposition); + return new ResponseEntity(bar, headers, HttpStatus.OK); + } + } + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + DEException.throwException("预览失败,请联系管理员"); + } + + return null; + } + @DeRateLimiter @PostMapping(value = "/screenshot", produces = {MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE}) public ResponseEntity screenshot(@RequestBody XpackEmailViewRequest request) { diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 7afe499902..2cb580c952 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -444,7 +444,7 @@ public class ChartViewService { fieldMap.put("yAxis", yAxis); fieldMap.put("extStack", extStack); fieldMap.put("extBubble", extBubble); - PluginViewParam pluginViewParam = buildPluginParam(fieldMap, fieldCustomFilter, extFilterList, ds, table, view); + PluginViewParam pluginViewParam = buildPluginParam(fieldMap, fieldCustomFilter, extFilterList, ds, table, view, rowPermissionsTree); String sql = pluginViewSql(pluginViewParam, view); if (StringUtils.isBlank(sql)) { return new ArrayList(); @@ -908,7 +908,7 @@ public class ChartViewService { fieldMap.put("extBubble", extBubble); fieldMap.put("xAxis", xAxis); fieldMap.put("yAxis", yAxis); - PluginViewParam pluginViewParam = buildPluginParam(fieldMap, fieldCustomFilter, extFilterList, ds, table, view); + PluginViewParam pluginViewParam = buildPluginParam(fieldMap, fieldCustomFilter, extFilterList, ds, table, view, rowPermissionsTree); String sql = pluginViewSql(pluginViewParam, view); if (StringUtils.isBlank(sql)) { return emptyChartViewDTO(view); @@ -1358,7 +1358,7 @@ public class ChartViewService { return dto; } - private PluginViewParam buildPluginParam(Map> fieldMap, List customFilters, List extFilters, Datasource ds, DatasetTable table, ChartViewDTO view) { + private PluginViewParam buildPluginParam(Map> fieldMap, List customFilters, List extFilters, Datasource ds, DatasetTable table, ChartViewDTO view, List rowPermissionsTree) { PluginViewParam pluginViewParam = new PluginViewParam(); PluginViewSetImpl pluginViewSet = BeanUtils.copyBean(new PluginViewSetImpl(), table); pluginViewSet.setDsType(ds.getType()); @@ -1380,6 +1380,7 @@ public class ChartViewService { pluginViewParam.setPluginChartFieldCustomFilters(fieldFilters); pluginViewParam.setPluginChartExtFilters(panelFilters); pluginViewParam.setPluginViewLimit(pluginViewLimit); + pluginViewParam.setRowPermissionsTree(rowPermissionsTree); return pluginViewParam; } diff --git a/backend/src/main/java/io/dataease/service/chart/ViewPluginBaseServiceImpl.java b/backend/src/main/java/io/dataease/service/chart/ViewPluginBaseServiceImpl.java index 5b54376b2c..c77eba238c 100644 --- a/backend/src/main/java/io/dataease/service/chart/ViewPluginBaseServiceImpl.java +++ b/backend/src/main/java/io/dataease/service/chart/ViewPluginBaseServiceImpl.java @@ -15,6 +15,7 @@ import io.dataease.plugins.common.dto.chart.ChartFieldCustomFilterDTO; import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO; import io.dataease.plugins.common.dto.sqlObj.SQLObj; import io.dataease.plugins.common.request.chart.ChartExtFilterRequest; +import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; import io.dataease.plugins.common.util.BeanUtils; import io.dataease.plugins.common.util.ConstantsUtil; import io.dataease.plugins.datasource.query.QueryProvider; @@ -74,9 +75,9 @@ public class ViewPluginBaseServiceImpl implements ViewPluginBaseService { String methodName = "transCustomFilterList"; SQLObj sqlObj = BeanUtils.copyBean(SQLObj.builder().build(), pluginViewSQL); List filters = list.stream().map(item -> gson.fromJson(gson.toJson(item), ChartFieldCustomFilterDTO.class)).collect(Collectors.toList()); - Object o ; + Object o; if ((o = execProviderMethod(queryProvider, methodName, sqlObj, filters)) != null) { - return (String)o; + return (String) o; } return null; } @@ -89,30 +90,38 @@ public class ViewPluginBaseServiceImpl implements ViewPluginBaseService { List filters = list.stream().map(item -> gson.fromJson(gson.toJson(item), ChartExtFilterRequest.class)).collect(Collectors.toList()); Object o; if ((o = execProviderMethod(queryProvider, methodName, sqlObj, filters)) != null) { - return (String)o; + return (String) o; } return null; } + @Override + public String permissionWhere(String s, List list, PluginViewSQL pluginViewSQL) { + QueryProvider queryProvider = ProviderFactory.getQueryProvider(s); + SQLObj sqlObj = BeanUtils.copyBean(SQLObj.builder().build(), pluginViewSQL); + return queryProvider.transFilterTrees(sqlObj, list); + } + private String sqlFix(String sql) { if (sql.lastIndexOf(";") == (sql.length() - 1)) { sql = sql.substring(0, sql.length() - 1); } return sql; } + @Override public PluginViewSQL getTableObj(PluginViewSet pluginViewSet) { String tableName = null; DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(pluginViewSet.getInfo(), DataTableInfoDTO.class); if (ObjectUtils.isNotEmpty(pluginViewSet.getMode()) && 1 == pluginViewSet.getMode()) { tableName = TableUtils.tableName(pluginViewSet.getTableId()); - }else { + } else { switch (DatasetType.getEnumObjByKey(pluginViewSet.getType())) { case DB: tableName = dataTableInfoDTO.getTable(); break; case SQL: - String sql = dataTableInfoDTO.isBase64Encryption()? new String(java.util.Base64.getDecoder().decode(dataTableInfoDTO.getSql())): dataTableInfoDTO.getSql(); + String sql = dataTableInfoDTO.isBase64Encryption() ? new String(java.util.Base64.getDecoder().decode(dataTableInfoDTO.getSql())) : dataTableInfoDTO.getSql(); tableName = dataSetTableService.handleVariableDefaultValue(sql, null, pluginViewSet.getDsType()); tableName = "(" + sqlFix(tableName) + ")"; @@ -139,7 +148,7 @@ public class ViewPluginBaseServiceImpl implements ViewPluginBaseService { PluginViewSQL tableObj = PluginViewSQL.builder().tableName(realTableName).tableAlias(tableAlias).build(); QueryProvider queryProvider = ProviderFactory.getQueryProvider(pluginViewSet.getDsType()); SQLObj sqlObj = SQLObj.builder().tableName(realTableName).tableAlias(tableAlias).build(); - PluginViewSetImpl child = (PluginViewSetImpl)pluginViewSet; + PluginViewSetImpl child = (PluginViewSetImpl) pluginViewSet; queryProvider.setSchema(sqlObj, child.getDs()); tableObj.setTableName(sqlObj.getTableName()); tableObj.setTableAlias(sqlObj.getTableAlias()); @@ -149,9 +158,9 @@ public class ViewPluginBaseServiceImpl implements ViewPluginBaseService { private String getOriginName(String dsType, PluginViewField pluginViewField, PluginViewSQL tableObj) { String keyword_fix = ConstantsUtil.constantsValue(dsType, "KEYWORD_FIX"); String originField; - String reflectField = reflectFieldName(dsType, pluginViewField); + String reflectField = reflectFieldName(dsType, pluginViewField); if (ObjectUtils.isNotEmpty(pluginViewField.getExtField()) && pluginViewField.getExtField() == 2) { - originField = calcFieldRegex(dsType,pluginViewField.getOriginName(), tableObj); + originField = calcFieldRegex(dsType, pluginViewField.getOriginName(), tableObj); } else if (ObjectUtils.isNotEmpty(pluginViewField.getExtField()) && pluginViewField.getExtField() == 1) { originField = String.format(keyword_fix, tableObj.getTableAlias(), StringUtils.isNotBlank(reflectField) ? reflectField : pluginViewField.getOriginName()); } else { @@ -164,38 +173,37 @@ public class ViewPluginBaseServiceImpl implements ViewPluginBaseService { QueryProvider queryProvider = ProviderFactory.getQueryProvider(dsType); String methodName = "calcFieldRegex"; SQLObj sqlObj = BeanUtils.copyBean(SQLObj.builder().build(), pluginViewSQL); - Object o ; + Object o; if ((o = execProviderMethod(queryProvider, methodName, originField, sqlObj)) != null) { - return (String)o; + return (String) o; } return null; } - private String reflectFieldName(String dsType, PluginViewField pluginViewField ) { + private String reflectFieldName(String dsType, PluginViewField pluginViewField) { QueryProvider queryProvider = ProviderFactory.getQueryProvider(dsType); String methodName = "reflectFieldName"; - DatasetTableField field = BeanUtils.copyBean(new DatasetTableField(), pluginViewField);; - Object o ; + DatasetTableField field = BeanUtils.copyBean(new DatasetTableField(), pluginViewField); + Object o; if ((o = execProviderMethod(queryProvider, methodName, field)) != null) { - return (String)o; + return (String) o; } return null; } - private PluginViewSQL getField(String dsType, PluginViewField field, String originField, String fieldAlias) { QueryProvider queryProvider = ProviderFactory.getQueryProvider(dsType); String methodName; if (StringUtils.equals(field.getTypeField(), "xAxis") || StringUtils.equals(field.getTypeField(), "extStack")) { methodName = "getXFields"; - }else { + } else { methodName = "getYFields"; } ChartViewFieldDTO chartViewFieldDTO = BeanUtils.copyBean(new ChartViewFieldDTO(), field); Object execResult; - if ((execResult = execProviderMethod(queryProvider, methodName, chartViewFieldDTO, originField, fieldAlias)) != null){ - SQLObj sqlObj = (SQLObj)execResult; + if ((execResult = execProviderMethod(queryProvider, methodName, chartViewFieldDTO, originField, fieldAlias)) != null) { + SQLObj sqlObj = (SQLObj) execResult; PluginViewSQL result = PluginViewSQL.builder().build(); return BeanUtils.copyBean(result, sqlObj); } @@ -215,27 +223,26 @@ public class ViewPluginBaseServiceImpl implements ViewPluginBaseService { } - - private PluginViewSQL addSort(String sort, String originField, String fieldAlias) { + private PluginViewSQL addSort(String sort, String originField, String fieldAlias) { if (StringUtils.isNotEmpty(sort) && !StringUtils.equalsIgnoreCase(sort, "none")) { return PluginViewSQL.builder().orderField(originField).orderAlias(fieldAlias).orderDirection(sort).build(); } return null; } - private String getWhere(String dsType, PluginViewField field,String originField,String fieldAlias) { + private String getWhere(String dsType, PluginViewField field, String originField, String fieldAlias) { QueryProvider queryProvider = ProviderFactory.getQueryProvider(dsType); String methodName; if (StringUtils.equals(field.getTypeField(), "xAxis") || StringUtils.equals(field.getTypeField(), "extStack")) { return null; - }else { + } else { methodName = "getYWheres"; } ChartViewFieldDTO chartViewFieldDTO = BeanUtils.copyBean(new ChartViewFieldDTO(), field); Object execResult; - if ((execResult = execProviderMethod(queryProvider, methodName, chartViewFieldDTO, originField, fieldAlias)) != null){ - String where = (String)execResult; + if ((execResult = execProviderMethod(queryProvider, methodName, chartViewFieldDTO, originField, fieldAlias)) != null) { + String where = (String) execResult; return where; } return null; diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java index eef88b89c5..99fccc8b24 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -972,7 +972,11 @@ public class DataSetTableService { return new ArrayList<>(); } DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(id); - return getSqlVariableDetails(type, Arrays.asList(datasetTable)); + if (datasetTable != null) { + return getSqlVariableDetails(type, Arrays.asList(datasetTable)); + } else { + return null; + } } private List getSqlVariableDetails(String type, List datasetTables) { @@ -2861,7 +2865,8 @@ public class DataSetTableService { hasSubBinaryExpression = false; try { BinaryExpression rightBinaryExpression = (BinaryExpression) expr.getRightExpression(); - hasSubBinaryExpression = rightBinaryExpression instanceof AndExpression || rightBinaryExpression instanceof OrExpression;; + hasSubBinaryExpression = rightBinaryExpression instanceof AndExpression || rightBinaryExpression instanceof OrExpression; + ; } catch (Exception e) { } if (expr.getRightExpression() instanceof BinaryExpression && !hasSubBinaryExpression && hasVariable(expr.getRightExpression().toString())) { diff --git a/backend/src/main/java/io/dataease/service/datasource/DatasourceService.java b/backend/src/main/java/io/dataease/service/datasource/DatasourceService.java index b867ebed3c..900c9ef98d 100644 --- a/backend/src/main/java/io/dataease/service/datasource/DatasourceService.java +++ b/backend/src/main/java/io/dataease/service/datasource/DatasourceService.java @@ -158,11 +158,17 @@ public class DatasourceService { } public List getDatasourceList(DatasourceUnionRequest request) throws Exception { - request.setSort("update_time desc"); List datasourceDTOS = extDataSourceMapper.queryUnion(request); - datasourceDTOS.forEach(datasourceDTO -> { - datasourceTrans(datasourceDTO); - }); + datasourceDTOS.forEach(this::datasourceTrans); + if (StringUtils.isBlank(request.getSort())) { + datasourceDTOS.sort((o1,o2) -> { + int tmp = StringUtils.compareIgnoreCase(o1.getTypeDesc(), o2.getTypeDesc()); + if (tmp == 0) { + tmp = StringUtils.compareIgnoreCase(o1.getName(), o2.getName()); + } + return tmp; + }); + } return datasourceDTOS; } diff --git a/frontend/src/components/canvas/DeCanvas.vue b/frontend/src/components/canvas/DeCanvas.vue index 797273c3f3..959a1379aa 100644 --- a/frontend/src/components/canvas/DeCanvas.vue +++ b/frontend/src/components/canvas/DeCanvas.vue @@ -297,6 +297,9 @@ export default { // this.$emit('handleDrop', e) // } handleDrop(e) { + if (!this.dragComponentInfo) { + return + } this.dragComponentInfo.moveStatus = 'drop' // 记录拖拽信息 this.dropComponentInfo = deepCopy(this.dragComponentInfo) diff --git a/frontend/src/components/canvas/components/TextAttr.vue b/frontend/src/components/canvas/components/TextAttr.vue index 5b42a930bd..59a66cf145 100644 --- a/frontend/src/components/canvas/components/TextAttr.vue +++ b/frontend/src/components/canvas/components/TextAttr.vue @@ -24,7 +24,7 @@ > - + @@ -47,7 +47,7 @@ :value="item.value" > - + {{ item.label }} @@ -257,7 +257,7 @@ @click="goColor" /> -
+
-
+
-
+
- +
@@ -327,7 +327,7 @@ style="width: 20px;float: left;margin-top: 2px;margin-left: 2px;" > - +
@@ -336,7 +336,7 @@ style="width: 20px;float: left;margin-top: 2px;margin-left: 2px;" > - +
- +
@@ -616,7 +616,7 @@ export default { mainStyle() { const style = { - left: (this.getPositionX(this.curComponent.style.left) - this.scrollLeft) + 'px', + left: (this.getPositionX(this.curComponent.style.left) - this.scrollLeft - 10) + 'px', top: (this.getPositionY(this.curComponent.style.top) - this.scrollTop + 20) + 'px' } return style diff --git a/frontend/src/components/canvas/components/Toolbar.vue b/frontend/src/components/canvas/components/Toolbar.vue index 2900b4b022..b2138a1d57 100644 --- a/frontend/src/components/canvas/components/Toolbar.vue +++ b/frontend/src/components/canvas/components/Toolbar.vue @@ -153,6 +153,30 @@ @change="styleChange" /> + + + + + + + + {{ $t('panel.export_pdf_page') }} + + + + @@ -247,6 +271,7 @@ export default { }, data() { return { + showPageLine: false, showGridSwitch: false, mobileLayoutInitStatus: false, isShowPreview: false, @@ -305,6 +330,7 @@ export default { this.scale = this.canvasStyleData.scale this.mobileLayoutInitStatus = this.mobileLayoutStatus this.showGridSwitch = this.canvasStyleData.aidedDesign.showGrid + this.showPageLine = this.canvasStyleData.pdfPageLine?.showPageLine this.autoCache() }, beforeDestroy() { @@ -323,6 +349,7 @@ export default { }, editPanelInit() { this.showGridSwitch = this.canvasStyleData.aidedDesign.showGrid + this.showPageLine = this.canvasStyleData.pdfPageLine?.showPageLine }, close() { // 关闭页面清理缓存 @@ -589,6 +616,10 @@ export default { this.$store.commit('canvasChange') this.canvasStyleData.aidedDesign.showGrid = !this.canvasStyleData.aidedDesign.showGrid }, + showPageLineChange() { + this.$store.commit('canvasChange') + this.canvasStyleData.pdfPageLine.showPageLine = !this.canvasStyleData.pdfPageLine.showPageLine + }, // batch option batchOption() { bus.$emit('change_panel_right_draw', !this.batchOptStatus) diff --git a/frontend/src/components/canvas/components/editor/ComponentWrapper.vue b/frontend/src/components/canvas/components/editor/ComponentWrapper.vue index bba9a44403..feb5095084 100644 --- a/frontend/src/components/canvas/components/editor/ComponentWrapper.vue +++ b/frontend/src/components/canvas/components/editor/ComponentWrapper.vue @@ -204,7 +204,7 @@ export default { return style }, componentActiveFlag() { - return !this.mobileLayoutStatus && ((this.curComponent && this.config.id === this.curComponent.id && !this.previewVisible && !this.showPosition.includes('email-task')) || this.showPosition.includes('multiplexing')) + return (!this.mobileLayoutStatus || this.terminal === 'mobile') && ((this.curComponent && this.config.id === this.curComponent.id && !this.previewVisible && !this.showPosition.includes('email-task')) || this.showPosition.includes('multiplexing')) }, scale() { return Math.min(this.previewCanvasScale.scalePointWidth, this.previewCanvasScale.scalePointHeight) @@ -279,7 +279,7 @@ export default { } else { return { ... - getStyle(style, ['top', 'left', 'width', 'height', 'rotate']), + getStyle(style, ['top', 'left', 'width', 'height', 'rotate']), position: 'relative' } } diff --git a/frontend/src/components/canvas/components/editor/DeEditor.vue b/frontend/src/components/canvas/components/editor/DeEditor.vue index 31234920ae..64ee36fd7f 100644 --- a/frontend/src/components/canvas/components/editor/DeEditor.vue +++ b/frontend/src/components/canvas/components/editor/DeEditor.vue @@ -12,6 +12,11 @@ @mousedown="handleMouseDown" @scroll="canvasScroll" > + - + { + const top = this.getShapeStyleIntDeDrag(item.style, 'top') + const height = this.getShapeStyleIntDeDrag(item.style, 'height') + baseHeight = Math.max(baseHeight, top + height) + }) + return baseHeight + }, customStyle() { let style = { width: '100%', @@ -1024,6 +1046,20 @@ export default { }, deep: true }, + scrollHeight: { + handler(newVal, oldVla) { + this.$nextTick(() => { + if (newVal !== oldVla && this.showPageLine) { + const lineRef = this.$refs['main-page-line'] + if (lineRef?.init) { + lineRef.init(newVal) + } + } + console.log(newVal) + }) + }, + deep: true + }, outStyle: { handler(newVal, oldVla) { this.resizeParentBoundsRef() @@ -1251,6 +1287,9 @@ export default { }, changeStyleWithScale, handleMouseDown(e) { + if (this.isPageLineTarget(e)) { + return + } // 如果没有选中组件 在画布上点击时需要调用 e.preventDefault() 防止触发 drop 事件 if (!this.curComponent || (this.curComponent.component !== 'v-text' && this.curComponent.component !== 'rect-shape')) { e.preventDefault() @@ -1259,6 +1298,9 @@ export default { // 挤占式画布设计 this.containerMouseDown(e) }, + isPageLineTarget(e) { + return e.target.classList && [...e.target.classList].includes('page-line-item') + }, hideArea() { this.isShowArea = 0 @@ -1517,6 +1559,9 @@ export default { } }, handleDragOver(e) { + if (!this.dragComponentInfo?.shadowStyle) { + return + } this.dragComponentInfo.shadowStyle.x = e.pageX - 220 this.dragComponentInfo.shadowStyle.y = e.pageY - 90 + this.scrollTop this.dragComponentInfo.style.left = this.dragComponentInfo.shadowStyle.x / this.scalePointWidth diff --git a/frontend/src/components/canvas/components/editor/PageLineEditor.vue b/frontend/src/components/canvas/components/editor/PageLineEditor.vue new file mode 100644 index 0000000000..fe582606eb --- /dev/null +++ b/frontend/src/components/canvas/components/editor/PageLineEditor.vue @@ -0,0 +1,136 @@ + + + + + diff --git a/frontend/src/components/canvas/components/editor/Preview.vue b/frontend/src/components/canvas/components/editor/Preview.vue index 648499c89c..1ce56ac016 100644 --- a/frontend/src/components/canvas/components/editor/Preview.vue +++ b/frontend/src/components/canvas/components/editor/Preview.vue @@ -112,7 +112,7 @@ style="position: absolute;right: 70px;top:15px" > - + {{ $t('panel.copy') }}(+ D Control + D) + >{{ $t('panel.copy') }} (+ D Control + D) - {{ $t('panel.level') }} + {{ $t('panel.level') }} - - {{ $t('panel.hyperlinks') }} + >{{ $t('panel.hyperlinks') }} - + {{ $t('panel.position_adjust') }} diff --git a/frontend/src/components/canvas/customComponent/UserView.vue b/frontend/src/components/canvas/customComponent/UserView.vue index 475fdf50bf..63fea5b87e 100644 --- a/frontend/src/components/canvas/customComponent/UserView.vue +++ b/frontend/src/components/canvas/customComponent/UserView.vue @@ -141,7 +141,7 @@ style="position: absolute;right: 70px;top:15px" > 0 && method(param).then(res => { this.data = this.optionData(res.data) + this.clearDefault(this.data) bus.$emit('valid-values-change', true) }).catch(e => { bus.$emit('valid-values-change', false) @@ -228,6 +229,27 @@ export default { bus.$off('reset-default-value', this.resetDefaultValue) }, methods: { + clearDefault(optionList) { + const emptyOption = !optionList?.length + + if (!this.inDraw && this.element.options.value) { + if (Array.isArray(this.element.options.value)) { + if (emptyOption) { + this.element.options.value = [] + return + } + const tempValueArray = JSON.parse(JSON.stringify(this.element.options.value)) + this.element.options.value = tempValueArray.filter(item => optionList.some(option => option === item)) + } else { + if (emptyOption) { + this.element.options.value = '' + return + } + const tempValueArray = JSON.parse(JSON.stringify(this.element.options.value.split(','))) + this.element.options.value = tempValueArray.filter(item => optionList.some(option => option === item)).join(',') + } + } + }, clearHandler() { this.value = this.element.options.attrs.multiple ? [] : null this.$refs.deSelect && this.$refs.deSelect.resetSelectAll && this.$refs.deSelect.resetSelectAll() diff --git a/frontend/src/components/widget/deWidget/DeSelectGrid.vue b/frontend/src/components/widget/deWidget/DeSelectGrid.vue index b6cb323382..d4887feb9a 100644 --- a/frontend/src/components/widget/deWidget/DeSelectGrid.vue +++ b/frontend/src/components/widget/deWidget/DeSelectGrid.vue @@ -179,6 +179,7 @@ export default { this.element.options.attrs.fieldId.length > 0 && method(param).then(res => { this.data = this.optionData(res.data) + this.clearDefault(this.data) this.changeInputStyle() if (this.element.options.attrs.multiple) { this.checkAll = this.value.length === this.data.length @@ -250,6 +251,27 @@ export default { bus.$off('reset-default-value', this.resetDefaultValue) }, methods: { + clearDefault(optionList) { + const emptyOption = !optionList?.length + + if (!this.inDraw && this.element.options.value) { + if (Array.isArray(this.element.options.value)) { + if (emptyOption) { + this.element.options.value = [] + return + } + const tempValueArray = JSON.parse(JSON.stringify(this.element.options.value)) + this.element.options.value = tempValueArray.filter(item => optionList.some(option => option === item)) + } else { + if (emptyOption) { + this.element.options.value = '' + return + } + const tempValueArray = JSON.parse(JSON.stringify(this.element.options.value.split(','))) + this.element.options.value = tempValueArray.filter(item => optionList.some(option => option === item)).join(',') + } + } + }, clearHandler() { this.value = this.element.options.attrs.multiple ? [] : null this.checkAll = false diff --git a/frontend/src/icons/svg/page-line.svg b/frontend/src/icons/svg/page-line.svg new file mode 100644 index 0000000000..224b1e0a58 --- /dev/null +++ b/frontend/src/icons/svg/page-line.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 0be62dda0c..e36c6bab0f 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -1509,7 +1509,14 @@ export default { Line (area) chart, Column (Bar) chart, Dashboard: {a} is series name, {b} is category value, {c} is value
Pie chart, Funnel chart: {a} is series name, {b} is data item name, {c} is value, {d} is percentage
Map : {a} (series name), {b} is area name, {c} is merged values, {d} is none
- Scatter (Bubble) plot: {a} is series name, {b} is data name, {c} is numeric array, {d} is none` + Scatter (Bubble) plot: {a} is series name, {b} is data name, {c} is numeric array, {d} is none`, + h_position: 'Horizontal Position', + v_position: 'Vertical Position', + p_left: 'Left', + p_right: 'Right', + p_top: 'Top', + p_bottom: 'Bottom', + p_center: 'Center' }, dataset: { spend_time: 'Spend', @@ -2244,6 +2251,8 @@ export default { aided_grid: 'Aided Grid', aided_grid_open: 'Open', aided_grid_close: 'Close', + export_pdf_page: 'Pagination Line', + export_pdf_page_remark: 'Only valid for API export dashboard PDF pagination', subject_no_edit: 'System Subject Can Not Edit', subject_name_not_null: 'Subject Name Can Not Be Null And Less Than 20 charts', is_enable: 'Enable', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 934ee002fd..9339083849 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -1503,7 +1503,14 @@ export default { 折線(區域)圖、柱狀(條形)圖、儀表盤 : {a}(系列名稱),{b}(類目值),{c}(數值)
餅圖、漏鬥圖: {a}(系列名稱),{b}(數據項名稱),{c}(數值), {d}(百分比)
地圖 : {a}(系列名稱),{b}(區域名稱),{c}(合並數值), {d}(無)
- 散點圖(氣泡)圖 : {a}(系列名稱),{b}(數據名稱),{c}(數值數組), {d}(無)` + 散點圖(氣泡)圖 : {a}(系列名稱),{b}(數據名稱),{c}(數值數組), {d}(無)`, + h_position: '水平位置', + v_position: '垂直位置', + p_left: '左對齊', + p_right: '右對齊', + p_top: '上對齊', + p_bottom: '下對齊', + p_center: '居中' }, dataset: { spend_time: '耗時', @@ -2238,6 +2245,8 @@ export default { aided_grid: '輔助設計網格', aided_grid_open: '打開', aided_grid_close: '關閉', + export_pdf_page: '分頁線', + export_pdf_page_remark: '僅對API導出儀表板PDF分頁有效', subject_no_edit: '繫統主題不能修改', subject_name_not_null: '主題名稱需要1~20字符', is_enable: '是否啟用', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index e82257b21a..c5ecf9bc9a 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -1502,7 +1502,14 @@ export default { 折线(区域)图、柱状(条形)图、仪表盘 : {a}(系列名称),{b}(类目值),{c}(数值)
饼图、漏斗图: {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
地图 : {a}(系列名称),{b}(区域名称),{c}(合并数值), {d}(无)
- 散点图(气泡)图 : {a}(系列名称),{b}(数据名称),{c}(数值数组), {d}(无)` + 散点图(气泡)图 : {a}(系列名称),{b}(数据名称),{c}(数值数组), {d}(无)`, + h_position: '水平位置', + v_position: '垂直位置', + p_left: '左对齐', + p_right: '右对齐', + p_top: '上对齐', + p_bottom: '下对齐', + p_center: '居中' }, dataset: { spend_time: '耗时', @@ -2238,6 +2245,8 @@ export default { aided_grid: '辅助设计网格', aided_grid_open: '打开', aided_grid_close: '关闭', + export_pdf_page: '分页线', + export_pdf_page_remark: '仅对API导出仪表板PDF分页有效', subject_no_edit: '系统主题不能修改', subject_name_not_null: '主题名称需要1~20字符', is_enable: '是否启用', diff --git a/frontend/src/views/chart/chart/chart.js b/frontend/src/views/chart/chart/chart.js index a2bf9a20e2..86a5087fc5 100644 --- a/frontend/src/views/chart/chart/chart.js +++ b/frontend/src/views/chart/chart/chart.js @@ -127,7 +127,9 @@ export const DEFAULT_SIZE = { symbolOpacity: 0.7, symbolStrokeWidth: 2, showIndex: false, - indexLabel: '序号' + indexLabel: '序号', + hPosition: 'center', + vPosition: 'center' } export const DEFAULT_SUSPENSION = { show: true diff --git a/frontend/src/views/chart/chart/util.js b/frontend/src/views/chart/chart/util.js index cec78c5011..972c25c602 100644 --- a/frontend/src/views/chart/chart/util.js +++ b/frontend/src/views/chart/chart/util.js @@ -206,7 +206,9 @@ export const TYPE_CONFIGS = [ 'dimensionFontStyle', 'dimensionLetterSpace', 'dimensionFontShadow', - 'spaceSplit' + 'spaceSplit', + 'hPosition', + 'vPosition' ], 'title-selector-ant-v': [ 'show', @@ -251,7 +253,9 @@ export const TYPE_CONFIGS = [ 'dimensionFontStyle', 'dimensionLetterSpace', 'dimensionFontShadow', - 'spaceSplit' + 'spaceSplit', + 'hPosition', + 'vPosition' ], 'title-selector-ant-v': [ 'show', @@ -1939,7 +1943,9 @@ export const TYPE_CONFIGS = [ 'dimensionFontStyle', 'dimensionLetterSpace', 'dimensionFontShadow', - 'spaceSplit' + 'spaceSplit', + 'hPosition', + 'vPosition' ], 'title-selector': [ 'show', @@ -1984,7 +1990,9 @@ export const TYPE_CONFIGS = [ 'dimensionFontStyle', 'dimensionLetterSpace', 'dimensionFontShadow', - 'spaceSplit' + 'spaceSplit', + 'hPosition', + 'vPosition' ], 'title-selector': [ 'show', diff --git a/frontend/src/views/chart/components/normal/LabelNormal.vue b/frontend/src/views/chart/components/normal/LabelNormal.vue index 52aab307f2..c874c21a4d 100644 --- a/frontend/src/views/chart/components/normal/LabelNormal.vue +++ b/frontend/src/views/chart/components/normal/LabelNormal.vue @@ -189,6 +189,9 @@ export default { this.label_content_class.letterSpacing = (customAttr.size.quotaLetterSpace ? customAttr.size.quotaLetterSpace : DEFAULT_SIZE.quotaLetterSpace) + 'px' this.label_content_class.textShadow = customAttr.size.quotaFontShadow ? '2px 2px 4px' : 'none' + this.content_class.alignItems = customAttr.size.hPosition ? customAttr.size.hPosition : DEFAULT_SIZE.hPosition + this.content_class.justifyContent = customAttr.size.vPosition ? customAttr.size.vPosition : DEFAULT_SIZE.vPosition + if (!this.dimensionShow) { this.label_space.marginTop = '0px' } else { diff --git a/frontend/src/views/chart/components/normal/LabelNormalText.vue b/frontend/src/views/chart/components/normal/LabelNormalText.vue index eb9a6967b4..c31a4dba2b 100644 --- a/frontend/src/views/chart/components/normal/LabelNormalText.vue +++ b/frontend/src/views/chart/components/normal/LabelNormalText.vue @@ -216,6 +216,9 @@ export default { this.label_content_class.letterSpacing = (customAttr.size.quotaLetterSpace ? customAttr.size.quotaLetterSpace : DEFAULT_SIZE.quotaLetterSpace) + 'px' this.label_content_class.textShadow = customAttr.size.quotaFontShadow ? '2px 2px 4px' : 'none' + this.content_class.alignItems = customAttr.size.hPosition ? customAttr.size.hPosition : DEFAULT_SIZE.hPosition + this.content_class.justifyContent = customAttr.size.vPosition ? customAttr.size.vPosition : DEFAULT_SIZE.vPosition + if (!this.dimensionShow) { this.label_space.marginTop = '0px' } else { diff --git a/frontend/src/views/chart/components/shapeAttr/SizeSelector.vue b/frontend/src/views/chart/components/shapeAttr/SizeSelector.vue index 810a25c0ea..5a1e9b38b6 100644 --- a/frontend/src/views/chart/components/shapeAttr/SizeSelector.vue +++ b/frontend/src/views/chart/components/shapeAttr/SizeSelector.vue @@ -634,6 +634,54 @@ @change="changeBarSizeCase('spaceSplit')" /> + + + {{ $t('chart.p_left') }} + {{ $t('chart.p_center') }} + {{ $t('chart.p_right') }} + + + + + {{ $t('chart.p_top') }} + {{ $t('chart.p_center') }} + {{ $t('chart.p_bottom') }} + +
@@ -1076,6 +1124,9 @@ export default { this.sizeForm.dimensionFontIsItalic = this.sizeForm.dimensionFontIsItalic ? this.sizeForm.dimensionFontIsItalic : DEFAULT_SIZE.dimensionFontIsItalic this.sizeForm.dimensionLetterSpace = this.sizeForm.dimensionLetterSpace ? this.sizeForm.dimensionLetterSpace : DEFAULT_SIZE.dimensionLetterSpace this.sizeForm.dimensionFontShadow = this.sizeForm.dimensionFontShadow ? this.sizeForm.dimensionFontShadow : DEFAULT_SIZE.dimensionFontShadow + + this.sizeForm.hPosition = this.sizeForm.hPosition ? this.sizeForm.hPosition : DEFAULT_SIZE.hPosition + this.sizeForm.vPosition = this.sizeForm.vPosition ? this.sizeForm.vPosition : DEFAULT_SIZE.vPosition } } }, diff --git a/frontend/src/views/chart/components/shapeAttr/SizeSelectorAntV.vue b/frontend/src/views/chart/components/shapeAttr/SizeSelectorAntV.vue index 4fab822eb7..4bf8dab6bc 100644 --- a/frontend/src/views/chart/components/shapeAttr/SizeSelectorAntV.vue +++ b/frontend/src/views/chart/components/shapeAttr/SizeSelectorAntV.vue @@ -984,6 +984,54 @@ @change="changeBarSizeCase('spaceSplit')" /> + + + {{ $t('chart.p_left') }} + {{ $t('chart.p_center') }} + {{ $t('chart.p_right') }} + + + + + {{ $t('chart.p_top') }} + {{ $t('chart.p_center') }} + {{ $t('chart.p_bottom') }} + +
@@ -1384,6 +1432,9 @@ export default { this.sizeForm.dimensionFontIsItalic = this.sizeForm.dimensionFontIsItalic ? this.sizeForm.dimensionFontIsItalic : DEFAULT_SIZE.dimensionFontIsItalic this.sizeForm.dimensionLetterSpace = this.sizeForm.dimensionLetterSpace ? this.sizeForm.dimensionLetterSpace : DEFAULT_SIZE.dimensionLetterSpace this.sizeForm.dimensionFontShadow = this.sizeForm.dimensionFontShadow ? this.sizeForm.dimensionFontShadow : DEFAULT_SIZE.dimensionFontShadow + + this.sizeForm.hPosition = this.sizeForm.hPosition ? this.sizeForm.hPosition : DEFAULT_SIZE.hPosition + this.sizeForm.vPosition = this.sizeForm.vPosition ? this.sizeForm.vPosition : DEFAULT_SIZE.vPosition } } }, diff --git a/frontend/src/views/panel/appTemplate/component/TemplateList.vue b/frontend/src/views/panel/appTemplate/component/TemplateList.vue index cc502c0606..ca5ba0777d 100644 --- a/frontend/src/views/panel/appTemplate/component/TemplateList.vue +++ b/frontend/src/views/panel/appTemplate/component/TemplateList.vue @@ -250,8 +250,8 @@ export default { } li.select { - background: var(--deWhiteHover, #3370ff); - color: var(--TextActive, #f4f4f5); + background: var(--deWhiteHover, #ecf5ff) !important; + color: var(--TextActive, #3370ff) !important; } .de-btn-fix { diff --git a/frontend/src/views/panel/appTemplate/component/TemplateMoveList.vue b/frontend/src/views/panel/appTemplate/component/TemplateMoveList.vue index 56aaeb324d..952556810a 100644 --- a/frontend/src/views/panel/appTemplate/component/TemplateMoveList.vue +++ b/frontend/src/views/panel/appTemplate/component/TemplateMoveList.vue @@ -201,8 +201,8 @@ export default { } li.select { - background: var(--deWhiteHover, #3370ff); - color: var(--TextActive, #f4f4f5); + background: var(--deWhiteHover, #ecf5ff) !important; + color: var(--TextActive, #3370ff) !important; } .de-btn-fix { diff --git a/frontend/src/views/panel/edit/index.vue b/frontend/src/views/panel/edit/index.vue index 47955dbe3f..3a12ce4475 100644 --- a/frontend/src/views/panel/edit/index.vue +++ b/frontend/src/views/panel/edit/index.vue @@ -165,12 +165,12 @@ v-show=" show &&showIndex===1" :canvas-id="canvasId" /> - - + +
- + - + {{ panelInfo.name }} @@ -205,7 +205,7 @@ class="this_mobile_canvas_main" :style="mobileCanvasStyle" > - + - + - + @@ -268,7 +268,7 @@ />
- +
@@ -287,7 +287,7 @@ >{{ $t('panel.position_adjust') }} - +
- +
\ No newline at end of file + diff --git a/frontend/src/views/system/relationship/index.vue b/frontend/src/views/system/relationship/index.vue index 11e3b7e977..d96ac23586 100644 --- a/frontend/src/views/system/relationship/index.vue +++ b/frontend/src/views/system/relationship/index.vue @@ -39,6 +39,7 @@ placement="bottom" trigger="manual" :width="popoverSize" + popper-class="relation-popover" >