FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)

(基于vue)实现效果

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)

文章目录

前言

一、FullCalendar是什么?

二、使用步骤

1.引入库

2.html部分代码

3.css样式代码(样式我单独写个scss文件引入的)

4.逻辑代码部分 

总结


前言

闲来无事搞个排班排课表,之前貌似遇到过这类的需求,只不过没做上。主要用的就是FullCalendar插件。基于vue框架写法。

基本的功能可以新建个日程看看样式,可以拖拽日程进去。


提示:以下是本篇文章正文内容,下面案例可供参考

一、FullCalendar是什么?

Fullcalendar是一个非常受欢迎的日历日程处理的js组件,它功能强大,文档齐全,可定制化高,可与你的项目无缝对接。

官网链接:https://fullcalendar.io/demos

主要是针对于jq为基础写的插件,官网文档是全英文的,所以还要靠万能的度娘。

这里附个链接,在Vue框架下使用Fullcalendar_Helloweba

里面是详细讲解用vue写法的插件用法,只不过我原封照搬的时候遇到很多问题,后面我会总结一下。

二、使用步骤

1.引入库

代码如下(示例):

npm install @fullcalendar/core

npm install @fullcalendar/vue

npm install @fullcalendar/daygrid

npm install @fullcalendar/interaction

npm install @fullcalendar/timegrid

npm install @fullcalendar/list

(这个也可以一次npm install 由于我一次性安装出问题了我就一个一个安装的)

import '@fullcalendar/core'; // solves problem with Vite
import FullCalendar from '@fullcalendar/vue';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin,{ Draggable } from '@fullcalendar/interaction';
import timeGridPlugin from '@fullcalendar/timegrid';
import listPlugin from '@fullcalendar/list';
import moment from "moment";


2.html部分代码

这部分没啥说的,做的页面布局,我搞的都是纯静态的,有需要的直接复制粘贴就行,css样式我是用scss文件引入的,代码放在下面。

  
    
      
      + 新建日程
    
    
      
        
          日程状态图例
          
            未开始
            进行中
            已完成
            已延时
          
        
        
            可拖动列表
            
              
                  {{ item.name }}
                  {{ item.value }}
              
          
        
      
      
        
          
        
      
    
    
    
        
          
            
          
          
            
              
              
              
              
            
          
          
            
              
              
            
          
        
        
          取 消
          确 定
        
  
  

3.css样式代码(样式我单独写个scss文件引入的)

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)

.calendar{
    padding: 0 20px;
    .el-button{
        width: 100px;
    }
 .calendar_header{
    display: flex;
    margin: 30px 0;
    .el-input{
        width: 200px;
        margin-right: 16px;
    }
 }  
 .calendar_body{
    display: flex;
    .calendar_body_left{
        display: flex;
        flex-direction: column;
        width: 10%;
        .el-button{
            margin-left: 0 !important;
            color: #fff;
            margin-bottom: 4px;
        }
        .unstart_btn{
            background-color: #ffcc99;
        }
        .doing_btn{
            background-color: #5580ee;
        }
        .success_btn{
            background-color: #87d068;
        }
        .delay_btn{
            background-color: #FF0033;
        }
    }
    .calendar_body_right{
        width: 85%;
    }
 }
 .el-dialog{width: 30%;}
 .el-date-editor.el-range-editor.el-input__inner.el-date-editor--datetimerange{
    width: 100%;
 }
 .el-select{
    width: 100%;
 }
 .calendar_body_left_top{
    .calendar_body_left_top_title{
        margin-bottom: 15px;
        font-size: 18px;
        font-weight: bolder;
    }
 }
 .calendar_body_left_bottom{
    padding: 0 25px;
    margin-top: 20px;
    .calendar_body_left_bottom_title{
        font-size: 18px;
        font-weight: bolder;
    }
     .circle {
        background-color: #3788d8;
        border-radius: 10px;
        color: #fff;
        display: inline-block;
        font-size: 12px;
        height: 18px;
        line-height: 18px;
        padding: 0 6px;
        text-align: center;
        white-space: nowrap;
        border: 1px solid #fff;
      }
      .holiday {
        background-color: #FF6600;
      }
      .work{
        background-color: #66CCCC;
      }
      .date-box {
        //border: 1px solid #ccc;
        border-radius: 5px;
      }
      .box {
        margin-top:15px;
        border: 1px solid #FFFFCC;
        padding: 10px 20px;
        border-radius: 5px;
        display: flex;
        justify-content: space-between;
        cursor: pointer;
        background-color: #FFFFCC;
      }
 }
}

4.逻辑代码部分 

先上代码

// @ is an alias to /src
import "@/assets/css/calendar.scss"

import '@fullcalendar/core'; // solves problem with Vite
import FullCalendar from '@fullcalendar/vue';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin,{ Draggable } from '@fullcalendar/interaction';
import timeGridPlugin from '@fullcalendar/timegrid';
import listPlugin from '@fullcalendar/list';
import moment from "moment";

export default {
  name: 'Home',
  components: {
  FullCalendar
  },
  data() {
  return {
    n:4,
    searchVal:'',
    dialogFormVisible:false,
    formLabelWidth: '120px',
      form:{
        name: '',
        date: '',
        status:'',
      },
      rules: {
          name: [
            { required: true, message: '请输入日程名称', trigger: 'blur' },
            // { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
          ],
          date: [
            { required: true, message: '请选择日期', trigger: 'change' }
          ],
          status: [
            { required: true, message: '请选择日程状态', trigger: 'change' }
          ]
    },
    testData:[{
            id: 1,
            title: '任务1未开始',
            start: '2023-04-06 10:30:00',
            end: '2023-04-07 10:30:00',
            // color: '#ffcc99',
            status:'unstart',
            editable: true, //允许拖动缩放,不写默认就是false
            overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false
        },{
            id: 2,
            title: '任务2进行中',
            start: '2023-04-06 10:30:00',
            end: '2023-04-08 10:30:00',
            // color: '#5580ee',
            status:'doing',
            editable: true, //允许拖动缩放
            overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false
        },{
            id: 3,
            title: '任务3已完成',
            start: '2023-04-09 10:30:00',
            end: '2023-04-09 18:30:00',
            // color: '#87d068',
            status:'success',
            editable: true, //允许拖动缩放
            overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false
        },{
            id: 4,
            title: '任务4已延时',
            start: '2023-04-18 10:30:00',
            end: '2023-04-18 10:30:00',
            // color: '#ff99b3',
            status:'delay',
            editable: true, //允许拖动缩放
            overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false
        }],
      // 可拖动列表数据
      list: [
        // { name: '删除假日', value: '0', color: 'blue'  }
        { name: '工作日1', value: '1', status: 'work' },
        { name: '工作日2', value: '5', status: 'work' },
        { name: '春节放假', value: '7', status: 'holiday' },
        { name: '中秋节放假', value: '3', status: 'holiday'  },
        { name: '国庆节放假', value: '7', status: 'holiday'  },
      ],
    calendarOptions: {
      plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin, listPlugin],
      initialView: 'dayGridMonth',
      locale: 'zh-cn', //? 配置中文
      firstDay: 1,// 把每周设置为从周一开始
      initialDate: moment().format("YYYY-MM-DD HH:mm:ss"), // 自定义设置背景颜色时一定要初始化日期时间
      aspectRatio: 2.6, // 设置日历单元格宽度与高度的比例。
      buttonText: {/* 设置按钮文字 */
        today: '今天',
        month: '月',
        week: '周',
        day: '日',
        list: '周列表',
      },
      headerToolbar: {//日历头部
        left: 'prev,next today',
        center: 'title',
        right: 'dayGridMonth,timeGridWeek,timeGridDay listWeek',
      },
      selectable: true,//可编辑
      // dayMaxEvents: true,
      // slotMinutes: 15,
      editable: false, // 日历上是否可拖拽
      droppable: true,
      dropAccept: '.list-group-item',
      drop: this.drop,
      height: 650,
      validRange: this.validRange,  //设置可显示的总日期范围
      events: [], //背景色 (添加相同时间的背景色时颜色会重叠)
      datesSet: this.datesSet, //日期渲染;修改日期范围后触发
      eventClick: this.handleEventClick, //点击日程触发
      dateClick: this.handleDateClick, //点击日期触发
      eventDrop: this.calendarEventDropOrResize, //拖动事件触发
      eventResize: this.calendarEventDropOrResize, //缩放事件触发
      displayEventTime: false, //不显示具体时间
    },
    validRange: {
      start: '2023-01-01 ',
      end: moment().add(6, 'months').format('YYYY-MM-DD HH:mm:ss'),
    },
    new_startDate:'',
    new_endDate:'',
  }
},
mounted() {
  // 初始化日历 调用获取视图活动数据方法
  this.datesSet();

  // 拖拽
  var containerEl = document.getElementById('list-group-item');
    // 初始化外部事件
    new Draggable(containerEl, {
        itemSelector: '.list-group-item',
      }
    )
},
methods: {
  datesSet(info) {   //注意:该方法在页面初始化时就会触发一次
      // console.log(info)
      // this.search()  //请求本页数据
      //虚拟数据
      this.testData.forEach((item,index) => {
        // console.log('item',item)
          if(item.status == 'unstart'){
            this.$set(item,"color", "#ffcc99")
        }else if(item.status == 'doing'){
          this.$set(item,"color", "#5580ee")
        }else if(item.status == 'success'){
          this.$set(item,"color", "#87d068")
        }else if(item.status == 'delay'){
          this.$set(item,"color", "#FF0033")
        }else if(item.status == 'work'){
          this.$set(item,"color", "#66CCCC")
        }else{
          this.$set(item,"color", "#FF6600")
        }
      });
      this.calendarOptions.events = this.testData
      this.list.forEach((item,index) => {
        if(item.status == 'work'){
          this.$set(item,"color","#66CCCC")
        }else{
          this.$set(item,"color","#FF6600")
        }
      })
    },
  dialogAdd(){
    this.dialogFormVisible = true
  },
  submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            this.dialogFormVisible = false;
            this.n ++
            // console.log('date',this.form.date)
            let obj = {
              id: Number(this.n),
              title: String(this.form.name),
              start: String(this.form.date[0]),
              end: String(this.form.date[1]),
              // color: '#ff99b3',
              status:String(this.form.status),
              editable: true, //允许拖动缩放
              overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false
          }
            this.testData.push(obj)
            this.datesSet();
            // console.log('this.calendarOptions.events',this.calendarOptions.events)
          } else {
            console.log('error submit!!');
            return false;
          }
        });
  },
  // 转换时间格式
  parseTime(date) {
    const yy = date.getFullYear()
				const MM = (date.getMonth() + 1) < 10 ? '0' + (
                    date.getMonth() + 1) : (date.getMonth() + 1)
				const dd = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
				const HH = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
				const mm = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
				const ss = date.getSeconds()  0
      console.log('date',date)
      date.draggedEl.remove()
      this.n ++
      const obj = {
        // dayNum: date.draggedEl.lastChild.innerHTML,
          id: Number(this.n),
          title: String(date.draggedEl.firstChild.innerHTML),
          start: Date.parse(moment(date.dateStr).format()), // 开始时间
          end: Date.parse(moment(date.dateStr).add(date.draggedEl.lastChild.innerHTML, 'days').format()), // 结束时间
          // color: '#ff99b3',
          status:isWork ? 'work' : 'holiday',
          editable: true, //允许拖动缩放
          overlap: true, //允许时间重叠,即可以与其他事件并存,不写默认就是false
      }
      this.testData.push(obj)
      this.datesSet();
      // console.log(this.calendarOptions.events)
      // console.log('date.draggedEl.lastChild.innerHTML',date.draggedEl.lastChild.className.indexOf('holiday'))
    }
}

};

 5.踩坑部分

