291 lines
6.6 KiB
Vue

<template>
<view class="calendar">
<view class="calendar-header">
<u-icon @click="prevYear" name="arrow-left-double" color="#A2A4AF" size="40"></u-icon>
<u-icon @click="prevMonth" name="arrow-left" color="#A2A4AF" size="40"></u-icon>
<text>{{ currentYear }} {{ currentMonth + 1 }} </text>
<u-icon @click="nextMonth" name="arrow-right" color="#A2A4AF" size="40"></u-icon>
<u-icon @click="nextYear" name="arrow-right-double" color="#A2A4AF" size="40"></u-icon>
</view>
<view class="calendar-weekdays">
<text v-for="day in weekdays" :key="day">{{ day }}</text>
</view>
<view class="calendar-days">
<view v-for="day in daysInMonth" :key="day.date" class="calendar-day" @click="examineCalendarView(day)"
:class="day.id || day.num ? 'calendar-day2' : 'calendar-day1'">
<view class="calendar-day_header" :class="{
'other-month': day.isOtherMonth,
'current-day': $dayjs(day.date).format('YYYY-MM-DD') == defaultDay,
'day-active': day.id || day.num,
'day-forbidden': dateTimeUp(day.date)
}">
<view>
{{ day.day }}
</view>
<view class="calendar-text">
{{ day.id || day.num ? "已写" : "未写" }}
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import dayjs from "dayjs";
export default {
name: "CalendarView",
props: {
defaultMonth: {
type: String,
default: () => dayjs().format("YYYY-MM")
},
ocrBuildLogAllList: {
type: Array,
default: () => []
},
type: {
type: Number,
default: () => 1
},
},
data() {
return {
currentDate: this.defaultMonth,
weekdays: ["日", "一", "二", "三", "四", "五", "六"],
dataList: [],
defaultType: 1,
defaultDay: dayjs().format("YYYY-MM-DD"),
};
},
computed: {
dateTimeUp() {
return (dateTime) => {
return !dayjs(dateTime).isBefore(dayjs());
};
},
currentYear() {
return dayjs(this.currentDate).year();
},
currentMonth() {
return dayjs(this.currentDate).month();
},
daysInMonth() {
console.log(22222222222, this.currentDate);
const currentDayjs = dayjs(this.currentDate);
const startOfMonth = currentDayjs.startOf("month");
const endOfMonth = currentDayjs.endOf("month");
const startDay = startOfMonth.day();
const endDay = endOfMonth.day();
// 计算上个月需要显示的天数
const prevMonthDays = [];
for (let i = startDay - 1; i >= 0; i--) {
const date = startOfMonth.subtract(startDay - i, "day");
// console.log(date.date(),date.format('YYYY-MM-DD'));
prevMonthDays.unshift({
day: date.date(),
date: date.format("YYYY-MM-DD"),
isOtherMonth: true,
isCurrentDay: false,
});
}
// 计算当前月的天数
const currentMonthDays = [];
for (let i = 0; i < endOfMonth.date(); i++) {
const date = startOfMonth.add(i, "day");
currentMonthDays.push({
day: date.date(),
date: date.format("YYYY-MM-DD"),
isOtherMonth: false,
isCurrentDay: date.isSame(dayjs(), "day"),
});
}
// 计算下个月需要显示的天数
const nextMonthDays = [];
for (let i = 1; i <= 6 - endDay; i++) {
const date = endOfMonth.add(i, "day");
nextMonthDays.push({
day: date.date(),
date: date.format("YYYY-MM-DD"),
isOtherMonth: true,
isCurrentDay: false,
});
}
const resultList = [
...prevMonthDays,
...currentMonthDays,
...nextMonthDays,
];
return resultList.map((item) => {
const find = this.dataList.find((ele) => dayjs(ele.date).format("YYYY-MM-DD") == item.date);
if (find) {
return {
...item,
...find,
};
}
return {
...item,
};
});
},
},
methods: {
prevMonth() {
this.currentDate = this.$dayjs(this.currentDate)
.subtract(1, "month")
.format("YYYY-MM-DD");
},
nextMonth() {
this.currentDate = this.$dayjs(this.currentDate)
.add(1, "month")
.format("YYYY-MM-DD");
},
prevYear() {
this.currentDate = this.$dayjs(this.currentDate)
.subtract(1, "year")
.format("YYYY-MM-DD");
},
nextYear() {
this.currentDate = this.$dayjs(this.currentDate)
.add(1, "year")
.format("YYYY-MM-DD");
},
currentDay() {
this.currentDate = dayjs(this.defaultMonth).format("YYYY-MM");
},
examineCalendarView(row) {
if (this.dateTimeUp(row.date)) return
this.defaultDay = this.$dayjs(row.date).format('YYYY-MM-DD');
this.$emit("examineCalendarView", row);
},
},
watch: {
defaultMonth: {
// immediate: true,
handler(newVal) {
console.log(1111111, newVal);
this.currentDay();
},
},
type: {
handler(newVal) {
this.defaultType = newVal;
},
deep: true,
immediate: true,
},
ocrBuildLogAllList: {
handler(newVal) {
this.dataList = newVal;
},
deep: true,
immediate: true,
},
daysInMonth: {
handler(newVal) {
const find = this.daysInMonth.find(item => this.$dayjs(item.date).format('YYYY-MM-DD') == this.defaultDay);
if (find) {
this.$emit("examineCalendarView", find);
}
},
deep: true,
// immediate: true,
}
},
};
</script>
<style lang="less" scoped>
.calendar {
width: 100%;
background-color: #FFFFFF;
padding: 0 28rpx;
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 40rpx;
>text {
font-weight: 500;
font-size: 30rpx;
color: #1A1A1A;
}
}
.calendar-weekdays {
display: flex;
justify-content: space-around;
// margin-bottom: 10px;
>text {
flex: 1;
height: 110rpx;
font-size: 28rpx;
color: #4D4D4D;
display: flex;
align-items: center;
justify-content: center;
}
}
.calendar-days {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 0px;
height: 580rpx;
grid-auto-rows: auto;
}
.calendar-day {
cursor: pointer;
position: relative;
display: flex;
justify-content: center;
.calendar-day_header {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 82rpx;
height: 82rpx;
border-radius: 50%;
border: 2rpx solid #B90303;
font-size: 28rpx;
color: #B3B3B3;
.calendar-text {
font-size: 20rpx;
}
}
.day-active {
border: 2rpx solid #3D99FF;
color: #4D4D4D;
}
.other-month {
display: none;
}
.current-day {
border-color: transparent;
background-color: #3D99FF;
color: white;
}
.day-forbidden {
border-color: transparent;
background: #F8F8F8;
color: #4D4D4D;
}
}
</style>