<template>
|
<div class="flex items-center">
|
<div class="flex items-center space-x-1">
|
<div
|
class="ywifont ywicon-pre"
|
:class="{ 'cursor-not-allowed': !offsetClickIsAllow, 'cursor-pointer': offsetClickIsAllow }"
|
@click="preDayClick"
|
></div>
|
<el-date-picker
|
style="width: 240px"
|
v-model="dateValue"
|
type="daterange"
|
:start-placeholder="START_PLACEHOLDER"
|
:end-placeholder="END_PLACEHOLDER"
|
:value-format="valueFormat"
|
:format="DEFAULT_FORMATS_DATE"
|
:disabled-date="disabledDate"
|
:clearable="false"
|
:disabled="disabled"
|
@change="datePickerChange"
|
>
|
<template v-for="(value, name) in $slots" #[name]="slotData">
|
<slot :name="name" v-bind="slotData || {}"></slot>
|
</template>
|
</el-date-picker>
|
<div
|
class="ywifont ywicon-next"
|
:class="{ 'cursor-not-allowed': !offsetClickIsAllow, 'cursor-pointer': offsetClickIsAllow }"
|
@click="nextDayClick"
|
></div>
|
</div>
|
|
<div class="ml-2 inline-flex items-center space-x-2 text-[14px]">
|
<div
|
@click="quickPickRangeClick(parseInt(item))"
|
class="border border-solid rounded-md px-2 cursor-pointer"
|
:class="{ 'bg-[#1677ff]': parseInt(item) === quickPickValue, 'text-white': parseInt(item) === quickPickValue }"
|
v-for="item in Object.keys(timeRangeMapTitle)"
|
:key="item"
|
>
|
{{ timeRangeMapTitle[item] }}
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { ElDatePicker } from 'element-plus';
|
import { definePropType } from 'element-plus/es/utils/vue/props/runtime';
|
import { ref, type PropType, computed, watch, nextTick } from 'vue';
|
import type { TimeRangeParam } from '../types';
|
import { TimeRangeEnum, TimeStepValue, monthTimeRangeEnumMapTitle } from './types';
|
import { dayTimeRangeEnumMapTitle, timeRangeEnumMapValue } from './types';
|
import {
|
CURRENT_DAY,
|
DEFAULT_FORMATS_DATE,
|
DEFAULT_FORMATS_TIME,
|
END_PLACEHOLDER,
|
RANGE_SEPARATOR,
|
START_PLACEHOLDER,
|
} from '/@/components/form/datepicker/constants';
|
import { formatDate } from '/@/utils/formatTime';
|
import moment from 'moment';
|
|
const valueFormat = DEFAULT_FORMATS_DATE + ' ' + DEFAULT_FORMATS_TIME;
|
const props = defineProps({
|
data: {
|
type: Object as PropType<TimeRangeParam>,
|
},
|
disabled: {
|
type: Boolean,
|
default: false,
|
},
|
});
|
|
const getRangeMapTitle = (timeStep: TimeStepValue) => {
|
switch (timeStep) {
|
case TimeStepValue.Day:
|
return dayTimeRangeEnumMapTitle;
|
case TimeStepValue.Month:
|
return monthTimeRangeEnumMapTitle;
|
default:
|
return dayTimeRangeEnumMapTitle;
|
}
|
};
|
|
const timeRangeMapTitle = getRangeMapTitle(props.data?.origin?.time_step);
|
const dateValue = defineModel({
|
type: definePropType<[string, string]>(Array),
|
});
|
const emit = defineEmits(['change']);
|
|
const dateChange = () => {
|
nextTick(() => {
|
emit('change', dateValue.value);
|
});
|
};
|
|
const disabledDate = (date: Date) => {
|
return date > CURRENT_DAY;
|
};
|
|
const resetQuickPickValue = () => {
|
quickPickValue.value = null;
|
};
|
const quickPickValue = ref<TimeRangeEnum>(null);
|
const quickPickRangeClick = (val: TimeRangeEnum) => {
|
if (props.disabled) return;
|
if (quickPickValue.value === val) return;
|
|
quickPickValue.value = val;
|
dateValue.value = timeRangeEnumMapValue[val]().map((item) => formatDate(item)) as [string, string];
|
dateChange();
|
};
|
|
const offsetClickIsAllow = computed(() => !!dateValue.value && !props.disabled);
|
const preDayClick = () => {
|
if (props.disabled) return;
|
|
if (!dateValue.value) return;
|
dateValue.value[0] = moment(dateValue.value[0]).subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss');
|
dateChange();
|
|
resetQuickPickValue();
|
};
|
|
const nextDayClick = () => {
|
if (props.disabled) return;
|
|
if (!dateValue.value) return;
|
dateValue.value[1] = moment(dateValue.value[1]).add(1, 'day').format('YYYY-MM-DD HH:mm:ss');
|
dateChange();
|
|
resetQuickPickValue();
|
};
|
|
const datePickerChange = (va) => {
|
resetQuickPickValue();
|
dateChange();
|
};
|
|
defineExpose({
|
formatDateValue: dateValue,
|
});
|
</script>
|
<style scoped lang="scss">
|
:deep(.el-date-editor .el-range__close-icon--hidden) {
|
display: none;
|
}
|
</style>
|