日程安排也是OA里的一项重要功能,所以基于jeecgboot开发这个日程安排。
日程安排主要涉及以下几个方面:
1、数据库方面,主要是分日历与日程
日历可以分个人日历与工作日历,一般情况下,个人日历只给自己查看,当然也可以考虑把个人日历分享给其它人员查看,工作日历可以让多人分享查看或管理,同时为了区分,可以通过颜色进行区分,不输入所有者与参与者,默认自己就是所有者与参与者。
通过上面建的日历来建日程,相应的拥所有者或参与者默认就从上面日历继承过来,颜色也一样。
提醒级别分为1-重要/紧急,2-重要/不紧急,3-不重要/紧急,4-不重要/不紧急。
提醒时间分为不提醒,提前5分钟,10分钟,15分钟,30分钟,1小时,2小时7种。
提醒方式分为消息提醒,邮件提醒,短信提醒,微信提醒等4种。
数据库结构如下:
/* Navicat MySQL Data Transfer Source Server : 本地开发虚拟机数据库 Source Server Version : 50721 Source Host : 192.168.199.151:3306 Source Database : nbcio-boot Target Server Type : MYSQL Target Server Version : 50721 File Encoding : 65001 Date: 2023-05-03 12:02:14 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for oa_calendar -- ---------------------------- DROP TABLE IF EXISTS `oa_calendar`; CREATE TABLE `oa_calendar` ( `id` varchar(36) NOT NULL COMMENT 'id', `name` varchar(100) NOT NULL COMMENT '名称', `remark` text COMMENT '备注', `color` varchar(15) NOT NULL COMMENT '颜色', `create_by` varchar(50) DEFAULT NULL COMMENT '创建人', `create_time` datetime DEFAULT NULL COMMENT '创建日期', `update_by` varchar(50) DEFAULT NULL COMMENT '更新人', `update_time` datetime DEFAULT NULL COMMENT '更新日期', `sys_org_code` varchar(64) DEFAULT NULL COMMENT '所属部门', `type` int(10) NOT NULL COMMENT '日历类型', `owner` text COMMENT '所属人', `taker` text COMMENT '参与人', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- ---------------------------- -- Table structure for oa_schedule -- ---------------------------- DROP TABLE IF EXISTS `oa_schedule`; CREATE TABLE `oa_schedule` ( `id` varchar(36) NOT NULL COMMENT 'id', `title` varchar(100) DEFAULT NULL COMMENT '标题', `content` text COMMENT '内容', `start_time` datetime DEFAULT NULL COMMENT '开始时间', `end_time` datetime DEFAULT NULL COMMENT '结束时间', `owner` text COMMENT '所属人', `taker` text COMMENT '参与人', `remind` int(10) DEFAULT NULL COMMENT '提前提醒时间', `address` varchar(100) DEFAULT NULL COMMENT '地点', `color` varchar(15) DEFAULT NULL COMMENT '颜色', `source` varchar(50) DEFAULT NULL COMMENT '来源', `level` int(10) DEFAULT NULL COMMENT '优先级', `create_by` varchar(50) DEFAULT NULL COMMENT '创建人', `create_time` datetime DEFAULT NULL COMMENT '创建日期', `update_by` varchar(50) DEFAULT NULL COMMENT '更新人', `update_time` datetime DEFAULT NULL COMMENT '更新日期', `sys_org_code` varchar(64) DEFAULT NULL COMMENT '所属部门', `url` varchar(200) DEFAULT NULL COMMENT '链接', `cal_id` varchar(36) DEFAULT NULL COMMENT '日历类型', `remind_type` varchar(30) DEFAULT NULL COMMENT '提醒方式', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2、前端组件采用 FullCalendar
FullCalendar提供了丰富的属性设置和方法调用,开发者可以根据FullCalendar提供的API快速完成一个日历日程的开发。
在package.json增加下面组件
"@fullcalendar/core": "^5.11.3", "@fullcalendar/daygrid": "^5.11.3", "@fullcalendar/interaction": "^5.11.3", "@fullcalendar/list": "^5.11.3", "@fullcalendar/moment": "^5.11.3", "@fullcalendar/resource-timeline": "^5.11.3", "@fullcalendar/scrollgrid": "^5.11.3", "@fullcalendar/timegrid": "^5.11.3", "@fullcalendar/vue": "^5.11.2",
考虑到中国农历问题,增加下面组件
"solarday2lunarday": "^1.12.1",
主要使用如下:
<template> <div style="background:#FFF;"> <a-button @click="handleAdd" style="margin-bottom: 20px" type="primary">新建日程</a-button> <FullCalendar class="fullCalendar" @eventDrop="handleDrop" ref="fullCalendar" :options="calendarOptions" /> <oa-schedule-modal ref="modalForm" @ok="modalFormOk"></oa-schedule-modal> </div> </template> <script> import FullCalendar from "@fullcalendar/vue"; import dayGridPlugin from "@fullcalendar/daygrid"; import interactionPlugin from "@fullcalendar/interaction"; import listPlugin from '@fullcalendar/list'; import timeGridPlugin from "@fullcalendar/timegrid"; import momentPlugin from "@fullcalendar/moment"; import resourceTimelinePlugin from "@fullcalendar/resource-timeline"; import scrollgridPlugin from "@fullcalendar/scrollgrid"; var moment = require("moment"); // import calenderFormate from "../utils/calendar"; import calendar from "solarday2lunarday"; import { JeecgListMixin } from '@/mixins/JeecgListMixin'; import OaScheduleModal from './modules/OaScheduleModal'; import { GetList } from '@/api/oa/schedule'; import estar from '../util/estar'; export default { mixins:[JeecgListMixin], components: { FullCalendar, // 像使用自定义组件一样使用 OaScheduleModal, }, data() { return { form: { title: "", start: "", end: "", }, isDay: false, isWeek: false, isMonth: true, custom: null, day: null, week: null, month: null, findRoom: false, calendarApi: null, calendarOptions: { plugins: [ dayGridPlugin, interactionPlugin, listPlugin, momentPlugin, timeGridPlugin, resourceTimelinePlugin, scrollgridPlugin, ], // 需要用哪个插件引入后放到这个数组里 // initialDate: new Date(), // 日历第一次加载时显示的初始日期。可以解析为Date的任何职包括ISO8601日期字符串,例如"2014-02-01"。 initialView: "dayGridMonth", // 日历加载时的初始视图,默认值为'dayGridMonth',可以为任何可用视图的值,如例如'dayGridWeek','timeGridDay','listWeek' locale: "zh-cn", // 设置日历的语言,中文为 “zh-cn” firstDay: "1", // 设置每周的第一天,默认值取决于当前语言环境,该值为代表星期几的数字,且值必须为整数,星期日=0 // weekNumberCalculation: 'ISO', // 指定"ISO"结果为ISO8601周数。指定"ISO"将firstDay的默认值更改为1(Monday) buttonText: { // 文本将显示在headerToolbar / footerToolbar的按钮上。不支持HTML注入。所有特殊字符将被转义。 today: "今天", month: "月", week: "周", day: "日", list: '周列表' }, editable: true, eventDrop: this.DropEvent, dayMaxEvents: true, // 在dayGrid视图中如果每个单元格事件超出单元格会出现'+more' moreLinkContent: "查看更多", // 点击+more触发该回调 moreLinkClick: this.eventLimitClickFun, // unselectAuto: true, selectable: true, // 允许用户点击或拖拽选中 // dayHeaderContent: this.columnHeaderHtmlFun, headerToolbar: { // 在日历顶部定义按钮和标题。将headerToolbar选项设置为false不会显示任何标题工具栏。可以为对象提供属性start/center/end或left/center/right。这些属性包含带有逗号/空格分隔值的字符串。用逗号分隔的值将相邻显示。用空格分隔的值之间会显示一个很小的间隙。 // right: "today prev next title", start: "today prev next", end: "dayGridMonth,timeGridWeek,timeGridDay listWeek,custom", center: "title", }, // header :{ // // left: "today prev next title", // left: 'today prev next title ', // center: '', // right: "agendaDay,agendaWeek,month,custom", // // right: 'custom, month,agendaWeek,agendaDay' // }, views: { dayGridMonth: { displayEventTime: false, dayCellContent(item) { //console.log("data", item); let _date = moment(item.date).format("YYYY-MM-DD"); let startDate = ""; _date = _date.split("-"); startDate = _date[2]; let _dateF = calendar.solar2lunar(_date[0], _date[1], _date[2]); let _dateS = ""; //console.log("_dateF", _dateF); if (startDate[0] == "0") { startDate = startDate[1]; } else { startDate = startDate; } if (_dateF.Term !== "") { _dateS = _dateF.Term; } else { _dateS = _dateF.IDayCn; } return { html: `<p style="letter-spacing: 1px;margin-top: 7.5px;"><label>${startDate}</label><span style="margin-left:2px">${_dateS}</span></p>`, }; }, }, }, // displayEventTime:false, eventTimeFormat: { // 在每个事件上显示的时间的格式 hour: "numeric", minute: "2-digit", hour12: false, }, events: [], //eventColor: "#f08f00", // 修改日程背景色 // events: [ // 将在日历上显示的事件对象, events 可以是数组、json、函数。具体可以查看官方文档 // title: '标题', // start: '事件开始事件', // end: '事件结束事件', // 这里要注意,end为可选参数,无end参数时该事件仅在当天展示 // backgroundColor: '#FDEBC9', // 该事件的背景颜色 // borderColor: '#FDEBC9', // 该事件的边框颜色 // textColor: '#F9AE26' // 该事件的文字颜色 // ], customButtons: { // 定义可在headerToolbar / footerToolbar中使用的自定义按钮 today: { text: "今天", // 按钮的展示文本 click: this.todayClick, // 点击按钮触发的事件,这里要注意的是当按钮绑定了事件之后该按钮原本自带的事件将会失效 }, next: { click: this.nextClick, }, prev: { click: this.prevClick, }, timeGridDay: { text: "日", click: this.dayView, }, timeGridWeek: { text: "周", click: this.weekView, }, dayGridMonth: { text: "月", click: this.monthView, }, }, datesSet: this.datesSet, eventClick: this.handleEventClick, // 点击事件时,触发该回调 // eventDrop:this.handleDrop, eventMouseEnter: this.handleMouseEnter, // 鼠标悬停在事件上时,触发该回调 eventMouseLeave: this.handleMouseLeave, // 鼠标移除时,触发该回调 dateClick: this.handleDateClick, // 当用户单击日期或时间时,触发该回调,触发此回调,您必须加载interaction插件 }, startTime: '', endTime: '', }; },
界面如下: