
<template>
<div style="height: 100%">
<el-row>
<el-col :span="12">
<el-select
v-model="year"
size="mini"
@change="change_year"
>
<el-option
v-for="item in yearOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-select
v-model="month"
size="mini"
style="margin-right: 20px"
@change="change_mon"
>
<el-option
v-for="item in monthOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-col>
</el-row>
<el-row style="height: 100%">
<el-col :span="24">
<el-row style="width: 100%">
<full-calendar
ref="fullCalendar"
style="width: 100%"
:options="calendarOptions"
:event-content="renderEventContent"
/>
</el-row>
</el-col>
</el-row>
<el-dialog
title="切换状态"
:visible.sync="dialogVisible"
>
<p>您确定要将选中的日期切换为 {{ selectedStatus }} 吗?</p>
<span
slot="footer"
class="dialog-footer"
>
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button
type="primary"
@click="confirmChange"
>确 定</el-button
>
</span>
</el-dialog>
</div>
</template>
<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import bootstrapPlugin from '@fullcalendar/bootstrap'
import { formatDate } from '../../../api/basic/util'
import { list, save } from '../../../api/basic/tamapsexample'
export default {
components: {
FullCalendar
},
data() {
return {
year: new Date().getFullYear(),
month: new Date().getMonth() + 1,
yearOptions: [],
monthOptions: [],
selectedEvent: null,
selectedDate: null,
calendarOptions: {
dateClick: this.handleDateClick,
selectable: true,
locale: 'zh-cn',
plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin, bootstrapPlugin],
firstDay: '1',
headerToolbar: true,
slotLabelFormat: {
hour: '2-digit',
minute: '2-digit',
meridiem: false,
hour12: false
},
eventTimeFormat: {
hour: 'numeric',
minute: '2-digit',
hour12: false
},
weekends: true,
events: [],
height: 700,
editable: false,
selectable: true,
navLinks: false,
handleWindowResize: true,
initialDate: new Date(),
initialView: 'dayGridMonth',
fixedWeekCount: false
},
dialogVisible: false,
selectedStatus: '',
calendarData: []
}
},
mounted() {
this.initYearMonthOptions()
this.getCalendarData()
},
methods: {
initYearMonthOptions() {
const now = new Date()
for (let i = now.getFullYear() - 5; i <= now.getFullYear() + 5; i++) {
this.yearOptions.push({
value: i,
label: `${i}年`
})
}
for (let j = 1; j <= 12; j++) {
this.monthOptions.push({
value: j,
label: `${j}月`
})
}
},
async getCalendarData() {
const response = await list({ year: this.year, month: this.month })
this.calendarData = response.data.list
const rawEvents = this.generateFakeData(this.year, this.month, this.calendarData)
const events = []
rawEvents.forEach((event) => {
const { title, start, classNames } = event
events.push({
title,
start,
allDay: true,
classNames
})
})
console.log('Events:', events)
this.calendarOptions.events = events
const formatData = formatDate(new Date(this.year, this.month - 1, 1), 'yyyy-MM-dd')
console.log('formatData:', formatData)
this.$refs.fullCalendar.getApi().gotoDate(formatData)
},
generateFakeData(year, month, calendarData) {
const rawEvents = []
console.log('rawEvents', rawEvents)
const daysInMonth = new Date(year, month, 0).getDate()
const calendarMap = new Map(calendarData.map((event) => [event.date, event]))
for (let day = 1; day <= daysInMonth; day++) {
const format = 'yyyy-MM-dd'
const date = new Date(year, month - 1, day)
const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(
date.getDate()
).padStart(2, '0')}`
console.log('eventForDay:', formattedDate, 'date:', formatDate(date, format))
const eventForDay = calendarMap.get(formattedDate)
let status
let statusClass
if (eventForDay) {
status = eventForDay.status === '0' ? '休' : '班'
statusClass = eventForDay.status === '0' ? 'restday' : 'workday'
console.log('eventForDay:', formattedDate, 'status:', status, 'date:', formatDate(date, format))
rawEvents.push({
title: status,
start: date,
classNames: [statusClass]
})
} else {
const dayOfWeek = date.getDay()
const isWorkDay = dayOfWeek >= 1 && dayOfWeek <= 5
status = isWorkDay ? '班' : '休'
statusClass = isWorkDay ? 'workday' : 'restday'
const format = 'yyyy-MM-dd'
console.log('No event for day:', formattedDate, 'status:', status, 'date:', formatDate(date, format))
rawEvents.push({
title: status,
start: date,
classNames: [statusClass]
})
}
}
console.log('rawEvents', rawEvents)
return rawEvents
},
change_year() {
this.getCalendarData()
},
change_mon() {
this.getCalendarData()
},
handleDateClick(arg) {
this.selectedDate = arg.date
console.log(arg.date)
const format = 'yyyy-MM-dd'
const formattedDate = formatDate(this.selectedDate, format)
const eventForDay = this.calendarData.find((event) => event.date === formattedDate)
const status = eventForDay
? eventForDay.status === '0'
? '休'
: '班'
: arg.date.getDay() >= 1 && arg.date.getDay() <= 5
? '班'
: '休'
this.showDialog(status)
},
renderEventContent(eventInfo) {
return {
html: `<div class="${eventInfo.event.classNames.join(' ')}">
<span class="event-title">${eventInfo.event.title}</span>
</div>`
}
},
showDialog(status) {
const date = this.selectedDate
console.log(status)
if (date) {
this.selectedStatus = status === '班' ? '休' : '班'
this.dialogVisible = true
} else {
this.$message.warning('请先选择一个日期!')
}
},
async confirmChange() {
const date = this.selectedDate
const format = 'yyyy-MM-dd'
console.log('nowdate', formatDate(date, format))
if (date) {
const events = this.calendarOptions.events
const eventIndex = events.findIndex((event) => {
return event.start.toDateString() === date.toDateString()
})
if (eventIndex !== -1) {
const currentEvent = events[eventIndex]
if (currentEvent.title === '班') {
currentEvent.title = '休'
currentEvent.classNames = ['restday']
} else {
currentEvent.title = '班'
currentEvent.classNames = ['workday']
}
} else {
events.push({
title: '班',
start: date,
allDay: true,
classNames: ['workday']
})
}
this.calendarOptions.events = [...events]
const saveData = {
date: formatDate(date, 'yyyy-MM-dd'),
year: String(date.getFullYear()),
month: String(date.getMonth() + 1),
status: this.selectedStatus === '班' ? 1 : 0
}
try {
await save(saveData)
this.$message.success('保存成功!')
} catch (error) {
this.$message.error('保存失败,请重试!')
}
this.dialogVisible = false
}
}
}
}
</script>
<style>
.workday {
background-color: blue;
}
.event-title {
font-weight: bold;
}
</style>