diff --git a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java index e189b67497..b4f810d23c 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java +++ b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java @@ -541,11 +541,18 @@ public class ChartDataManage { ChartExtFilterDTO tmpFilter = new ChartExtFilterDTO(); DatasetTableFieldDTO datasetTableField = datasetTableFieldManage.selectById(tmpField.getId()); tmpFilter.setDatasetTableField(datasetTableField); - tmpFilter.setOperator("in"); tmpFilter.setDateStyle(fieldMap.get(tmpField.getId()).getDateStyle()); tmpFilter.setDatePattern(fieldMap.get(tmpField.getId()).getDatePattern()); tmpFilter.setFieldId(String.valueOf(tmpField.getId())); - tmpFilter.setValue(Collections.singletonList(dimValMap.get(tmpField.getId()))); + if (datasetTableField.getDeType() == 1) { + tmpFilter.setOperator("between"); + // 把value类似过滤组件处理,获得start time和end time + Map stringLongMap = Utils.parseDateTimeValue(dimValMap.get(tmpField.getId())); + tmpFilter.setValue(Arrays.asList(String.valueOf(stringLongMap.get("startTime")), String.valueOf(stringLongMap.get("endTime")))); + } else { + tmpFilter.setOperator("in"); + tmpFilter.setValue(Collections.singletonList(dimValMap.get(tmpField.getId()))); + } extFilterList.add(tmpFilter); drillFilters.add(tmpFilter); } @@ -614,11 +621,14 @@ public class ChartDataManage { if (Arrays.asList(ChartConstants.M_Y).contains(compareCalc.getType())) { if (StringUtils.equalsIgnoreCase(compareCalc.getField() + "", filterDTO.getFieldId())) { // -1 year - Calendar calendar = Calendar.getInstance(); - calendar.setTime(new Date(Long.parseLong(filterDTO.getValue().getFirst()))); - calendar.add(Calendar.YEAR, -1); - filterDTO.getValue().set(0, String.valueOf(calendar.getTime().getTime())); - isYOY = true; + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date(Long.parseLong(filterDTO.getValue().getFirst()))); + calendar.add(Calendar.YEAR, -1); + filterDTO.getValue().set(0, String.valueOf(calendar.getTime().getTime())); + isYOY = true; + } catch (Exception e) { + } } } } @@ -1594,7 +1604,7 @@ public class ChartDataManage { private List getAllChartFields(ChartViewDTO view) { // get all fields - Map> stringListMap = chartViewManege.listByDQ(view.getTableId(), view.getId()); + Map> stringListMap = chartViewManege.listByDQ(view.getTableId(), view.getId(), view); List dimensionList = stringListMap.get("dimensionList"); List quotaList = stringListMap.get("quotaList"); List allFields = new ArrayList<>(); diff --git a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java index b27edb4538..556d71328f 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java +++ b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java @@ -118,7 +118,7 @@ public class ChartViewManege { return chartDataManage.calcData(details); } - public Map> listByDQ(Long id, Long chartId) { + public Map> listByDQ(Long id, Long chartId, ChartViewDTO chartViewDTO) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("dataset_group_id", id); wrapper.eq("checked", true); @@ -133,6 +133,9 @@ public class ChartViewManege { // filter column disable field Map desensitizationList = new HashMap<>(); List datasetTableFieldDTOS = permissionManage.filterColumnPermissions(collect, desensitizationList, id, null); + if (!chartViewDTO.getType().equalsIgnoreCase("table-info")) { + datasetTableFieldDTOS = datasetTableFieldDTOS.stream().filter(datasetTableFieldDTO -> !desensitizationList.keySet().contains(datasetTableFieldDTO.getDataeaseName())).collect(Collectors.toList()); + } datasetTableFieldDTOS.add(createCountField(id)); List list = transFieldDTO(datasetTableFieldDTOS); diff --git a/core/core-backend/src/main/java/io/dataease/chart/server/ChartViewServer.java b/core/core-backend/src/main/java/io/dataease/chart/server/ChartViewServer.java index d998eb9b6e..ecfb167754 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/server/ChartViewServer.java +++ b/core/core-backend/src/main/java/io/dataease/chart/server/ChartViewServer.java @@ -34,8 +34,8 @@ public class ChartViewServer implements ChartViewApi { } @Override - public Map> listByDQ(Long id, Long chartId) { - return chartViewManege.listByDQ(id, chartId); + public Map> listByDQ(Long id, Long chartId, ChartViewDTO dto) { + return chartViewManege.listByDQ(id, chartId, dto); } @Override diff --git a/core/core-frontend/package.json b/core/core-frontend/package.json index b70396c3a4..aa153cf001 100644 --- a/core/core-frontend/package.json +++ b/core/core-frontend/package.json @@ -45,6 +45,7 @@ "nprogress": "^0.2.0", "pinia": "^2.0.32", "qs": "^6.11.0", + "screenfull": "^6.0.2", "snowflake-id": "^1.1.0", "tinymce": "^5.8.2", "vant": "^4.8.3", diff --git a/core/core-frontend/src/api/chart.ts b/core/core-frontend/src/api/chart.ts index f03cf4d11a..0dee589af3 100644 --- a/core/core-frontend/src/api/chart.ts +++ b/core/core-frontend/src/api/chart.ts @@ -26,8 +26,8 @@ export interface ComponentInfo { datasetId: string } -export const getFieldByDQ = async (id, chartId): Promise => { - return request.post({ url: `/chart/listByDQ/${id}/${chartId}`, data: {} }).then(res => { +export const getFieldByDQ = async (id, chartId, data): Promise => { + return request.post({ url: `/chart/listByDQ/${id}/${chartId}`, data: data }).then(res => { return res?.data }) } diff --git a/core/core-frontend/src/assets/svg/icon_pc_fullscreen.svg b/core/core-frontend/src/assets/svg/icon_pc_fullscreen.svg new file mode 100644 index 0000000000..8c2bdacdc5 --- /dev/null +++ b/core/core-frontend/src/assets/svg/icon_pc_fullscreen.svg @@ -0,0 +1 @@ + diff --git a/core/core-frontend/src/components/dashboard/DbToolbar.vue b/core/core-frontend/src/components/dashboard/DbToolbar.vue index 23bb2a947a..163205832e 100644 --- a/core/core-frontend/src/components/dashboard/DbToolbar.vue +++ b/core/core-frontend/src/components/dashboard/DbToolbar.vue @@ -28,6 +28,7 @@ import OuterParamsSet from '@/components/visualization/OuterParamsSet.vue' import { XpackComponent } from '@/components/plugin' import DbMoreComGroup from '@/custom-component/component-group/DbMoreComGroup.vue' import { useCache } from '@/hooks/web/useCache' +import DeFullscreen from '@/components/visualization/common/DeFullscreen.vue' const { t } = useI18n() const dvMainStore = dvMainStoreWithOut() const snapshotStore = snapshotStoreWithOut() @@ -521,12 +522,7 @@ const initOpenHandler = newWindow => { @@ -360,12 +369,18 @@ defineExpose({ width: 100%; height: 100%; } + .enlarge-inner-with-header { + display: flex; + flex-direction: column; + } .enlarge-wrapper { width: 100%; height: 100%; } } .tab-header { + margin-top: -10px; + margin-bottom: 10px; --ed-tabs-header-height: 34px; --custom-tab-color: #646a73; diff --git a/core/core-frontend/src/components/visualization/common/DeFullscreen.vue b/core/core-frontend/src/components/visualization/common/DeFullscreen.vue new file mode 100644 index 0000000000..0cc86744e9 --- /dev/null +++ b/core/core-frontend/src/components/visualization/common/DeFullscreen.vue @@ -0,0 +1,69 @@ + + + + + diff --git a/core/core-frontend/src/custom-component/v-query/QueryConditionConfiguration.vue b/core/core-frontend/src/custom-component/v-query/QueryConditionConfiguration.vue index b5f4372e8d..edf5679ada 100644 --- a/core/core-frontend/src/custom-component/v-query/QueryConditionConfiguration.vue +++ b/core/core-frontend/src/custom-component/v-query/QueryConditionConfiguration.vue @@ -656,11 +656,27 @@ const cancelValueSource = () => { } const confirmValueSource = () => { - if (valueSource.value.some(ele => !ele.trim())) { + if ( + valueSource.value.some(ele => { + if (typeof ele === 'string') { + return !ele.trim() + } + return false + }) + ) { ElMessage.error('手工输入-选项值不能为空') return } - curComponent.value.valueSource = cloneDeep(valueSource.value.filter(ele => ele.trim())) + console.log(cloneDeep(valueSource.value), 'valueSource') + + curComponent.value.valueSource = cloneDeep( + valueSource.value.filter(ele => { + if (typeof ele === 'string') { + return ele.trim() + } + return true + }) + ) handleValueSourceChange() cancelValueSource() } diff --git a/core/core-frontend/src/locales/zh-CN.ts b/core/core-frontend/src/locales/zh-CN.ts index 4a3a01cf01..6d832c19be 100644 --- a/core/core-frontend/src/locales/zh-CN.ts +++ b/core/core-frontend/src/locales/zh-CN.ts @@ -104,7 +104,7 @@ export default { no_failed_file: '暂无失败文件', no_file: '暂无文件', no_task: '暂无任务', - download_all: '下载全部', + download_all: '全部下载', download: '下载' }, driver: { diff --git a/core/core-frontend/src/permission.ts b/core/core-frontend/src/permission.ts index 5b2fbbca88..402bd50e1c 100644 --- a/core/core-frontend/src/permission.ts +++ b/core/core-frontend/src/permission.ts @@ -22,7 +22,7 @@ const { start, done } = useNProgress() const { loadStart, loadDone } = usePageLoading() -const whiteList = ['/login', '/de-link', '/chart-view'] // 不重定向白名单 +const whiteList = ['/login', '/de-link', '/chart-view', '/notSupport'] // 不重定向白名单 const embeddedWindowWhiteList = ['/dvCanvas', '/dashboard', '/preview', '/dataset-embedded-form'] const embeddedRouteWhiteList = ['/dataset-embedded', '/dataset-form', '/dataset-embedded-form'] router.beforeEach(async (to, from, next) => { @@ -34,13 +34,13 @@ router.beforeEach(async (to, from, next) => { await appStore.setAppModel() isDesktop = appStore.getDesktop } - if (isMobile()) { + if (isMobile() && to.path !== '/notSupport') { done() loadDone() if (to.name === 'link') { window.location.href = window.origin + '/mobile.html#' + to.path } else if (to.path === '/dvCanvas') { - window.location.href = window.origin + '/mobile.html#' + to.path + next('/notSupport') } else if ( wsCache.get('user.token') || isDesktop || diff --git a/core/core-frontend/src/permissionMobile.ts b/core/core-frontend/src/permissionMobile.ts index 3e2b3c5943..7affd4ecd0 100644 --- a/core/core-frontend/src/permissionMobile.ts +++ b/core/core-frontend/src/permissionMobile.ts @@ -39,7 +39,7 @@ router.beforeEach(async (to, _, next) => { next() } } else { - if (whiteList.includes(to.path) || to.path.includes('/de-link')) { + if (whiteList.includes(to.path) || to.name === 'link') { next() } else { next('/login') // 否则全部重定向到登录页 diff --git a/core/core-frontend/src/router/index.ts b/core/core-frontend/src/router/index.ts index 0428ac6371..006703bae7 100644 --- a/core/core-frontend/src/router/index.ts +++ b/core/core-frontend/src/router/index.ts @@ -20,6 +20,13 @@ export const routes: AppRouteRecordRaw[] = [ } ] }, + { + path: '/notSupport', + name: 'notSupport', + hidden: true, + meta: {}, + component: () => import('@/views/mobile/panel/NotSupport.vue') + }, { path: '/login', name: 'login', diff --git a/core/core-frontend/src/store/modules/data-visualization/copy.ts b/core/core-frontend/src/store/modules/data-visualization/copy.ts index 61f1602246..f4d984b12a 100644 --- a/core/core-frontend/src/store/modules/data-visualization/copy.ts +++ b/core/core-frontend/src/store/modules/data-visualization/copy.ts @@ -115,10 +115,10 @@ export const copyStore = defineStore('copy', { newComponent.canvasId = 'canvas-main' } dvMainStore.addCopyComponent(newComponent, idMap, copyDataTemp.copyCanvasViewInfo) + if (dvMainStore.multiplexingStyleAdapt && copyDataTemp.copyFrom === 'multiplexing') { + adaptCurThemeCommonStyle(newComponent) + } if (dvInfo.value.type === 'dashboard') { - if (dvMainStore.multiplexingStyleAdapt && copyDataTemp.copyFrom === 'multiplexing') { - adaptCurThemeCommonStyle(newComponent) - } eventBus.emit('addDashboardItem-' + newComponent.canvasId, newComponent) } if (i === dataArray.length - 1) { diff --git a/core/core-frontend/src/store/modules/data-visualization/dvMain.ts b/core/core-frontend/src/store/modules/data-visualization/dvMain.ts index 601cfcbb2d..b167f53aa2 100644 --- a/core/core-frontend/src/store/modules/data-visualization/dvMain.ts +++ b/core/core-frontend/src/store/modules/data-visualization/dvMain.ts @@ -23,6 +23,7 @@ import { get, set } from 'lodash-es' export const dvMainStore = defineStore('dataVisualization', { state: () => { return { + fullscreenFlag: false, // 全屏启用标识 staticResourcePath: '/static-resource/', canvasCollapse: { defaultSide: false, @@ -446,6 +447,9 @@ export const dvMainStore = defineStore('dataVisualization', { this.curLinkageView = this.curComponent this.targetLinkageInfo = targetLinkageInfo }, + setFullscreenFlag(val) { + this.fullscreenFlag = val + }, removeViewFilter(componentId) { this.componentData = this.componentData.map(item => { const newItem = item diff --git a/core/core-frontend/src/style/index.less b/core/core-frontend/src/style/index.less index 4e79048f4c..1fb9324735 100644 --- a/core/core-frontend/src/style/index.less +++ b/core/core-frontend/src/style/index.less @@ -495,3 +495,16 @@ strong { top: calc(50% - 22px) !important; left: calc(50% - 40px) !important; } + +// 解决screenfull全屏时 部分嵌入到body中的组件(如 下来框 消息通知框等)被覆盖问题 +// 这里使用的方案为直接将body全屏 区间组件覆盖整个body +.de-screen-full{ + position:fixed !important; + z-index:200; + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100% !important; +} diff --git a/core/core-frontend/src/views/chart/components/editor/index.vue b/core/core-frontend/src/views/chart/components/editor/index.vue index deb66bc92d..c6701a389b 100644 --- a/core/core-frontend/src/views/chart/components/editor/index.vue +++ b/core/core-frontend/src/views/chart/components/editor/index.vue @@ -214,7 +214,7 @@ watch( { deep: true } ) const watchDs = () => { - getFields(props.view.tableId, props.view.id) + getFields(props.view.tableId, props.view.id, props.view.type) const nodeId = view.value['tableId'] if (!!nodeId) { cacheId = nodeId as unknown as string @@ -224,10 +224,10 @@ const watchDs = () => { curDatasetWeight.value = node.data.weight } } -const getFields = (id, chartId) => { +const getFields = (id, chartId, type) => { if (id && chartId) { fieldLoading.value = true - getFieldByDQ(id, chartId) + getFieldByDQ(id, chartId, { type: type }) .then(res => { state.dimension = (res.dimensionList as unknown as Field[]) || [] state.quota = (res.quotaList as unknown as Field[]) || [] @@ -1298,7 +1298,7 @@ const confirmEditCalc = () => { const obj = cloneDeep(calcEdit.value.fieldForm) setFieldDefaultValue(obj) saveField(obj).then(() => { - getFields(view.value.tableId, view.value.id) + getFields(view.value.tableId, view.value.id, view.value.type) closeEditCalc() }) } @@ -1314,7 +1314,7 @@ const chartFieldEdit = param => { state.currEditField.name = getFieldName(state.dimension.concat(state.quota), param.item.name) saveField(state.currEditField).then(() => { - getFields(view.value.tableId, view.value.id) + getFields(view.value.tableId, view.value.id, view.value.type) }) break case 'edit': @@ -1322,7 +1322,7 @@ const chartFieldEdit = param => { break case 'delete': deleteField(param.item?.id).then(() => { - getFields(view.value.tableId, view.value.id) + getFields(view.value.tableId, view.value.id, view.value.type) }) break } @@ -1538,7 +1538,7 @@ const copyChartFieldItem = id => { fieldLoading.value = true copyChartField(id, view.value.id) .then(() => { - getFields(view.value.tableId, view.value.id) + getFields(view.value.tableId, view.value.id, view.value.type) }) .catch(() => { fieldLoading.value = false @@ -1549,7 +1549,7 @@ const deleteChartFieldItem = id => { fieldLoading.value = true deleteChartField(id) .then(() => { - getFields(view.value.tableId, view.value.id) + getFields(view.value.tableId, view.value.id, view.value.type) }) .catch(() => { fieldLoading.value = false @@ -2570,7 +2570,7 @@ const deleteChartFieldItem = id => { { if (!['multiplexing', 'viewDialog'].includes(showPosition.value)) { let linkageCount = 0 let jumpCount = 0 - chartData.value?.fields?.forEach(item => { - const sourceInfo = view.value.id + '#' + item.id - if (nowPanelTrackInfo.value[sourceInfo]) { - linkageCount++ - } - if (nowPanelJumpInfo.value[sourceInfo]) { - jumpCount++ - } - }) + if (curView?.type?.includes('chart-mix')) { + chartData.value?.left?.fields?.forEach(item => { + const sourceInfo = view.value.id + '#' + item.id + if (nowPanelTrackInfo.value[sourceInfo]) { + linkageCount++ + } + if (nowPanelJumpInfo.value[sourceInfo]) { + jumpCount++ + } + }) + chartData.value?.right?.fields?.forEach(item => { + const sourceInfo = view.value.id + '#' + item.id + if (nowPanelTrackInfo.value[sourceInfo]) { + linkageCount++ + } + if (nowPanelJumpInfo.value[sourceInfo]) { + jumpCount++ + } + }) + } else { + chartData.value?.fields?.forEach(item => { + const sourceInfo = view.value.id + '#' + item.id + if (nowPanelTrackInfo.value[sourceInfo]) { + linkageCount++ + } + if (nowPanelJumpInfo.value[sourceInfo]) { + jumpCount++ + } + }) + } jumpCount && view.value?.jumpActive && (!mobileInPc.value || inMobile.value) && diff --git a/core/core-frontend/src/views/chart/components/views/components/ChartComponentS2.vue b/core/core-frontend/src/views/chart/components/views/components/ChartComponentS2.vue index 3a8c5930e9..8e27575788 100644 --- a/core/core-frontend/src/views/chart/components/views/components/ChartComponentS2.vue +++ b/core/core-frontend/src/views/chart/components/views/components/ChartComponentS2.vue @@ -469,8 +469,8 @@ const tabStyle = computed(() => [ const tablePageClass = computed(() => { return ( - ['#ffffff', '#A6A6A6FF'].includes( - canvasStyleData.value.component.seniorStyleSetting?.pagerColor + ['#ffffff', '#ffffffff', '#a6a6a6ff'].includes( + canvasStyleData.value.component.seniorStyleSetting?.pagerColor.toLowerCase() ) && 'table-page-info_dark' ) }) diff --git a/core/core-frontend/src/views/common/DeResourceTree.vue b/core/core-frontend/src/views/common/DeResourceTree.vue index d14853fd9b..c52c00f35a 100644 --- a/core/core-frontend/src/views/common/DeResourceTree.vue +++ b/core/core-frontend/src/views/common/DeResourceTree.vue @@ -133,6 +133,11 @@ const resourceTypeList = computed(() => { const menuList = computed(() => { const list = [ + { + label: '复制', + command: 'copy', + svgName: 'dv-copy-dark' + }, { label: '移动到', command: 'move', @@ -148,23 +153,13 @@ const menuList = computed(() => { command: 'delete', svgName: 'dv-delete', divided: true - }, - { - label: '编辑', - command: 'edit', - svgName: 'dv-edit' - }, - { - label: '复制', - command: 'copy', - svgName: 'dv-copy-dark' } ] return list }) const dvId = embeddedStore.dvId || router.currentRoute.value.query.dvId -if (dvId) { +if (dvId && showPosition.value === 'preview') { selectedNodeKey.value = dvId returnMounted.value = true } diff --git a/core/core-frontend/src/views/dashboard/DashboardPreviewShow.vue b/core/core-frontend/src/views/dashboard/DashboardPreviewShow.vue index f71d5894d0..9c1ef24cfd 100644 --- a/core/core-frontend/src/views/dashboard/DashboardPreviewShow.vue +++ b/core/core-frontend/src/views/dashboard/DashboardPreviewShow.vue @@ -12,7 +12,8 @@ import { useRequestStoreWithOut } from '@/store/modules/request' import { usePermissionStoreWithOut } from '@/store/modules/permission' import { useMoveLine } from '@/hooks/web/useMoveLine' import { Icon } from '@/components/icon-custom' -import { download2AppTemplate, downloadCanvas, downloadCanvas2 } from '@/utils/imgUtils' +import { download2AppTemplate, downloadCanvas2 } from '@/utils/imgUtils' +import { storeToRefs } from 'pinia' const dvMainStore = dvMainStoreWithOut() const previewCanvasContainer = ref(null) @@ -31,6 +32,8 @@ const state = reactive({ curPreviewGap: 0 }) +const { fullscreenFlag } = storeToRefs(dvMainStore) + const { width, node } = useMoveLine('DASHBOARD') const props = defineProps({ @@ -209,7 +212,12 @@ defineExpose({ @download="downloadH2" @downloadAsAppTemplate="downloadAsAppTemplate" /> -
+
{ dvMainStore.initCurMultiplexingComponents() curMultiplexTargetComponentsInfo.value = [] - componentData.value.forEach(item => { + componentData.value?.forEach(item => { curMultiplexTargetComponentsInfo.value.push({ id: item.id, label: item.label, @@ -138,7 +139,7 @@ onBeforeMount(() => { class="custom-tree" menu ref="multiplexInfoTree" - :empty-text="'暂无可用图表'" + :empty-text="'暂无可用组件'" :filter-node-method="filterNodeMethod" :data="curMultiplexTargetComponentsInfo" node-key="targetViewId" @@ -184,6 +185,7 @@ onBeforeMount(() => { :dv-info="dvInfo" :canvas-view-info="canvasViewInfo" /> +
diff --git a/core/core-frontend/src/views/data-visualization/PreviewHead.vue b/core/core-frontend/src/views/data-visualization/PreviewHead.vue index 77518a14b1..c3691e9f89 100644 --- a/core/core-frontend/src/views/data-visualization/PreviewHead.vue +++ b/core/core-frontend/src/views/data-visualization/PreviewHead.vue @@ -8,6 +8,7 @@ import { storeApi, storeStatusApi } from '@/api/visualization/dataVisualization' import { ref, watch, computed } from 'vue' import ShareVisualHead from '@/views/share/share/ShareVisualHead.vue' import { XpackComponent } from '@/components/plugin' +import DeFullscreen from '@/components/visualization/common/DeFullscreen.vue' const dvMainStore = dvMainStoreWithOut() const appStore = useAppStoreWithOut() const { dvInfo } = storeToRefs(dvMainStore) @@ -102,6 +103,7 @@ const initOpenHandler = newWindow => {
+