我正在尝试根据完整日历中的日期更改资源。我正在使用 resourcestimegridday 视图。每个资源都是一个人,只有在可用时才应该出现。我有一个查询,返回根据当天没有休假的人。
当我使用 eventDidMount 时,它仅在当天有事件(资源正确更改)时起作用,但在没有事件时不起作用。我在完整的日历文档中找不到实现我期望的选项。
如果我使用dateSet,我会遇到此错误: Pickup.vue:97未捕获(承诺中)TypeError:无法读取未定义的属性(读取“calendarOptions”)
PickupController.php
public function getResources(Request $request){
/**
* TODO
*
* SELECT
* employees.id
* FROM employees
* left JOIN appointments
* ON appointments.employee_id = employees.id
* WHERE employees.id NOT IN (
* SELECT appointments.employee_id WHERE (date(appointments.start_time) <= CURDATE() AND date(appointments.finish_time) >= CURDATE()))
* AND employees.department_id = 3
* GROUP BY employees.id
*/
$employees = Employee::select('employees.id','employees.name','employees.business_start_time','employees.business_finish_time')
->leftjoin('appointments','employees.id','=','appointments.employee_id')
->whereNotIn('employees.id',
DB::table('appointments')->select('appointments.employee_id')->whereDate(('appointments.start_time'),'<=',$request->date)->whereDate(('appointments.finish_time'),'>=',$request->date))
->where('employees.department_id','=',3)
->groupBy('employees.id')
->get();
$resources = [];
foreach($employees as $employee) {
$resource = [];
$resource['id'] = $employee->id;
$resource['title'] = $employee->name;
$resource['businessHours']['daysOfWeek'] = [ 1, 2, 3, 4, 5];
$resource['businessHours']['startTime'] = $employee->business_start_time;
$resource['businessHours']['endTime'] = $employee->business_finish_time;
$resources[] = $resource;
}
return response()->json($resources);
}
皮卡.vue
<script>
import FullCalendar from '@fullcalendar/vue3'
import timeGridPlugin from "@fullcalendar/timegrid"
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import resourceTimeGridPlugin from '@fullcalendar/resource-timegrid'
import scrollGridPlugin from '@fullcalendar/scrollgrid'
import listPlugin from '@fullcalendar/list'
import esLocale from '@fullcalendar/core/locales/es'
import adaptivePlugin from '@fullcalendar/adaptive'
import PickupModal from '../../Components/Modals/PickupModal.vue'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue'
import axios from 'axios'
import { router } from "@inertiajs/vue3"
import moment from 'moment'
import { reactive } from "vue";
export default {
name: 'Pickup',
components: {
FullCalendar,
PickupModal,
AuthenticatedLayout
},
emits: {
'deleteEventResource':{
id:'',
},
'editEventResource':{
id:'',
},
'closeModal':true,
'saveEventResource':{id:'',},
},
props: {
errors: Object,
events: Array,
resources: Array,
},
data() {
return {
showModal: false,
editing : false,
newEventResource: {
title: '',
content: '',
date_at: '',
end_at: '',
status: '',
color: '',
content: ''
},
calendarOptions : {
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
plugins: [ dayGridPlugin, timeGridPlugin, listPlugin,interactionPlugin, adaptivePlugin, resourceTimeGridPlugin, scrollGridPlugin ],
headerToolbar: {
left: "prev,next today",
center: "title",
right: "dayGridMonth,timeGridWeek,resourceTimeGridDay,listMonth",
},
initialView: 'resourceTimeGridDay',
locale: esLocale,
dayMaxEvents: false,
weekends: true,
navLinks: true,
nowIndicator: true,
firstDay: 1,
defaultAllDay: false,
timeZone: 'Europe/Madrid',
resources: [],
dateClick: this.handleDateClick,
eventClick: this.handleEventClick,
events: [],
dayMinWidth: 150,
stickyFooterScrollbar: true,
businessHours: [],
slotDuration: '00:15:00',
eventContent: function(eventInfo) {
return { html: eventInfo.timeText + "<br>" + eventInfo.event.title + "<br>" + eventInfo.event.extendedProps.content }
},
eventDidMount: this.dayDrivers, //works only on days that has events; resources changes
eventMouseEnter: function(info) {info.el.title = info.event.extendedProps.content;},
datesSet:function (dateInfo){
let date = dateInfo.startStr.split("T")[0];
axios.get(route('pickups.index',{date:date})).then(({data}) => {
this.$data.calendarOptions.resources = data; //returns Cannot read properties of undefined (reading 'calendarOptions')
});
},
//lazyFetching: false,
// rerenderDelay: 500,
}
}
},
beforeMount(){
const start = new Date().toISOString().split("T")[0];
this.$data.calendarOptions.resources = {
url: route('pickups.index',{date:start}),
method: 'GET',
failure: error => {
console.log('tenemos este error: ', error.message);
}
},
this.$data.calendarOptions.events = {
url: route('pickupsEvents'),
method: 'GET',
failure: error => {
console.log('tenemos este error: ', error.message);
}
}
},
methods: {
dateClick(arg){
this.$data.showModal = true;
this.setModalOpen(arg);
},
handleDateClick(clickInfo){
this.resetModal();
this.$data.showModal = true;
this.$emit('dateClick',clickInfo);
},
dayDrivers(date){
let calendarApi = this.$refs.fullCalendar.getApi()
const start = calendarApi.getDate().toISOString().split("T")[0];
axios.get(route('pickups.index',{date:start})).then(({data}) => {
// calendarApi.addResource(data);
this.$data.calendarOptions.resources = data;
//this.$refs.fullCalendar.getApi().refetchResources();
});
},
我找到了一个覆盖按钮的简单解决方案。
customButtons: {
prev: {
text: "prev",
click: () => {
let calendarApi = this.$refs.fullCalendar.getApi();
calendarApi.prev();
this.dayDrivers(calendarApi.getDate().toISOString().split("T")[0]);
}
},
next: {
text: "next",
click: () => {
let calendarApi = this.$refs.fullCalendar.getApi();
calendarApi.next();
this.dayDrivers(calendarApi.getDate().toISOString().split("T")[0]);
}
},
today: {
text: 'today',
click: () => {
let calendarApi = this.$refs.fullCalendar.getApi();
calendarApi.today();
this.dayDrivers(calendarApi.getDate().toISOString().split("T")[0]);
}
}
},