对接数据

This commit is contained in:
2025-10-24 15:45:38 +08:00
parent 672a2f4c90
commit d3375a347f
138 changed files with 16904 additions and 1026 deletions

View File

@ -0,0 +1,314 @@
<template>
<div class="date-picker-core">
<!-- 日期// 选择区 -->
<div class="picker-container">
<!-- 日模式 -->
<div v-if="mode === 'Daily'" class="daily-picker">
<HorizontalDateList>
<button
v-for="day in dailyDays"
:key="day.dateStr"
:class="{ 'selected': day.dateStr === selectedDate }"
@click="handleSelect(day.dateStr)"
>{{ day.day }}</button>
</HorizontalDateList>
</div>
<!-- 周模式 -->
<div v-else-if="mode === 'Weekly'" class="weekly-picker">
<HorizontalDateList>
<button
v-for="week in weeklyRanges"
:key="week.start"
:class="{ 'selected': week.start === selectedDate[0] && week.end === selectedDate[1] }"
@click="handleSelect([week.start, week.end])"
>{{ week.label }}</button>
</HorizontalDateList>
</div>
<!-- 月模式 -->
<div v-else class="monthly-picker">
<HorizontalDateList>
<button
style="margin: 0 15px"
v-for="(monthAbbr, index) in monthAbbrs"
:key="index"
:class="{ 'selected': (index + 1) === selectedMonth }"
@click="handleMonthSelect(index + 1)"
>{{ monthAbbr }}</button>
</HorizontalDateList>
</div>
</div>
</div>
</template>
<script>
import HorizontalDateList from '@/components/HorizontalDateList.vue';
export default {
name: 'OptionDates',
components: {
HorizontalDateList
},
props: {
// 当前年份,由外部传入
year: {
type: Number,
required: true
},
// 当前模式,由外部传入 (Daily, Weekly, Monthly)
mode: {
type: String,
required: true,
validator: (val) => ['Daily', 'Weekly', 'Monthly'].includes(val)
},
// 日模式下的当前月份,由外部传入
month: {
type: Number,
default: () => new Date().getMonth() + 1,
validator: (val) => val >= 1 && val <= 12
}
},
data() {
return {
selectedDate: this.mode === 'Daily' ? '' : ['', ''], // 选中的日期/日期范围
selectedMonth: this.month // 月模式下选中的月份
};
},
computed: {
// 日模式:生成"当前年月"的所有日期
dailyDays() {
const daysInMonth = this.getDaysInMonth(this.year, this.month);
return Array.from({ length: daysInMonth }, (_, i) => {
const day = i + 1;
const date = new Date(this.year, this.month - 1, day);
return {
day,
dateStr: this.formatDate(date)
};
});
},
// 周模式:生成"当前年份"的所有完整周区间
weeklyRanges() {
return this.getWeekRanges(this.year);
},
// 月模式12个月份的英文简写
monthAbbrs() {
return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
}
},
created() {
// 组件创建时自动选中当前日期或周
this.autoSelectCurrentDate();
},
methods: {
// 自动选中当前日期或周
autoSelectCurrentDate(shouldEmit = true) {
const now = new Date();
const currentYear = now.getFullYear();
const currentMonth = now.getMonth() + 1;
const currentDateStr = this.formatDate(now);
// 只有当年份和月份匹配当前日期时才自动选中
if (this.year === currentYear) {
if (this.mode === 'Daily' && this.month === currentMonth) {
this.selectedDate = currentDateStr;
if (shouldEmit) {
this.$emit('select', currentDateStr);
}
} else if (this.mode === 'Weekly') {
// 找到当前日期所在的周
const currentWeek = this.getWeekForDate(now);
if (currentWeek) {
this.selectedDate = [currentWeek.start, currentWeek.end];
if (shouldEmit) {
this.$emit('select', [currentWeek.start, currentWeek.end]);
}
}
} else if (this.mode === 'Monthly') {
// 月模式下自动选中当前月并导出日期范围
this.selectedMonth = currentMonth;
const [start, end] = this.getMonthRange(this.year, currentMonth);
if (shouldEmit) {
this.$emit('select', [start, end]);
}
}
}
},
// 获取指定日期所在的周
getWeekForDate(date) {
const weeks = this.getWeekRanges(this.year);
const dateStr = this.formatDate(date);
for (const week of weeks) {
// 检查日期是否在该周范围内
if (dateStr >= week.start && dateStr <= week.end) {
return week;
}
}
return null;
},
// 处理日/周模式的选择
handleSelect(value) {
this.selectedDate = value;
this.$emit('select', value);
},
// 处理月模式的选择
handleMonthSelect(month) {
this.selectedMonth = month;
const [start, end] = this.getMonthRange(this.year, month);
this.$emit('select', [start, end]);
},
// 辅助获取某月的天数month1-12
getDaysInMonth(year, month) {
return new Date(year, month, 0).getDate();
},
// 辅助:格式化日期为 yyyy-mm-dd
formatDate(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}`;
},
// 辅助获取某月的首尾日期month1-12
getMonthRange(year, month) {
const start = new Date(year, month - 1, 1);
const end = new Date(year, month, 0);
return [this.formatDate(start), this.formatDate(end)];
},
// 辅助:获取某年的所有完整周区间(假设周从周日开始,到周六结束)
getWeekRanges(year) {
const ranges = [];
let currentDate = new Date(year, 0, 1); // 当年1月1日
// 找到第一个周日(作为周起始)
while (currentDate.getDay() !== 0) {
currentDate.setDate(currentDate.getDate() + 1);
}
// 生成所有"结束日期在当年"的完整周
while (currentDate.getFullYear() === year) {
const start = new Date(currentDate);
const end = new Date(currentDate);
end.setDate(end.getDate() + 6); // 周日到周六共7天
if (end.getFullYear() === year) { // 确保周结束在当年
ranges.push({
label: `${this.monthAbbrs[start.getMonth()]} ${start.getDate()}-${end.getDate()}`,
start: this.formatDate(start),
end: this.formatDate(end)
});
}
currentDate.setDate(currentDate.getDate() + 7); // 下一周
}
return ranges;
},
// 重置选择状态
resetSelection() {
if (this.mode === 'Daily') {
this.selectedDate = '';
} else if (this.mode === 'Weekly') {
this.selectedDate = ['', ''];
} else {
this.selectedMonth = this.month;
}
}
},
watch: {
// 监听年份变化,重置选择
year() {
this.resetSelection();
this.autoSelectCurrentDate();
},
mode: {
handler(newMode, oldMode) {
if (newMode !== oldMode) {
this.resetSelection();
// 切换模式时不立即触发 emit让组件自行处理
this.autoSelectCurrentDate(false);
// 通知子组件重新计算滚动状态
this.$nextTick(() => {
this.$children.forEach(child => {
if (child.$options.name === 'HorizontalDateList') {
child.updateScrollState();
}
});
});
}
},
immediate: true
},
month() {
if (this.mode === 'Daily') {
this.selectedDate = '';
}
this.autoSelectCurrentDate();
}
},
};
</script>
<style scoped>
.date-picker-core {
padding: 10px;
}
.picker-container {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 12px;
border-radius: 4px;
width: 100%;
box-sizing: border-box;
background-color: #ffffff;
}
.daily-picker,
.weekly-picker,
.monthly-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
}
.daily-picker button,
.weekly-picker button,
.monthly-picker button {
padding: 6px 10px;
border: 1px solid #e5e7eb;
border-radius: 4px;
background: #fff;
cursor: pointer;
transition: all 0.2s;
font-size: 14px;
&:active {
opacity: 0.8;
}
}
.daily-picker button:hover,
.weekly-picker button:hover,
.monthly-picker button:hover {
border-color: #9ca3af;
}
.daily-picker button.selected,
.weekly-picker button.selected,
.monthly-picker button.selected {
background: #4f46e5;
color: #fff;
border-color: #4f46e5;
}
</style>