以上代码直接cv应该就可以实现一个静态的日历排班表了。下面来说说我实现的过程遇到那些问题:

(1)这一块看别人写的都是 import ‘@fullcalendar/core/vdom’ // solves problem with Vite

但是咱是vue2写的不适用。但是nodemodules包中有core文件我就把后面去掉了

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)

(2)在安装的时候总是会出现以下报错

viewType “” is not available. Please make sure you’ve loaded all neccessary plugins

不要指定安装版本直接install就行。报错不行就全部uninstall,重新下载。package.json文件里面没了才是卸载完成。我遇到的问题就是一次性下载后报错,我没卸载,看别人的版本可以,我直接又下载了别人的版本,结果还是不行,一定卸载干净再重新下载。我觉得安装我上面的代码应该不会报错,前提是你的node版本什么的和我差不多哈哈

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)

(3)这块这些Fullcalendar日历插件的事件的Info可以打印出当前拖拽的信息,比如拖拽前后的时间,还有样式什么的都可以在这里修改。打印出来附在下面啦        event就是拖拽后的信息,oldevent就是拖拽前的。我主要拿时间所以截图下面了。

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课) FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)(4)drop这块的拖拽主要是实现将左侧可拖拽列表中的日程拖放到Fullcalendar日历中。拖拽左侧日程块后打印date也可以获得好多有用的信息啦

FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课) FullCalendar 日历插件排班表排课表保姆级详解(可拖动排班排课)


总结

以上就是实现简易排班排课表的雏形啦,复杂的功能还是要基于数据啦,静态只是看看大概。先说这么多,后面有坑我再写;以及后面看看能不能再加上些好玩的功能。

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/ee3d7cb48d.html