lanan-repair-app/components/commonTimeSelect.vue
2025-11-04 18:46:51 +08:00

237 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="date-range-selector">
<u-subsection :list="filteredDateRangeList" keyName="label" :current="selected"
@change="handleSubsectionChange" />
<uni-datetime-picker :value="internalDateRange" type="daterange" @change="handleDatePickerChange" />
</view>
</template>
<script>
export default {
props: {
// Vue2 中使用 value 作为 v-model 的 prop
value: {
type: Array,
required: true
},
// 模式控制basic-基础范围relative-相对天数all-全部
mode: {
type: String,
default: 'basic', // 'basic' | 'relative' | 'all'
validator: (value) => ['basic', 'relative', 'all'].includes(value)
},
dateRangeList: {
type: Array,
default: () => [
// 基础范围
{
label: "本日",
value: "day",
mode: ['basic', 'all']
},
// {
// label: "本周",
// value: "week",
// mode: ['basic', 'all']
// },
{
label: "本月",
value: "month",
mode: ['basic', 'all']
},
{
label: "本年",
value: "year",
mode: ['basic', 'all']
},
// 相对天数范围
{
label: "近7天",
value: "7days",
mode: ['relative', 'all']
},
{
label: "近30天",
value: "30days",
mode: ['relative', 'all']
},
{
label: "近60天",
value: "60days",
mode: ['relative', 'all']
},
{
label: "近90天",
value: "90days",
mode: ['relative', 'all']
}
]
}
},
data() {
return {
selected: 0,
internalDateRange: this.value
};
},
computed: {
// 根据模式过滤选项列表
filteredDateRangeList() {
return this.dateRangeList.filter(item =>
item.mode.includes(this.mode)
);
}
},
watch: {
value(newVal) {
if (JSON.stringify(newVal) !== JSON.stringify(this.internalDateRange)) {
this.internalDateRange = newVal;
this.resetSelectedIndex();
}
},
internalDateRange(newVal) {
this.$emit('input', newVal); // Vue2 中使用 input 事件
this.$emit('subsection-change', newVal);
},
// 监听模式变化,重置选中状态
mode() {
this.selected = 0;
this.resetToDefaultRange();
}
},
methods: {
// 获取日期范围
getDateRange(type) {
const now = new Date()
let start, end
switch (type) {
case 'week':
// 获取本周的开始(周一)和结束(周日)
const day = now.getDay() || 7 // Sunday 为 0设为 7
start = new Date(now)
start.setDate(now.getDate() - day + 1)
end = new Date(start)
end.setDate(start.getDate() + 6)
break;
case 'month':
// 获取本月的开始和结束
start = new Date(now.getFullYear(), now.getMonth(), 1)
end = new Date(now.getFullYear(), now.getMonth() + 1, 0) // 本月最后一天
break;
case 'day':
// 获取当天的开始和结束00:00:00 到 23:59:59
start = new Date(now)
start.setHours(0, 0, 0, 0)
end = new Date(now)
end.setHours(23, 59, 59, 999)
break;
case 'year':
// 获取本年的开始和结束
start = new Date(now.getFullYear(), 0, 1); // 本年1月1日
end = new Date(now.getFullYear(), 11, 31); // 本年12月31日
break;
case '7days':
// 近7天
end = new Date(now);
end.setHours(23, 59, 59, 999);
start = new Date(now);
start.setDate(now.getDate() - 6);
start.setHours(0, 0, 0, 0);
break;
case '30days':
// 近30天
end = new Date(now);
end.setHours(23, 59, 59, 999);
start = new Date(now);
start.setDate(now.getDate() - 29);
start.setHours(0, 0, 0, 0);
break;
case '60days':
// 近60天
end = new Date(now);
end.setHours(23, 59, 59, 999);
start = new Date(now);
start.setDate(now.getDate() - 59);
start.setHours(0, 0, 0, 0);
break;
case '90days':
// 近90天
end = new Date(now);
end.setHours(23, 59, 59, 999);
start = new Date(now);
start.setDate(now.getDate() - 89);
start.setHours(0, 0, 0, 0);
break;
default:
console.warn('不支持的类型:', type)
return []
}
return [
this.formatDateCus(start),
this.formatDateCus(end)
]
},
// 格式化日期
formatDateCus(date) {
const y = date.getFullYear()
const m = (date.getMonth() + 1).toString().padStart(2, '0')
const d = date.getDate().toString().padStart(2, '0')
return `${y}-${m}-${d}`
},
handleSubsectionChange(index) {
this.selected = index;
const {
value
} = this.filteredDateRangeList[index];
this.internalDateRange = this.getDateRange(value);
},
handleDatePickerChange(newRange) {
this.internalDateRange = newRange;
this.resetSelectedIndex();
},
resetSelectedIndex() {
const filteredList = this.filteredDateRangeList;
const selectedIndex = filteredList.findIndex((item) => {
const range = this.getDateRange(item.value);
return JSON.stringify(range) === JSON.stringify(this.internalDateRange);
});
this.selected = selectedIndex !== -1 ? selectedIndex : -1;
},
// 重置到默认范围
resetToDefaultRange() {
const defaultType = this.filteredDateRangeList[0]?.value || 'day';
this.internalDateRange = this.getDateRange(defaultType);
}
},
created() {
// 默认选择第一个选项
if (!this.value || this.value.length === 0) {
this.resetToDefaultRange();
} else {
this.resetSelectedIndex();
}
}
};
</script>
<style scoped>
.date-range-selector {
/* 可以写样式 */
}
</style>