Merge pull request #8475 from dataease/pr@dev-v2_time_range

feat(查询组件): 日期筛选组件可设置查询的起始日期 #6005
This commit is contained in:
dataeaseShu 2024-03-13 15:42:30 +08:00 committed by GitHub
commit f3bf34375a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 196 additions and 32 deletions

View File

@ -24,7 +24,7 @@
"axios": "^1.3.3",
"crypto-js": "^4.1.1",
"dayjs": "^1.11.9",
"element-plus-secondary": "^0.5.2",
"element-plus-secondary": "^0.5.3",
"element-resize-detector": "^1.2.4",
"file-saver": "^2.0.5",
"html-to-image": "^1.11.11",

View File

@ -1,9 +1,11 @@
getLastStart
<script lang="ts" setup>
import { ref, reactive, nextTick, computed, shallowRef, toRefs, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { addQueryCriteriaConfig } from './options'
import { getCustomTime } from './time-format'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { getThisStart, getLastStart, getAround } from './time-format-dayjs'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import { useI18n } from '@/hooks/web/useI18n'
import { fieldType } from '@/utils/attr'
@ -20,6 +22,8 @@ import { getDatasetTree } from '@/api/dataset'
import { Tree } from '@/views/visualized/data/dataset/form/CreatDsGroup.vue'
import draggable from 'vuedraggable'
import RangeFilterTime from './RangeFilterTime.vue'
import type { ManipulateType } from 'dayjs'
import dayjs from 'dayjs'
const { t } = useI18n()
const dvMainStore = dvMainStoreWithOut()
@ -268,6 +272,102 @@ const multipleChange = (val: boolean, isMultipleChange = false) => {
curComponent.value.multiple = val
}
const isInRange = (ele, startWindowTime, timeStamp) => {
const {
intervalType,
regularOrTrends,
regularOrTrendsValue,
relativeToCurrent,
timeNum,
relativeToCurrentType,
around,
dynamicWindow,
maximumSingleQuery,
timeNumRange,
relativeToCurrentTypeRange,
aroundRange
} = ele.timeRange || {}
let isDynamicWindowTime = false
const noTime = ele.timeGranularityMultiple.split('time').join('').split('range')[0]
const queryTimeType = noTime === 'date' ? 'day' : (noTime as ManipulateType)
if (startWindowTime && dynamicWindow) {
isDynamicWindowTime =
dayjs(startWindowTime)
.add(maximumSingleQuery, queryTimeType)
.startOf(queryTimeType)
.valueOf() -
1000 <
timeStamp
}
if (intervalType === 'none') {
if (dynamicWindow) return isDynamicWindowTime
return false
}
let startTime
if (relativeToCurrent === 'custom') {
startTime = getAround(relativeToCurrentType, around === 'f' ? 'subtract' : 'add', timeNum)
} else {
switch (relativeToCurrent) {
case 'thisYear':
startTime = getThisStart('year')
break
case 'lastYear':
startTime = getLastStart('year')
break
case 'thisMonth':
startTime = getThisStart('month')
break
case 'lastMonth':
startTime = getLastStart('month')
break
case 'today':
startTime = getThisStart('day')
break
case 'yesterday':
startTime = getLastStart('day')
break
case 'monthBeginning':
startTime = getThisStart('month')
break
case 'yearBeginning':
startTime = getThisStart('year')
break
default:
break
}
}
const startValue = regularOrTrends === 'fixed' ? regularOrTrendsValue : startTime
if (intervalType === 'start') {
return startWindowTime < +new Date(startValue) || isDynamicWindowTime
}
if (intervalType === 'end') {
return timeStamp > +new Date(startValue) || isDynamicWindowTime
}
if (intervalType === 'timeInterval') {
const startTime =
regularOrTrends === 'fixed'
? regularOrTrendsValue[0]
: getAround(relativeToCurrentType, around === 'f' ? 'subtract' : 'add', timeNum)
const endTime =
regularOrTrends === 'fixed'
? regularOrTrendsValue[1]
: getAround(
relativeToCurrentTypeRange,
aroundRange === 'f' ? 'subtract' : 'add',
timeNumRange
)
return (
startWindowTime < +new Date(startTime) - 1000 ||
timeStamp > +new Date(endTime) ||
isDynamicWindowTime
)
}
}
const validate = () => {
return conditions.value.some(ele => {
if (ele.auto) return false
@ -292,8 +392,13 @@ const validate = () => {
}
if (+ele.displayType === 7) {
if (!ele.defaultValueCheck) {
return false
if (!ele.defaultValueCheck) return false
if (ele.timeType === 'fixed') {
const [s, e] = ele.defaultValue || []
if (!s || !e) {
ElMessage.error('默认时间不能为空!')
return true
}
}
const {
timeNum,
@ -305,31 +410,53 @@ const validate = () => {
timeNumRange,
relativeToCurrentTypeRange,
aroundRange,
arbitraryTimeRange
arbitraryTimeRange,
timeType
} = ele
const startTime = getCustomTime(
timeNum,
relativeToCurrentType,
timeGranularity,
around,
arbitraryTime,
timeGranularityMultiple,
'start-config'
)
const endTime = getCustomTime(
timeNumRange,
relativeToCurrentTypeRange,
timeGranularity,
aroundRange,
arbitraryTimeRange,
timeGranularityMultiple,
'end-config'
)
const startTime =
timeType === 'dynamic'
? getCustomTime(
timeNum,
relativeToCurrentType,
timeGranularity,
around,
arbitraryTime,
timeGranularityMultiple,
'start-config'
)
: new Date(ele.defaultValue[0])
const endTime =
timeType === 'dynamic'
? getCustomTime(
timeNumRange,
relativeToCurrentTypeRange,
timeGranularity,
aroundRange,
arbitraryTimeRange,
timeGranularityMultiple,
'end-config'
)
: new Date(ele.defaultValue[1])
if (+startTime > +endTime) {
ElMessage.error('结束时间必须大于开始时间!')
return true
}
if (!ele.setTimeRange) return false
if (
isInRange(
ele,
timeGranularityMultiple.includes('time')
? dayjs(+startTime).startOf('day').valueOf()
: +startTime,
timeGranularityMultiple.includes('time')
? dayjs(+endTime).startOf('day').valueOf()
: +endTime
)
) {
ElMessage.error('默认值必须在时间筛选范围内!')
return true
}
return false
}

View File

@ -88,6 +88,10 @@ const relativeToCurrentTypeList = computed(() => {
}
].slice(0, index)
})
const relativeToCurrentTypeListTips = computed(() => {
return (relativeToCurrentTypeList.value[relativeToCurrentTypeList.value.length - 1] || {}).label
})
const relativeToCurrentList = computed(() => {
let list = []
if (!timeRange.value) return list
@ -315,7 +319,7 @@ const relativeToCurrentList = computed(() => {
:min="1"
controls-position="right"
/>
{{ relativeToCurrentTypeListTips }}
</div>
</div>
</div>

View File

@ -1,9 +1,10 @@
<script lang="ts" setup>
import { toRefs, PropType, ref, onBeforeMount, watch, nextTick, computed } from 'vue'
import { Calendar } from '@element-plus/icons-vue'
import { toRefs, PropType, ref, onBeforeMount, watch, nextTick, computed, h } from 'vue'
import { type DatePickType } from 'element-plus-secondary'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import type { ManipulateType } from 'dayjs'
import { type TimeRange } from './time-format'
import dayjs from 'dayjs'
import { getThisStart, getLastStart, getAround } from './time-format-dayjs'
import VanPopup from 'vant/es/popup'
import VanDatePicker from 'vant/es/date-picker'
@ -13,6 +14,7 @@ import 'vant/es/popup/style'
import 'vant/es/date-picker/style'
import 'vant/es/picker-group/style'
import 'vant/es/time-picker/style'
import { Icon } from '@/components/icon-custom'
interface SelectConfig {
selectValue: any
@ -63,7 +65,7 @@ const props = defineProps({
const selectValue = ref()
const multiple = ref(false)
const dvMainStore = dvMainStoreWithOut()
const calendar = h(Icon, { name: 'icon_calendar_outlined' })
const { config } = toRefs(props)
const minDate = new Date('1970/1/1')
const maxDate = new Date('2100/1/1')
@ -181,6 +183,19 @@ const getIndex = () => {
const index = ['year', 'month', 'date'].findIndex(ele => type.includes(ele))
return index
}
const startWindowTime = ref(0)
const calendarChange = val => {
startWindowTime.value = +new Date(val[0])
}
const visibleChange = () => {
startWindowTime.value = 0
}
const queryTimeType = computed(() => {
const noTime = config.value.timeGranularityMultiple.split('time').join('').split('range')[0]
return noTime === 'date' ? 'day' : (noTime as ManipulateType)
})
const disabledDate = val => {
const timeStamp = +new Date(val)
@ -195,11 +210,24 @@ const disabledDate = val => {
timeNum,
relativeToCurrentType,
around,
dynamicWindow,
maximumSingleQuery,
timeNumRange,
relativeToCurrentTypeRange,
aroundRange
} = config.value.timeRange || {}
let isDynamicWindowTime = false
if (startWindowTime.value && dynamicWindow) {
isDynamicWindowTime =
dayjs(startWindowTime.value)
.add(maximumSingleQuery, queryTimeType.value)
.startOf(queryTimeType.value)
.valueOf() -
1000 <
timeStamp
}
if (intervalType === 'none') {
if (dynamicWindow) return isDynamicWindowTime
return false
}
let startTime
@ -239,11 +267,11 @@ const disabledDate = val => {
const startValue = regularOrTrends === 'fixed' ? regularOrTrendsValue : startTime
if (intervalType === 'start') {
return timeStamp < +new Date(startValue)
return timeStamp < +new Date(startValue) || isDynamicWindowTime
}
if (intervalType === 'end') {
return timeStamp > +new Date(startValue)
return timeStamp > +new Date(startValue) || isDynamicWindowTime
}
if (intervalType === 'timeInterval') {
@ -259,7 +287,11 @@ const disabledDate = val => {
aroundRange === 'f' ? 'subtract' : 'add',
timeNumRange
)
return timeStamp < +new Date(startTime) - 1000 || timeStamp > +new Date(endTime)
return (
timeStamp < +new Date(startTime) - 1000 ||
timeStamp > +new Date(endTime) ||
isDynamicWindowTime
)
}
}
@ -341,11 +373,13 @@ const formatDate = computed(() => {
:key="config.timeGranularityMultiple"
:type="config.timeGranularityMultiple"
:style="selectStyle"
@visible-change="visibleChange"
:disabled-date="disabledDate"
@calendar-change="calendarChange"
:format="formatDate"
:prefix-icon="calendar"
v-if="multiple"
@change="handleValueChange"
:prefix-icon="Calendar"
:range-separator="$t('cron.to')"
:start-placeholder="$t('datasource.start_time')"
:end-placeholder="$t('datasource.end_time')"
@ -354,9 +388,8 @@ const formatDate = computed(() => {
v-else
v-model="selectValue"
:type="config.timeGranularity"
:disabled-date="disabledDate"
:prefix-icon="calendar"
:style="selectStyle"
:prefix-icon="Calendar"
:placeholder="$t('commons.date.select_date_time')"
/>
<div