gaoluyang
2026-06-24 712aa51536236d43e87273e4ce45ac5691dffad8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<script lang="ts" setup>
import type { Dayjs } from 'dayjs';
 
import { onMounted, ref } from 'vue';
 
import { DatePicker, Radio, RadioGroup } from 'ant-design-vue';
import dayjs from 'dayjs';
 
import { getRangePickerDefaultProps } from '#/utils/rangePickerProps';
 
/** 快捷日期范围选择组件 */
defineOptions({ name: 'ShortcutDateRangePicker' });
 
const emits = defineEmits<{
  change: [times: [Dayjs, Dayjs]];
}>();
 
const times = ref<[Dayjs, Dayjs]>(); // 日期范围
 
const rangePickerProps = getRangePickerDefaultProps();
const timeRangeOptions = [
  rangePickerProps.presets[3]!, // 昨天
  {
    label: rangePickerProps.presets[1]!.label,
    value: [
      dayjs().subtract(7, 'day').startOf('day'),
      dayjs().subtract(1, 'day').endOf('day'),
    ],
  },
  {
    label: rangePickerProps.presets[2]!.label,
    value: [
      dayjs().subtract(30, 'day').startOf('day'),
      dayjs().subtract(1, 'day').endOf('day'),
    ],
  },
];
const timeRangeType = ref(timeRangeOptions[1]!.label); // 默认选中第一个选项
 
/** 设置时间范围 */
function setTimes() {
  // 根据选中的选项设置时间范围
  const selectedOption = timeRangeOptions.find(
    (option) => option.label === timeRangeType.value,
  );
  if (selectedOption) {
    times.value = selectedOption.value as [Dayjs, Dayjs];
  }
}
 
/** 快捷日期单选按钮选中 */
async function handleShortcutDaysChange() {
  // 设置时间范围
  setTimes();
  // 触发时间范围选中事件
  emitDateRangePicker();
}
 
/** 日期范围改变 */
function handleDateRangeChange() {
  emitDateRangePicker();
}
 
/** 触发时间范围选中事件 */
function emitDateRangePicker() {
  if (times.value && times.value.length === 2) {
    emits('change', times.value);
  }
}
 
/** 初始化 */
onMounted(() => {
  handleShortcutDaysChange();
});
</script>
 
<template>
  <div class="flex items-center gap-2">
    <RadioGroup
      v-model:value="timeRangeType"
      @change="handleShortcutDaysChange"
    >
      <Radio
        v-for="option in timeRangeOptions"
        :key="option.label"
        :value="option.label"
      >
        {{ option.label }}
      </Radio>
    </RadioGroup>
    <DatePicker.RangePicker
      v-model:value="times"
      :format="rangePickerProps.format"
      :value-format="rangePickerProps.valueFormat"
      :placeholder="rangePickerProps.placeholder"
      :presets="rangePickerProps.presets"
      class="!w-full !max-w-96"
      @change="handleDateRangeChange"
    />
    <slot></slot>
  </div>
</template>