mirror of
https://github.com/dataease/dataease.git
synced 2025-02-24 03:22:56 +08:00
Merge pull request #13381 from dataease/pr@dev-v2_st
feat(查询组件): 下拉查询组件支持自定义排序 #12387
This commit is contained in:
commit
facf7a1477
@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
destroy-on-close
|
||||
append-to-body
|
||||
:title="$t('v_query.custom_sort')"
|
||||
v-model="dialogShow"
|
||||
class="custom-sort_filter"
|
||||
width="300px"
|
||||
>
|
||||
<div>
|
||||
<draggable :list="sortList" animation="300" class="drag-list">
|
||||
<template #item="{ element }">
|
||||
<span :key="element.name" class="item-dimension" :title="element">
|
||||
<el-icon size="20px">
|
||||
<Icon name="drag"><drag class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
<span class="item-span">
|
||||
{{ element }}
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeDialog">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="save">{{ $t('chart.confirm') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import drag from '@/assets/svg/drag.svg'
|
||||
import draggable from 'vuedraggable'
|
||||
import { ref, unref } from 'vue'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
|
||||
const sortList = ref([])
|
||||
const dialogShow = ref(false)
|
||||
const sortInit = list => {
|
||||
init(list)
|
||||
dialogShow.value = true
|
||||
}
|
||||
const init = list => {
|
||||
sortList.value = cloneDeep(list)
|
||||
}
|
||||
|
||||
const emits = defineEmits(['save'])
|
||||
const closeDialog = () => {
|
||||
dialogShow.value = false
|
||||
}
|
||||
const save = () => {
|
||||
emits('save', unref(sortList))
|
||||
closeDialog()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
sortInit
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.custom-sort_filter {
|
||||
.drag-list {
|
||||
overflow: auto;
|
||||
max-height: 800px;
|
||||
.item-dimension {
|
||||
padding: 2px;
|
||||
margin: 2px;
|
||||
border: solid 1px #eee;
|
||||
text-align: left;
|
||||
color: #606266;
|
||||
background-color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.item-icon {
|
||||
cursor: move;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.item-span {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.item-dimension + .item-dimension {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.item-dimension:hover {
|
||||
color: #1890ff;
|
||||
background: #e8f4ff;
|
||||
border-color: #a3d3ff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -23,6 +23,8 @@ import {
|
||||
unref
|
||||
} from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { enumValueObj } from '@/api/dataset'
|
||||
import CustomSortFilter from './CustomSortFilter.vue'
|
||||
import { addQueryCriteriaConfig } from './options'
|
||||
import { getCustomTime } from './time-format'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
@ -1755,6 +1757,35 @@ const getOptions = (id, component) => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleSortChange = () => {
|
||||
handleFieldChange()
|
||||
curComponent.value.sortList = []
|
||||
resetSort()
|
||||
}
|
||||
|
||||
const resetSort = () => {
|
||||
if (sortComputed.value) {
|
||||
curComponent.value.sort = ''
|
||||
}
|
||||
}
|
||||
|
||||
const customSortFilterRef = ref()
|
||||
|
||||
const sortSave = list => {
|
||||
curComponent.value.sortList = cloneDeep(list)
|
||||
}
|
||||
|
||||
const handleCustomClick = async () => {
|
||||
if (sortComputed.value || curComponent.value.sort !== 'customSort') return
|
||||
const list = await enumValueObj({ queryId: curComponent.value.sortId, searchText: '' })
|
||||
customSortFilterRef.value.sortInit([...new Set(list.map(ele => ele[curComponent.value.sortId]))])
|
||||
}
|
||||
|
||||
const sortComputed = computed(() => {
|
||||
const { sortId, displayId } = curComponent.value
|
||||
return sortId && displayId && sortId !== displayId
|
||||
})
|
||||
|
||||
const treeDialog = ref()
|
||||
const startTreeDesign = () => {
|
||||
const [comId] = curComponent.value.checkedFields
|
||||
@ -2804,6 +2835,7 @@ defineExpose({
|
||||
:placeholder="t('v_query.display_field')"
|
||||
class="search-field"
|
||||
v-model="curComponent.displayId"
|
||||
@change="resetSort"
|
||||
>
|
||||
<template v-if="curComponent.displayId" #prefix>
|
||||
<el-icon>
|
||||
@ -2865,7 +2897,7 @@ defineExpose({
|
||||
:placeholder="t('v_query.the_sorting_field')"
|
||||
v-model="curComponent.sortId"
|
||||
class="sort-field"
|
||||
@change="handleFieldChange"
|
||||
@change="handleSortChange"
|
||||
>
|
||||
<template v-if="curComponent.sortId" #prefix>
|
||||
<el-icon>
|
||||
@ -2919,6 +2951,13 @@ defineExpose({
|
||||
>
|
||||
<el-option :label="t('chart.asc')" value="asc" />
|
||||
<el-option :label="t('chart.desc')" value="desc" />
|
||||
<el-option
|
||||
@click="handleCustomClick"
|
||||
:title="sortComputed ? $t('v_query.display_sort') : ''"
|
||||
:disabled="sortComputed"
|
||||
:label="t('v_query.custom_sort')"
|
||||
value="customSort"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
@ -3081,6 +3120,7 @@ defineExpose({
|
||||
<el-button type="primary" @click="numTypeChange">{{ t('dataset.confirm') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<customSortFilter ref="customSortFilterRef" @save="sortSave"></customSortFilter>
|
||||
<CascadeDialog @saveCascade="saveCascade" ref="cascadeDialog"></CascadeDialog>
|
||||
</template>
|
||||
|
||||
|
@ -26,6 +26,7 @@ interface SelectConfig {
|
||||
displayType: string
|
||||
showEmpty: boolean
|
||||
id: string
|
||||
sortList?: string[]
|
||||
queryConditionWidth: number
|
||||
placeholder: string
|
||||
resultMode: number
|
||||
@ -287,6 +288,14 @@ const setOldMapValue = arr => {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
const customSort = () => {
|
||||
if (config.value.sortList?.length && config.value.sort === 'customSort') {
|
||||
options.value.sort(
|
||||
(a, b) => config.value.sortList.indexOf(a.value) - config.value.sortList.indexOf(b.value)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const handleFieldIdChange = (val: EnumValue) => {
|
||||
loading.value = true
|
||||
enumValueObj(val)
|
||||
@ -313,6 +322,7 @@ const handleFieldIdChange = (val: EnumValue) => {
|
||||
checked: oldArr.includes(ele)
|
||||
}
|
||||
})
|
||||
customSort()
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
@ -348,16 +358,6 @@ const handleFieldIdChange = (val: EnumValue) => {
|
||||
}
|
||||
|
||||
const visible = ref(false)
|
||||
const visibleChange = (val: boolean) => {
|
||||
setTimeout(() => {
|
||||
visible.value = !val
|
||||
if (!val) {
|
||||
isFromRemote.value = false
|
||||
searchText.value = ''
|
||||
remoteMethod('')
|
||||
}
|
||||
}, 50)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => config.value.showEmpty,
|
||||
@ -449,6 +449,11 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
watch([() => config.value.sortList], val => {
|
||||
if (!val?.length || config.value.sort !== 'customSort') return
|
||||
customSort()
|
||||
})
|
||||
|
||||
watch(
|
||||
() => config.value.optionValueSource,
|
||||
(valNew, newOld) => {
|
||||
@ -474,16 +479,6 @@ watch(
|
||||
|
||||
const searchText = ref('')
|
||||
const isFromRemote = ref(false)
|
||||
const clear = () => {
|
||||
remoteMethod('')
|
||||
}
|
||||
|
||||
const remoteMethod = (query: string) => {
|
||||
if (config.value.optionValueSource !== 1) return
|
||||
isFromRemote.value = true
|
||||
searchText.value = query
|
||||
debounceOptions(1)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => config.value.valueSource,
|
||||
@ -520,7 +515,7 @@ const setOptions = (num: number) => {
|
||||
handleFieldIdChange({
|
||||
queryId: field.id,
|
||||
displayId: displayId || field.id,
|
||||
sort,
|
||||
sort: sort === 'customSort' ? '' : sort,
|
||||
sortId,
|
||||
resultMode: config.value.resultMode || 0,
|
||||
searchText: searchText.value,
|
||||
@ -612,7 +607,6 @@ defineExpose({
|
||||
v-loading="loading"
|
||||
filterable
|
||||
@change="handleValueChange"
|
||||
@visible-change="visibleChange"
|
||||
:popper-class="
|
||||
visible ? 'load-select filter-select-popper_class' : 'filter-select-popper_class'
|
||||
"
|
||||
@ -635,9 +629,7 @@ defineExpose({
|
||||
ref="single"
|
||||
:style="selectStyle"
|
||||
filterable
|
||||
@clear="clear"
|
||||
radio
|
||||
@visible-change="visibleChange"
|
||||
:popper-class="
|
||||
visible ? 'load-select filter-select-popper_class' : 'filter-select-popper_class'
|
||||
"
|
||||
|
@ -2564,6 +2564,8 @@ export default {
|
||||
variable_mgm: '参数设置'
|
||||
},
|
||||
v_query: {
|
||||
display_sort: '显示字段和排序字段不一致,无法进行自定义排序',
|
||||
custom_sort: '自定义排序',
|
||||
msg_center: '消息中心',
|
||||
to_be_filled: '待填报',
|
||||
the_minimum_value: '数值区间最大值必须大于最小值',
|
||||
|
Loading…
Reference in New Issue
Block a user