Fullcalendar日历使用,包括视图选择、事件插入、编辑事件、事件状态更改、事件添加和删除、事件拖动调整,自定义头部,加入el-popover显示图片、图片预览、添加附件链接等,支持手机显示。
•
前端
Fullcalendar这个插件挺好,就是很多方法感觉官方文档也没怎么说,导致上手难度大,而且有些默认事件真的不太友好…废话不多说,先上效果图!
1、效果GIF
1.1 基本按钮功能

1.2 事件hover显示

1.3 事件添加、编辑、状态修改

1.4 日历事件搜索

2、 代码实现
2.1 Fullcalendar日历、el-popover弹窗
Fullcalendar@5.11.3引入后,要设置一大堆参数calendarOptions,包括显示时间区域、默认视图、是否显示全天类型、中文界面、事件的操作函数等,具体的一些设置内容,见下面代码的注释。
{{ arg.event.extendedProps.isDone == false ? "未开始" : "已完成" }} {{ arg.event.allDay == true ? "全天" : formatTimer(arg.event.start) }} 加载中... {{ arg.event.title }} {{ arg.event.extendedProps.address == null ? "" : arg.event.extendedProps.address.replace( "D:\\flask\\upload\\", "" ) }} {{ arg.timeText }} {{ arg.event.title }}
在这里,鼠标在事件上面经过时,会显示一个弹出窗,如下图。可见,弹出框有:是否已完成,开始时间,图列说明(可以是图片、GIF等),文字说明、链接或是附件。以上的这些都是用el-popover实现,用了v-slot:eventContent="arg",将日历的数据进行处理。图片的显示需要修改源码才能显示,不然有bug显示不出来,修改的源码见此文章第3节内容。

2.2 Fullcalendar日历自定义头部
在calendarOptions设置里,修改headerToolbar,设置为false。

然后写好自己的html代码,并调整好css样式。

绑定自定义按钮的函数功能,主要是利用了calendarApi自带的函数功能,包括视图切换、月日视图切换、往前和往后功能等,当然搜索功能是自己定义的。

2.3 搜索功能
这里是onSearch函数功能,主要是在前端对events的过滤,然后再设置视图为list视图,注意这个视图在日历头部的功能区是没有的,但是是Fullcalendar内置的。当搜索框为空或者清空搜索字符后,需要重新请求后端数据。 

