Files
pqs-9100_client/frontend/src/components/TimeControl/index.vue

262 lines
8.2 KiB
Vue
Raw Normal View History

2024-10-22 13:19:13 +08:00
<template>
2024-10-22 14:47:25 +08:00
<div class='time-control'>
2024-10-22 13:19:13 +08:00
<el-select
2024-10-22 14:47:25 +08:00
class='select'
v-model='timeUnit'
placeholder='选择时间单位'
@change='handleChange'
2024-10-22 13:19:13 +08:00
>
2024-10-23 19:30:11 +08:00
<!-- 采用 v-for 动态渲染 -->
<el-option
2024-11-06 21:15:49 +08:00
v-for='unit in timeUnits'
:key='unit.value'
:label='unit.label'
:value='unit.value'
2024-10-23 19:30:11 +08:00
></el-option>
2024-10-22 13:19:13 +08:00
</el-select>
2024-10-22 14:47:25 +08:00
<!-- 禁用时间选择器 -->
<div class='date-display'>
2024-10-22 13:19:13 +08:00
<el-date-picker
2024-10-22 14:47:25 +08:00
class='date-picker'
v-model='startDate'
type='date'
placeholder='起始时间'
2024-11-06 21:15:49 +08:00
@change='emitDateChange'
:disabled-date='disableStartDate'
2024-10-22 14:47:25 +08:00
:readonly="timeUnit != '自定义'"
2024-10-22 13:19:13 +08:00
></el-date-picker>
<el-text>~</el-text>
<el-date-picker
2024-10-22 14:47:25 +08:00
class='date-picker'
v-model='endDate'
type='date'
placeholder='结束时间'
2024-11-06 21:15:49 +08:00
@change='emitDateChange'
:disabled-date='disableEndDate'
2024-10-22 13:19:13 +08:00
:readonly="timeUnit !== '自定义'"
></el-date-picker>
</div>
2024-10-22 14:47:25 +08:00
<div class='date-display' v-if="timeUnit !== '自定义'">
2024-10-22 13:19:13 +08:00
<el-button
2024-10-22 14:47:25 +08:00
style='width: 10px;'
class='triangle-button'
type='primary'
@click='prevPeriod'
2024-11-06 21:15:49 +08:00
@change='emitDateChange'
2024-10-22 13:19:13 +08:00
>
2024-10-22 14:47:25 +08:00
<div class='left_triangle'></div>
2024-10-22 13:19:13 +08:00
</el-button>
2024-11-06 21:15:49 +08:00
<el-button class='triangle-button' type='primary' @click='goToCurrent'>
当前
2024-10-22 13:19:13 +08:00
</el-button>
<el-button
2024-10-22 14:47:25 +08:00
style='width: 10px;'
class='triangle-button'
type='primary'
@click='nextPeriod'
:disabled='isNextDisabled'
2024-10-22 13:19:13 +08:00
>
2024-10-22 14:47:25 +08:00
<div class='right_triangle'></div>
2024-10-22 13:19:13 +08:00
</el-button>
</div>
</div>
</template>
2024-10-23 19:30:11 +08:00
2024-11-06 21:15:49 +08:00
<script setup lang='ts'>
import { ref, onMounted, defineProps, defineEmits } from 'vue'
2024-10-23 19:30:11 +08:00
2024-11-06 21:15:49 +08:00
// 定义时间单位的类型
2024-10-28 08:39:09 +08:00
interface TimeUnit {
label: string;
value: string;
}
2024-11-06 21:15:49 +08:00
2024-10-28 08:39:09 +08:00
// 定义组件的props包含包括和排除的时间单位
2024-11-06 21:15:49 +08:00
const props = defineProps({
include: {
type: Array as () => string[],
default: () => ['日', '周', '月', '季度', '年', '自定义'],
},
exclude: {
type: Array as () => string[],
default: () => [],
},
default: {
type: String,
2024-11-07 10:24:33 +08:00
default: '月',
2024-11-06 21:15:49 +08:00
},
})
// 定义事件
const emit = defineEmits<{
2024-11-07 10:24:33 +08:00
(e: 'update-dates', startDate: string, endDate: string): void;
2024-11-06 21:15:49 +08:00
}>()
const timeUnit = ref<string>(props.default) // 默认选择
2024-11-07 10:24:33 +08:00
const startDate = ref<Date>(new Date(0)) // 起始日期
2024-11-06 21:15:49 +08:00
const endDate = ref<Date>(new Date()) // 结束日期
const isNextDisabled = ref<boolean>(false) // 控制下一周期按钮的禁用状态
const today = ref<Date>(new Date()) // 当前日期
// 过滤出可用的时间单位
const timeUnits = ref<TimeUnit[]>(
props.include.filter(unit => !props.exclude.includes(unit)).map(unit => ({
label: unit,
value: unit,
})),
)
// 发出日期变化事件
const emitDateChange = () => {
emit('update-dates', formatDate(startDate.value), formatDate(endDate.value))
2024-11-07 10:24:33 +08:00
console.log('emitDateChange', startDate.value, endDate.value)
2024-11-06 21:15:49 +08:00
}
// 在组件挂载时更新日期范围
onMounted(() => {
updateDateRange()
})
const handleChange = (unit: string) => {
// 根据选择的时间单位处理日期变化
if (unit !== '自定义') {
updateDateRange()
} else {
// 自定义选项逻辑
startDate.value = new Date(new Date().setDate(new Date().getDate() - 1))
endDate.value = new Date()
}
timeUnit.value = unit
emitDateChange() // 变化时也发出更新事件
updateNextButtonStatus()
}
const updateDateRange = () => {
// 根据选择的时间单位计算起始和结束日期
if (timeUnit.value === '日') {
startDate.value = today.value
endDate.value = today.value
} else if (timeUnit.value === '周') {
startDate.value = getStartOfWeek(today.value)
endDate.value = getEndOfWeek(today.value)
} else if (timeUnit.value === '月') {
startDate.value = new Date(today.value.getFullYear(), today.value.getMonth(), 1)
endDate.value = new Date(today.value.getFullYear(), today.value.getMonth() + 1, 0)
} else if (timeUnit.value === '季度') {
const quarter = Math.floor(today.value.getMonth() / 3)
startDate.value = new Date(today.value.getFullYear(), quarter * 3, 1)
endDate.value = new Date(today.value.getFullYear(), quarter * 3 + 3, 0)
} else if (timeUnit.value === '年') {
startDate.value = new Date(today.value.getFullYear(), 0, 1)
endDate.value = new Date(today.value.getFullYear(), 11, 31)
}
updateNextButtonStatus()
}
const getStartOfWeek = (date: Date) => {
const startOfWeek = new Date(date)
const day = startOfWeek.getDay()
const diff = day === 0 ? -6 : 1 - day // 星期天的情况
startOfWeek.setDate(startOfWeek.getDate() + diff)
return startOfWeek
}
const getEndOfWeek = (date: Date) => {
const endOfWeek = new Date(date)
const day = endOfWeek.getDay()
const diff = day === 0 ? 0 : 7 - day // 星期天的情况
endOfWeek.setDate(endOfWeek.getDate() + diff)
return endOfWeek
}
const prevPeriod = () => {
const prevStartDate = new Date(startDate.value)
const prevEndDate = new Date(endDate.value)
if (timeUnit.value === '日') {
prevStartDate.setDate(prevStartDate.getDate() - 1)
prevEndDate.setDate(prevEndDate.getDate() - 1)
} else if (timeUnit.value === '周') {
prevStartDate.setDate(prevStartDate.getDate() - 7)
prevEndDate.setDate(prevEndDate.getDate() - 7)
} else if (timeUnit.value === '月') {
prevStartDate.setMonth(prevStartDate.getMonth() - 1)
prevEndDate.setMonth(prevEndDate.getMonth() - 1)
} else if (timeUnit.value === '季度') {
prevStartDate.setMonth(prevStartDate.getMonth() - 3)
prevEndDate.setMonth(prevEndDate.getMonth() - 3)
} else if (timeUnit.value === '年') {
prevStartDate.setFullYear(prevStartDate.getFullYear() - 1)
prevEndDate.setFullYear(prevEndDate.getFullYear() - 1)
}
startDate.value = prevStartDate
endDate.value = prevEndDate
updateNextButtonStatus()
}
const goToCurrent = () => {
if (timeUnit.value !== '自定义') {
updateDateRange() // 更新为当前选择时间单位的时间范围
}
}
const nextPeriod = () => {
const nextStartDate = new Date(startDate.value)
const nextEndDate = new Date(endDate.value)
if (timeUnit.value === '日') {
nextStartDate.setDate(nextStartDate.getDate() + 1)
nextEndDate.setDate(nextEndDate.getDate() + 1)
} else if (timeUnit.value === '周') {
nextStartDate.setDate(nextStartDate.getDate() + 7)
nextEndDate.setDate(nextEndDate.getDate() + 7)
} else if (timeUnit.value === '月') {
nextStartDate.setMonth(nextStartDate.getMonth() + 1)
nextEndDate.setMonth(nextEndDate.getMonth() + 1)
} else if (timeUnit.value === '季度') {
nextStartDate.setMonth(nextStartDate.getMonth() + 3)
nextEndDate.setMonth(nextStartDate.getMonth() + 3)
} else if (timeUnit.value === '年') {
nextStartDate.setFullYear(nextStartDate.getFullYear() + 1)
nextEndDate.setFullYear(nextEndDate.getFullYear() + 1)
}
startDate.value = nextStartDate
endDate.value = nextEndDate
updateNextButtonStatus()
}
const updateNextButtonStatus = () => {
// 更新下一个按钮的禁用状态
const maxDate = new Date() // 假设最新日期为今天
// 将 maxDate 设置为当天的开始时间
maxDate.setHours(0, 0, 0, 0)
// 将 endDate 设置为当天的开始时间并进行比较
const endDateAdjusted = new Date(endDate.value)
endDateAdjusted.setHours(0, 0, 0, 0)
// 仅比较日期部分
isNextDisabled.value = endDateAdjusted >= maxDate
emitDateChange() // 变化时也发出更新事件
}
// 限制开始日期不能选择超过当前日期
const disableStartDate = (date: Date) => {
return date > today.value
}
// 限制结束日期不能超过当前日期且必须大于开始日期
const disableEndDate = (date: Date) => {
if (timeUnit.value !== '自定义') return false // 如果不是自定义时间单位,则不限制
const start = new Date(startDate.value)
return date > today.value || (start && date <= start)
}
// 格式化日期yyyy-mm-dd
function formatDate(date:Date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
2024-10-22 14:47:25 +08:00
2024-10-22 13:19:13 +08:00
</script>
2024-10-22 14:47:25 +08:00
<style scoped lang='scss'>
2024-10-22 13:19:13 +08:00
@import "./index.scss";
</style>
2024-10-28 08:39:09 +08:00