feat(查询组件): 日期筛选组件可设置查询的起始日期 #6005

This commit is contained in:
dataeaseShu 2024-03-13 15:42:00 +08:00
parent d6dcaa1b71
commit e213a7e3f6
4 changed files with 196 additions and 32 deletions

View File

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

View File

@ -1,9 +1,11 @@
getLastStart
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive, nextTick, computed, shallowRef, toRefs, watch } from 'vue' import { ref, reactive, nextTick, computed, shallowRef, toRefs, watch } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { addQueryCriteriaConfig } from './options' import { addQueryCriteriaConfig } from './options'
import { getCustomTime } from './time-format' import { getCustomTime } from './time-format'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' 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 { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { fieldType } from '@/utils/attr' 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 { Tree } from '@/views/visualized/data/dataset/form/CreatDsGroup.vue'
import draggable from 'vuedraggable' import draggable from 'vuedraggable'
import RangeFilterTime from './RangeFilterTime.vue' import RangeFilterTime from './RangeFilterTime.vue'
import type { ManipulateType } from 'dayjs'
import dayjs from 'dayjs'
const { t } = useI18n() const { t } = useI18n()
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
@ -268,6 +272,102 @@ const multipleChange = (val: boolean, isMultipleChange = false) => {
curComponent.value.multiple = val 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 = () => { const validate = () => {
return conditions.value.some(ele => { return conditions.value.some(ele => {
if (ele.auto) return false if (ele.auto) return false
@ -292,8 +392,13 @@ const validate = () => {
} }
if (+ele.displayType === 7) { if (+ele.displayType === 7) {
if (!ele.defaultValueCheck) { if (!ele.defaultValueCheck) return false
return false if (ele.timeType === 'fixed') {
const [s, e] = ele.defaultValue || []
if (!s || !e) {
ElMessage.error('默认时间不能为空!')
return true
}
} }
const { const {
timeNum, timeNum,
@ -305,31 +410,53 @@ const validate = () => {
timeNumRange, timeNumRange,
relativeToCurrentTypeRange, relativeToCurrentTypeRange,
aroundRange, aroundRange,
arbitraryTimeRange arbitraryTimeRange,
timeType
} = ele } = ele
const startTime = getCustomTime( const startTime =
timeNum, timeType === 'dynamic'
relativeToCurrentType, ? getCustomTime(
timeGranularity, timeNum,
around, relativeToCurrentType,
arbitraryTime, timeGranularity,
timeGranularityMultiple, around,
'start-config' arbitraryTime,
) timeGranularityMultiple,
const endTime = getCustomTime( 'start-config'
timeNumRange, )
relativeToCurrentTypeRange, : new Date(ele.defaultValue[0])
timeGranularity, const endTime =
aroundRange, timeType === 'dynamic'
arbitraryTimeRange, ? getCustomTime(
timeGranularityMultiple, timeNumRange,
'end-config' relativeToCurrentTypeRange,
) timeGranularity,
aroundRange,
arbitraryTimeRange,
timeGranularityMultiple,
'end-config'
)
: new Date(ele.defaultValue[1])
if (+startTime > +endTime) { if (+startTime > +endTime) {
ElMessage.error('结束时间必须大于开始时间!') ElMessage.error('结束时间必须大于开始时间!')
return true 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 return false
} }

View File

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

View File

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