3、Fullcalendar源码修改
3.1 修改源码main.js的地址:
3.2 添加的show_pic函数/方法:
CalendarApi.prototype.show_pic = function (arg) {
var state = this.getCurrentData();
this.unselect();
// 出现图片的关键
this.dispatch({
type: 'CHANGE_DATE',
dateMarker: state.dateEnv.createMarker(arg.view.currentStart),
});
};
4、Vue源码
{{ title }}
今天 月 周 日 列表 {{ arg.event.extendedProps.isDone == false ? "未开始" : "已完成" }} {{ arg.event.allDay == true ? "全天" : formatTimer(arg.event.start) }} 加载中... {{ arg.event.title }} {{ arg.event.extendedProps.address == null ? "" : arg.event.extendedProps.address.replace( "D:\\flask\\upload\\", "" ) }} {{ arg.timeText }} {{ arg.event.title }} 事件 已完成 未确认 ![]()
确 定 取 消
5、 后端Flask源码
from flask import Flask, render_template,\
request, jsonify, make_response, Response, send_file,session,send_from_directory
from flask_cors import CORS
import datetime
import json
import pypyodbc
from collections import deque
import os
import base64
import hashlib
import xlwt
import openpyxl
import xlrd
app = Flask(__name__,
static_folder='./templates/static', # 设置静态文件夹目录
template_folder="./templates") # 设置vue编译输出目录dist文件夹,为Flask模板文件目录
# 解决后端跨域问题,不然会在前端网页控制台显示“ccess to XMLHttpRequest at 'http://localhost:8080/api/login' from origin 'null' has been blocked”
CORS(app, supports_credentials=True)
session = {}
@app.route('/')
def index():
return render_template('index.html',name='index') #使用模板插件,引入index.html。此处会自动Flask模板文件目录寻找index.html文件。
@app.route('/calendar/eventRecord', methods=["GET", "POST"])
def calendar_evnetRecord():
params = request.values
date = json.loads(params["dateRange"])
startTime = datetime.datetime.strptime(date[0],"%Y-%m-%d %H:%M:%S")
endTime = datetime.datetime.strptime(date[1],"%Y-%m-%d %H:%M:%S")
# print(params)
conn = get_conn()
cur = conn.cursor()
sql = "insert into 记事本(allDay, startStr,endStr, title, type, isDone, userName,img,address) values(%s, '%s','%s','%s','%s',%s,'%s','%s','%s')" \
%(params["isAllDay"],startTime,endTime,params["remark"],params["type"],params["isDone"],params["userName"],params["img"],params["address"])
cur.execute(sql)
cur.commit()
cur.close()
conn.close()
return jsonify({"code":200})
@app.route('/calendar/getCalendarList', methods=["GET", "POST"])
def calendar_getCalendarList():
params = request.values
conn = get_conn()
cur = conn.cursor()
sql = "select ID,title,Format(startStr, 'yyyy-MM-dd HH:mm:ss'),Format(endStr, 'yyyy-MM-dd HH:mm:ss'),allDay,isDone,img,address,type " \
"from 记事本 "
cur.execute(sql)
data = cur.fetchall()
cur.close()
conn.close()
return jsonify({"code":200,"data":data})
@app.route('/calendar/submit', methods=["GET", "POST"])
def calendar_submit():
params = request.values
date = json.loads(params["dateRange"])
startTime = datetime.datetime.strptime(date[0],"%Y-%m-%d %H:%M:%S")
endTime = datetime.datetime.strptime(date[1],"%Y-%m-%d %H:%M:%S")
conn = get_conn()
cur = conn.cursor()
sql="update 记事本 set startStr='%s',endStr='%s',title='%s',type='%s',isDone=%s,userName='%s',img='%s',address='%s' where ID=%s"\
%(startTime,endTime,params["remark"],params["type"],params["isDone"],params["userName"],params["img"],params["address"]
,params["id"])
cur.execute(sql)
cur.commit()
cur.close()
conn.close()
return jsonify({"code":200})
@app.route('/calendar/checked', methods=["GET", "POST"])
def calendar_checked():
params = request.values
status = True if params["status"] == "false" else False
conn = get_conn()
cur = conn.cursor()
sql = "update 记事本 set isDone=%s where ID=%s" %(status,params["id"])
cur.execute(sql)
cur.commit()
cur.close()
conn.close()
return jsonify({"code": 200, "info":"状态修改成功!"})
@app.route('/calendar/remove', methods=["GET", "POST"])
def calendar_remove():
matters_id = request.values.get("0")
conn = get_conn()
cur = conn.cursor()
sql = "delete from 记事本 where ID=%s" % (matters_id)
try:
cur.execute(sql)
cur.commit()
return jsonify({"code": 200, "info":"删除成功!"})
except Exception as e:
return jsonify({"code": 200, "info":"发生错误!错误代码:"+str(e)})
finally:
cur.close()
conn.close()
@app.route('/calendar/updateTime', methods=["GET", "POST"])
def calendar_updateTime():
params = request.values
conn = get_conn()
cur = conn.cursor()
sql = "update 记事本 set startStr='%s',endStr='%s' where ID=%s" %(params["Start"],params["End"],params["id"])
cur.execute(sql)
cur.commit()
cur.close()
conn.close()
return jsonify({"code": 200, "info": "事件时间修改成功!"})
@app.route('/get_file_download', methods=["GET", "POST"])
def get_file_download():
file_url = request.values.get("0")
with open(file_url, 'rb') as file_f:
res = make_response(file_f.read()) # 用flask提供的make_response 方法来自定义自己的response对象
# res.headers['Content-Type'] = 'image/jpg' # 设置response对象的请求头属性'Content-Type'为图片格式
return res
if __name__ == '__main__':
# 0.0.0.0 表示同一个局域网均可访问,也可以替换成本机地址:通过命令行命令:ipcofig 获取
app.run(host='0.0.0.0', port='5000', debug=True)
6 、数据库数据(ACCESS)格式

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