通过颜色区分任务完成状态
对于日历中的事件,通过不同颜色来区分任务是否完成。
先前尝试过使用任务的优先级来控制事件显示不同的颜色,效果并不好,颜色多了比较花哨,既影响信息有效展现,也影响美观,如下图所示:
最终采用只使用背景色来区分,任务完成(包括已完成和已取消)两种状态显示为灰色背景,其他状态显示为醒目的蓝色背景,边框色与背景色一致,避免出现一个框影响美观,文字使用白色,最终效果图如下:
需要调整设计到两个地方,一是任务数据加载的时候,二是动态修改单条任务的时候。
首先实现一个公共方法,通过任务状态计算颜色,如下:
// 计算事件颜色
calculateEventColor(status) {
// 根据状态设置不同的颜色,默认蓝底白字
let textColor = 'white'
let backgroundColor = '#0d6efd'
let borderColor = '#0d6efd'
switch (status) {
//已完成和已取消两种任务状态为灰底白字
case 'COMPLETED':
case 'CANCELED':
backgroundColor = 'gray'
borderColor = 'gray'
break
}
return {
backgroundColor: backgroundColor,
borderColor: borderColor,
textColor: textColor
}
}
然后在任务数据转换为事件时调用,如下:
// 任务数据转换为事件对象
convertTaskToEvent(task) {
// 计算全天事件属性值
const allDay = this.calculateAllDay(task.startTime, task.endTime)
// 根据状态设置不同的颜色
const color = this.calculateEventColor(task.status)
// 数据转换
return {
id: task.id,
title: task.name,
start: task.startTime,
end: task.endTime,
allDay: allDay,
textColor: color.textColor,
backgroundColor: color.backgroundColor,
borderColor: color.borderColor,
extendedProps: {
status: task.status,
plannedDuration: task.plannedDuration
}
}
}
还有就是动态修改单个任务的时候,需要通过setPro的API来实现,如下:
// 修改任务
modifyTask(task) {
const fullCalendar = this.$refs.fullCalendar.calendar
const event = fullCalendar.getEventById(task.id)
if (task.startTime && task.status != 'PENDING') {
// 开始时间有值,且状态不是待安排,更新任务信息
event.setProp('title', task.name)
event.setStart(task.startTime)
event.setEnd(task.endTime)
let allDay = this.calculateAllDay(task.startTime, task.endTime)
event.setAllDay(allDay)
event.setExtendedProp('status', task.status)
event.setExtendedProp('plannedDuration', task.plannedDuration)
// 根据状态设置不同的颜色
const color = this.calculateEventColor(task.status)
event.setProp('textColor', color.textColor)
event.setProp('backgroundColor', color.backgroundColor)
event.setProp('borderColor', color.borderColor)
} else {
// 开始时间无值或状态为待安排
// 从日历视图中移除任务
event.remove(task.id)
// 刷新收集箱列表
this.reloadCollectionBox()
}
}
解决新增事件重复问题
问题描述
使用过程中发现一个新问题,具体如下:
在周日历视图中,新增一个任务,保存,正常显示;
切换到月日历视图中,该任务会显示两次,如下所示:
并且再切换到周视图或日视图,该任务都会重复显示:
原因分析
依据前面的经验,切换视图时,若时间范围变大,FullCalendar将会自动调用后端服务,获取相应范围内的数据加载和显示,问题在于,该加载并没有处理同一事件的合并问题,
解决方案
尝试调用FullCalendar的render事件来刷新,无效。
查找官方文档,没找到清空事件的api。
然后查看addEvent方法时,有了新发现,该方法第二个参数可以指定数据源,相关描述如下:
source represents the Event Source you want to associate this event with. When the source is refetched, it will clear the dynamically added event from the internal cache before fetching. This optional parameter can be specified as any of the following:
- an Event Source ID string
- an Event Source Object
- true, which signifies the first event source
大意是指定一个数据源,当重新获取(refetched)时,会将动态添加的事件从内部缓存中清空。
这也是为什么通过addEvent方法动态添加的事件,在切换视图的时候为什么会重复显示了。
但是我们给日历组件FullCalendar设置事件是指定event属性为方法,当切换视图时会自动调用,并没有使用事件源,也没有调用refetch方法,这种方式下能有用吗?
尝试调整新增任务方法,将addEvent方法多传一个参数,设置为true,如下:
// 新增任务
addTask(task) {
// 获取日历对象
const fullCalendar = this.$refs.fullCalendar.calendar
// 将任务数据转换为日历事件
const event = this.convertTaskToEvent(task)
// 调用api添加任务
fullCalendar.addEvent(event, true)
}
测试发现,功能正常了,在周视图动态添加的任务,切换到月视图后不会重复显示两遍,问题解决。
应用系统
名称:遇见
地址:https://meet.popsoft.tech
说明:基于一二三应用开发平台和FullCalendar日历组件实现的面向个人的时间管理、任务管理系统,1分钟注册,完整功能,欢迎使用~