From 3b8febc016b6f26c50459201f3c3f092f82a8484 Mon Sep 17 00:00:00 2001 From: dataeaseShu Date: Mon, 17 Mar 2025 16:50:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=9F=A5=E8=AF=A2=E7=BB=84=E4=BB=B6):=20?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=BB=84=E4=BB=B6=E4=B8=8B=E6=8B=89=E6=A0=91?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom-component/v-query/Component.vue | 44 +- .../v-query/QueryConditionConfiguration.vue | 402 +++++++++++------- .../src/custom-component/v-query/Tree.vue | 18 +- .../v-query/TreeFieldDialog.vue | 9 +- core/core-frontend/src/hooks/web/useFilter.ts | 46 +- core/core-frontend/src/locales/en.ts | 4 + core/core-frontend/src/locales/tw.ts | 4 + core/core-frontend/src/locales/zh-CN.ts | 4 + 8 files changed, 324 insertions(+), 207 deletions(-) diff --git a/core/core-frontend/src/custom-component/v-query/Component.vue b/core/core-frontend/src/custom-component/v-query/Component.vue index 2670617881..3b5975a713 100644 --- a/core/core-frontend/src/custom-component/v-query/Component.vue +++ b/core/core-frontend/src/custom-component/v-query/Component.vue @@ -3,6 +3,7 @@ import icon_edit_outlined from '@/assets/svg/icon_edit_outlined.svg' import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg' import eventBus from '@/utils/eventBus' import { isISOMobile, isMobile } from '@/utils/utils' +import { cloneDeep } from 'lodash-es' import { ElMessage } from 'element-plus-secondary' import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot' import QueryConditionConfiguration from './QueryConditionConfiguration.vue' @@ -251,6 +252,27 @@ const releaseSelect = id => { unMountSelect.value = unMountSelect.value.filter(ele => ele !== id) } +const getKeyList = next => { + let checkedFieldsMapArr = Object.entries(next.checkedFieldsMap) + if (next.displayType === '9') { + checkedFieldsMapArr = ( + next.treeCheckedList?.length + ? next.treeCheckedList + : next.treeFieldList.map(() => { + return { + checkedFields: [...next.checkedFields], + checkedFieldsMap: cloneDeep(next.checkedFieldsMap) + } + }) + ) + .map(item => Object.entries(item.checkedFieldsMap)) + .flat() + } + return checkedFieldsMapArr + .filter(ele => next.checkedFields.includes(ele[0])) + .filter(ele => !!ele[1]) + .map(ele => ele[0]) +} const queryDataForId = id => { let requiredName = '' let numName = '' @@ -302,10 +324,8 @@ const queryDataForId = id => { requiredName = next.name } } - const keyList = Object.entries(next.checkedFieldsMap) - .filter(ele => next.checkedFields.includes(ele[0])) - .filter(ele => !!ele[1]) - .map(ele => ele[0]) + + const keyList = getKeyList(next) pre = [...new Set([...keyList, ...pre])] return pre }, []) @@ -490,11 +510,7 @@ const resetData = () => { } }) }) - - const keyList = Object.entries(next.checkedFieldsMap) - .filter(ele => next.checkedFields.includes(ele[0])) - .filter(ele => !!ele[1]) - .map(ele => ele[0]) + const keyList = getKeyList(next) pre = [...new Set([...keyList, ...pre])] return pre }, []) @@ -525,10 +541,7 @@ const clearData = () => { next.numValueEnd = undefined next.numValueStart = undefined } - const keyList = Object.entries(next.checkedFieldsMap) - .filter(ele => next.checkedFields.includes(ele[0])) - .filter(ele => !!ele[1]) - .map(ele => ele[0]) + const keyList = getKeyList(next) pre = [...new Set([...keyList, ...pre])] return pre }, []) @@ -607,10 +620,7 @@ const queryData = () => { requiredName = next.name } } - const keyList = Object.entries(next.checkedFieldsMap) - .filter(ele => next.checkedFields.includes(ele[0])) - .filter(ele => !!ele[1]) - .map(ele => ele[0]) + const keyList = getKeyList(next) pre = [...new Set([...keyList, ...pre])] return pre }, []) 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 993bed298e..fa9c44cf72 100644 --- a/core/core-frontend/src/custom-component/v-query/QueryConditionConfiguration.vue +++ b/core/core-frontend/src/custom-component/v-query/QueryConditionConfiguration.vue @@ -85,7 +85,6 @@ const activeConditionForRename = reactive({ }) const datasetMap = {} const snapshotStore = snapshotStoreWithOut() - const dfsComponentData = () => { let arr = componentData.value.filter( com => !['VQuery', 'DeTabs'].includes(com.innerType) && com.component !== 'Group' @@ -273,22 +272,6 @@ const showTypeError = computed(() => { }) }) -const showDatasetError = computed(() => { - if (!curComponent.value || curComponent.value.displayType !== '9') return false - if (!curComponent.value.checkedFields?.length) return false - if (!fields.value?.length) return false - let displayField = null - return curComponent.value.checkedFields.some(id => { - const arr = fields.value.find(itx => itx.componentId === id) - const field = arr.id - if (!field) return false - if (displayField === null) { - displayField = field - return false - } - return displayField !== field - }) -}) const typeList = [ { label: t('data_fill.rename'), @@ -306,52 +289,6 @@ const handleCheckAllChange = (val: boolean) => { val && setSameId() } -const setTreeDefault = () => { - if (!!curComponent.value.checkedFields.length) { - let checkId = '' - let tableId = '' - let comId = '' - fields.value.forEach(ele => { - if ( - curComponent.value.checkedFields.includes(ele.componentId) && - curComponent.value.checkedFieldsMap[ele.componentId] && - !checkId - ) { - checkId = curComponent.value.checkedFieldsMap[ele.componentId] - comId = ele.componentId - tableId = datasetFieldList.value.find(itx => itx.id === ele.componentId)?.tableId - } - }) - if (checkId && tableId) { - const componentObj = fields.value.find(ele => ele.componentId === comId) - const fieldArr = - curComponent.value.optionValueSource === 0 - ? componentObj?.fields?.dimensionList - : (fields.value.find(itx => itx.id === tableId) || {}).fields?.dimensionList - fields.value.forEach(ele => { - if (curComponent.value.checkedFields.includes(ele.componentId)) { - if (datasetFieldList.value.find(itx => itx.id === ele.componentId)?.tableId === tableId) { - curComponent.value.checkedFieldsMap[ele.componentId] = checkId - } - } - }) - const fieldObj = fieldArr.find(element => element.id === checkId) - if (!!curComponent.value.treeFieldList.length) { - const [fir] = curComponent.value.treeFieldList - if (fir && fir.field !== checkId) { - const [top] = curComponent.value.treeFieldList || [] - if (top?.id === fieldObj.id) return - - curComponent.value.treeFieldList = [fieldObj] - } - } else if (fieldObj) { - const [top] = curComponent.value.treeFieldList || [] - if (top?.id === fieldObj.id) return - curComponent.value.treeFieldList = [fieldObj] - } - } - } -} const handleCheckedFieldsChange = (value: string[]) => { handleDialogClick() const checkedCount = value.length @@ -398,10 +335,6 @@ const handleCheckedFieldsChangeTree = (value: string[]) => { isIndeterminate.value = checkedCount > 0 && checkedCount < fields.value.length setSameId() if (curComponent.value.displayType === '8') return - if (curComponent.value.displayType === '9') { - setTreeDefault() - return - } setType() } @@ -754,9 +687,6 @@ const setParameters = field => { if (notChangeType) return setType() - if (curComponent.value.displayType === '9') { - setTreeDefault() - } } const setType = () => { @@ -817,10 +747,6 @@ const setTypeChange = () => { ) { curComponent.value.timeGranularityMultiple = curComponent.value.timeGranularity } - - if (curComponent.value.displayType === '9') { - setTreeDefault() - } }) } @@ -991,6 +917,14 @@ const handleDatasetChange = () => { getOptions(curComponent.value.dataset.id, curComponent.value) } +const handleDatasetTreeChange = () => { + curComponent.value.treeFieldList = [] + curComponent.value.treeCheckedList = [] + relationshipChartIndex.value = 0 + curComponent.value.oldTreeLoad = true + getOptions(curComponent.value.treeDatasetId, curComponent.value) +} + const handleFieldChange = () => { if (!curComponent.value.defaultValueCheck) return curComponent.value.defaultValue = curComponent.value.multiple ? [] : undefined @@ -1221,6 +1155,30 @@ const validate = () => { return true } + if (ele.displayType === '9') { + if (!ele.treeDatasetId) { + ElMessage.error(t('data_set.dataset_cannot_be')) + return true + } + + if (!ele.treeFieldList?.length) { + ElMessage.error(t('common.tree_structure')) + return true + } + if ( + ele.treeCheckedList + ?.slice(0, ele.treeFieldList.length) + .some( + item => + !item.checkedFields?.length || + item.checkedFields.some(itx => !item.checkedFieldsMap[itx]) + ) + ) { + ElMessage.error(t('v_query.be_linked_first')) + return true + } + } + if (ele.displayType === '22' && ele.defaultValueCheck) { ele.numValueEnd = ele.defaultNumValueEnd ele.numValueStart = ele.defaultNumValueStart @@ -1553,12 +1511,16 @@ const confirmValueSource = () => { } const setCondition = (queryId: string) => { - conditions.value = cloneDeep(props.queryElement.propValue) || [] + conditions.value = (cloneDeep(props.queryElement.propValue) || []).map(ele => + parameterCompletion(ele) + ) init(queryId) } const setConditionOut = () => { - conditions.value = cloneDeep(props.queryElement.propValue) || [] + conditions.value = (cloneDeep(props.queryElement.propValue) || []).map(ele => + parameterCompletion(ele) + ) addQueryCriteria() init(conditions.value[conditions.value.length - 1].id) } @@ -1636,7 +1598,7 @@ const weightlessness = () => { valueSource.value = Array.from(new Set(valueSource.value)) } -const parameterCompletion = () => { +const parameterCompletion = ele => { const attributes = { timeType: 'fixed', hideConditionSwitching: false, @@ -1664,6 +1626,7 @@ const parameterCompletion = () => { timeNumRange: 0, relativeToCurrentTypeRange: 'year', aroundRange: 'f', + treeDatasetId: '', displayId: '', sortId: '', sort: 'asc', @@ -1688,18 +1651,26 @@ const parameterCompletion = () => { relativeToCurrentTypeRange: 'year', aroundRange: 'f' }, + oldTreeLoad: false, + treeCheckedList: [], treeFieldList: [] } Object.entries(attributes).forEach(([key, val]) => { - curComponent.value[key] ?? (curComponent.value[key] = val) + ele[key] ?? (ele[key] = val) }) - if (!curComponent.value.timeRange.relativeToCurrentRange) { - curComponent.value.timeRange.relativeToCurrentRange = 'custom' + if (!ele.treeDatasetId) { + ele.treeDatasetId = ele.dataset.id } + + if (!ele.timeRange.relativeToCurrentRange) { + ele.timeRange.relativeToCurrentRange = 'custom' + } + + return ele } -const handleCondition = item => { +const handleCondition = (item, idx = 0) => { handleDialogClick() if (activeConditionForRename.id) return activeCondition.value = item.id @@ -1791,8 +1762,10 @@ const handleCondition = item => { if (!valueSource.value.length) { valueSource.value.push('') } - parameterCompletion() nextTick(() => { + if (curComponent.value.displayType === '9') { + handleRelationshipChart(idx) + } curComponent.value.showError = showError.value curComponent.value.auto && (document.querySelector('.chart-field').scrollTop = 0) }) @@ -1839,14 +1812,7 @@ const sortComputed = computed(() => { const treeDialog = ref() const startTreeDesign = () => { - const [comId] = curComponent.value.checkedFields - const componentObj = fields.value.find(ele => ele.componentId === comId) - treeDialog.value.init( - componentObj?.fields?.dimensionList.filter( - ele => ele.deType === +curComponent.value.field.deType - ), - curComponent.value.treeFieldList - ) + treeDialog.value.init(curComponent.value.dataset.fields, curComponent.value.treeFieldList) } const saveTree = arr => { curComponent.value.treeFieldList = arr @@ -1859,23 +1825,9 @@ const showError = computed(() => { if (!checkedFields.length || !arr.length) { return true } - if ([1, 7, 8, 22].includes(+displayType)) { + if ([1, 7, 8, 22, 9].includes(+displayType)) { return false } - - if (displayType === '9') { - let displayField = null - return checkedFields.some(id => { - const arr = (fields.value || []).find(itx => itx.componentId === id) - const field = arr?.id - if (!field) return false - if (displayField === null) { - displayField = field - return false - } - return displayField !== field - }) - } return (optionValueSource === 1 && !field.id) || (optionValueSource === 2 && !valueSource.length) }) const handleDialogClick = () => { @@ -2102,6 +2054,48 @@ watch( const setRenameInput = val => { renameInput.value.push(val) } +const relationshipChartIndex = ref(0) +const notCurrentEle = (ele, index) => { + if (activeCondition.value !== ele.id) { + handleCondition(ele, index) + } else { + handleRelationshipChart(index) + } +} +const handleRelationshipChart = index => { + if (curComponent.value.treeCheckedList?.length) { + curComponent.value.treeCheckedList[relationshipChartIndex.value] = { + checkedFields: [...curComponent.value.checkedFields], + checkedFieldsMap: cloneDeep(curComponent.value.checkedFieldsMap) + } + } + relationshipChartIndex.value = index + if (!curComponent.value?.treeCheckedList?.length && !curComponent.value.oldTreeLoad) { + curComponent.value.treeCheckedList = curComponent.value.treeFieldList.map(ele => { + return { + checkedFields: [...curComponent.value.checkedFields], + checkedFieldsMap: curComponent.value.checkedFields.reduce((pre, next) => { + pre[next] = ele.id + return pre + }, {}) + } + }) + } else if (!curComponent.value?.treeCheckedList?.length && curComponent.value.oldTreeLoad) { + curComponent.value.treeCheckedList = curComponent.value.treeFieldList.map(() => { + return { + checkedFields: [...curComponent.value.checkedFields], + checkedFieldsMap: cloneDeep(curComponent.value.checkedFieldsMap) + } + }) + } + if (!curComponent.value?.treeCheckedList[index]) return + const { checkedFields, checkedFieldsMap } = curComponent.value?.treeCheckedList[index] + curComponent.value.checkedFields = checkedFields + curComponent.value.checkedFieldsMap = checkedFieldsMap + const checkedCount = checkedFields?.length + checkAll.value = checkedCount === fields.value?.length + isIndeterminate.value = checkedCount > 0 && checkedCount < fields.value?.length +} const addOperation = (cmd, condition, index) => { switch (cmd) { @@ -2157,7 +2151,7 @@ const renameInputBlur = () => { } const addQueryCriteria = () => { - conditions.value.push(addQueryCriteriaConfig()) + conditions.value.push(parameterCompletion(addQueryCriteriaConfig())) } const addQueryCriteriaAndSelect = () => { @@ -2202,48 +2196,77 @@ defineExpose({ :key="element.id" @dblclick.stop="addOperation('rename', element, index)" @click.stop="handleCondition(element)" - class="list-item_primary" - :class="element.id === activeCondition && 'active'" + class="list-item_box" + :style="{ + marginBottom: element.treeFieldList + ? element.treeFieldList.slice(1).length * 40 + 'px' + : 0 + }" > - - - -
- + + + +
+ + + + {{ element.name }} +
+
+ + + + + + + +
+
+ +
+
+ @@ -2633,13 +2656,19 @@ defineExpose({
{{ t('v_query.query_condition_configuration') }}
@@ -2717,6 +2746,42 @@ defineExpose({
+
+
+ {{ t('copilot.pls_choose_dataset') }} +
+
+ + + +
+
{{ t('v_query.tree_structure_design') }} @@ -2726,7 +2791,7 @@ defineExpose({ @click="startTreeDesign" >
@@ -2742,7 +2807,7 @@ defineExpose({ > - - {{ ele.name }} + {{ ele.name }} + {{ + t('common.associated_chart_first') + }} + + + {{ t('common.associated_chart') }} + +
- + @@ -3169,8 +3242,11 @@ defineExpose({
-
- +
+
@@ -3341,6 +3417,17 @@ defineExpose({ color: var(--ed-color-primary); } } + + .list-item_box { + width: 100%; + position: relative; + .list-tree_primary { + position: absolute; + left: 0; + padding: 8px 32px; + width: 100%; + } + } .list-item_primary { border-radius: 0; position: relative; @@ -3549,7 +3636,7 @@ defineExpose({ padding: 16px; box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12); - .ed-button { + .start-tree_design { position: absolute; left: 50%; top: 50%; @@ -3573,6 +3660,11 @@ defineExpose({ .field-tree_name { margin-left: 8px; + max-width: 100px; + } + + .field-relationship_chart { + margin-left: 8px; } } } diff --git a/core/core-frontend/src/custom-component/v-query/Tree.vue b/core/core-frontend/src/custom-component/v-query/Tree.vue index 2ec2908f6d..f095051e19 100644 --- a/core/core-frontend/src/custom-component/v-query/Tree.vue +++ b/core/core-frontend/src/custom-component/v-query/Tree.vue @@ -147,23 +147,6 @@ onMounted(() => { }, 0) }) -watch( - () => config.value.selectValue, - val => { - if (props.isConfig) return - if (config.value.multiple) { - treeValue.value = Array.isArray(val) ? [...val] : val - } - nextTick(() => { - multiple.value = config.value.multiple - if (!config.value.multiple) { - treeValue.value = Array.isArray(config.value.selectValue) - ? [...config.value.selectValue] - : config.value.selectValue - } - }) - } -) const showWholePath = ref(false) watch( () => config.value.multiple, @@ -253,6 +236,7 @@ const selectStyle = computed(() => { :render-after-expand="false" show-checkbox showBtn + @change="handleValueChange" :placeholder="placeholderText" collapse-tags :filter-node-method="filterMethod" diff --git a/core/core-frontend/src/custom-component/v-query/TreeFieldDialog.vue b/core/core-frontend/src/custom-component/v-query/TreeFieldDialog.vue index ff7228a48d..f26dba7046 100644 --- a/core/core-frontend/src/custom-component/v-query/TreeFieldDialog.vue +++ b/core/core-frontend/src/custom-component/v-query/TreeFieldDialog.vue @@ -102,12 +102,7 @@ defineExpose({
{{ t('visualization.level') }}{{ indexNumCascade[idx] }}
- +
- +