<!-- src/views/mes/modules/MesProductionWeekCalendar.vue -->
|
<template>
|
<div class="week-calendar">
|
<div class="calendar-header">
|
<a-button icon="left" @click="prevWeek" size="small" />
|
<span class="current-week-range">{{ weekRangeText }}</span>
|
<a-button icon="right" @click="nextWeek" size="small" />
|
<a-button @click="goToToday" size="small" style="margin-left: 8px">今天</a-button>
|
</div>
|
|
<div class="calendar-grid">
|
<div class="week-header">
|
<div
|
v-for="(day, index) in weekDays"
|
:key="index"
|
class="header-cell"
|
>
|
<div class="day-name">{{ day.format('ddd') }}</div>
|
<div
|
class="day-number"
|
:class="{ today: isToday(day), selected: isSelected(day) }"
|
@click="selectDay(day)"
|
>
|
{{ day.date() }}
|
</div>
|
</div>
|
</div>
|
|
<div class="calendar-body">
|
<div
|
v-for="(day, index) in weekDays"
|
:key="index"
|
class="day-cell"
|
:class="{ today: isToday(day), selected: isSelected(day) }"
|
@click="selectDay(day)"
|
>
|
<div class="cell-content">
|
<!-- 插槽用于渲染日期内容 -->
|
<slot
|
name="dateCell"
|
:date="day"
|
:isSelected="isSelected(day)"
|
:isToday="isToday(day)"
|
>
|
<!-- 默认内容 -->
|
<div class="default-content">
|
<!-- 可以在这里添加默认的日期内容渲染逻辑 -->
|
</div>
|
</slot>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import moment from 'moment'
|
|
export default {
|
name: 'MesProductionWeekCalendar',
|
props: {
|
// 起始日期,默认为今天
|
startDate: {
|
type: [Object, String, Date],
|
default: null
|
}
|
},
|
data() {
|
return {
|
// 当前显示的起始日期
|
currentStartDate: this.startDate ? moment(this.startDate) : moment(),
|
// 选中的日期
|
selectedDate: this.startDate ? moment(this.startDate) : moment()
|
}
|
},
|
computed: {
|
// 计算连续7天的日期
|
weekDays() {
|
const days = []
|
for (let i = 0; i < 7; i++) {
|
days.push(this.currentStartDate.clone().add(i, 'days'))
|
}
|
return days
|
},
|
// 当前显示的日期范围文本
|
weekRangeText() {
|
const start = this.currentStartDate
|
const end = this.currentStartDate.clone().add(6, 'days')
|
|
if (start.month() === end.month()) {
|
return `${start.format('YYYY年M月D日')} - ${end.format('D日')}`
|
} else {
|
return `${start.format('YYYY年M月D日')} - ${end.format('M月D日')}`
|
}
|
}
|
},
|
watch: {
|
startDate(newVal) {
|
if (newVal) {
|
this.currentStartDate = moment(newVal)
|
this.selectedDate = moment(newVal)
|
}
|
}
|
},
|
methods: {
|
// 切换到上7天
|
prevWeek() {
|
this.currentStartDate = this.currentStartDate.clone().subtract(7, 'days')
|
this.$emit('change', this.currentStartDate)
|
},
|
// 切换到下7天
|
nextWeek() {
|
this.currentStartDate = this.currentStartDate.clone().add(7, 'days')
|
this.$emit('change', this.currentStartDate)
|
},
|
// 跳转到今天
|
goToToday() {
|
this.currentStartDate = moment()
|
this.selectedDate = moment()
|
this.$emit('change', this.currentStartDate)
|
this.$emit('select', this.selectedDate)
|
},
|
// 选择日期
|
selectDay(day) {
|
this.selectedDate = day.clone()
|
this.$emit('select', day)
|
},
|
// 判断是否是今天
|
isToday(day) {
|
return day.isSame(moment(), 'day')
|
},
|
// 判断是否是选中的日期
|
isSelected(day) {
|
return day.isSame(this.selectedDate, 'day')
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.week-calendar {
|
padding: 16px;
|
}
|
|
.calendar-header {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
margin-bottom: 16px;
|
}
|
|
.current-week-range {
|
margin: 0 16px;
|
font-weight: bold;
|
font-size: 14px;
|
}
|
|
.calendar-grid {
|
border: 1px solid #e8e8e8;
|
border-radius: 4px;
|
overflow: hidden;
|
}
|
|
.week-header {
|
display: flex;
|
background-color: #fafafa;
|
border-bottom: 1px solid #e8e8e8;
|
}
|
|
.header-cell {
|
flex: 1;
|
text-align: center;
|
padding: 8px 0;
|
border-right: 1px solid #e8e8e8;
|
}
|
|
.header-cell:last-child {
|
border-right: none;
|
}
|
|
.day-name {
|
font-size: 12px;
|
color: #666;
|
margin-bottom: 4px;
|
}
|
|
.day-number {
|
font-size: 16px;
|
font-weight: bold;
|
cursor: pointer;
|
width: 30px;
|
height: 30px;
|
line-height: 30px;
|
margin: 0 auto;
|
border-radius: 50%;
|
}
|
|
.day-number.today {
|
background-color: #1890ff;
|
color: white;
|
}
|
|
.day-number.selected {
|
background-color: #bae7ff;
|
color: #1890ff;
|
}
|
|
.calendar-body {
|
display: flex;
|
height: 300px;
|
}
|
|
.day-cell {
|
flex: 1;
|
border-right: 1px solid #e8e8e8;
|
cursor: pointer;
|
padding: 4px;
|
}
|
|
.day-cell:last-child {
|
border-right: none;
|
}
|
|
.day-cell.today {
|
background-color: #e6f7ff;
|
}
|
|
.day-cell.selected {
|
background-color: #bae7ff;
|
}
|
|
.cell-content {
|
height: 100%;
|
overflow: hidden;
|
}
|
|
.default-content {
|
height: 100%;
|
}
|
</style>
|