前言 📝
本文主要是记录一下上下班打卡的逻辑,该业务场景是通过管理端配置上下班打卡次数,例如:2次(上午上班、下午下班)、4次(上午上班、上午下班、下午上班、下午下班)、6次(上午上班、上午下班、下午上班、下午下班、加班上班、加班下班)。通过配置实现对应的打卡逻辑,当打过这个时间段的卡之后,并且目前还没有进入下一个时间段,这区间是不能再次进行打卡的。
具体的逻辑我也记不清楚了,虽然是自己写的。但是也忘的差不多了。本文主要是用于记录一下,下次如果遇到的情况,可以返回来回顾一下当时的逻辑,没准会有不一样的体验想法。
/**
* AttendanceTypeEnum枚举:{上午上班 = 1,上午下班 = 2,下午上班 = 4,下午下班 = 8,加班上班 = 16,加班下班 = 32},前端枚举,value和后端字段相呼应
* clockConfig: 后端返回的上下班打开配置 数据格式 { 1: '9:00', 8: '18:00' }、{ 1: '9:00', 2: '12:00', 4: '13:00', 8: '18:00' }...
* todayClockRecord:该人员近日打卡记录,格式和clockConfig一样
*/
// 上下班状态
const status = computed(() => {
const arr = Object.keys(clockConfig.value).sort()
// 打卡区段
if (arr.length === 2) {
// 上午上班 下午下班
// 该判断是是否在下午打卡区间,并且下午还没有打卡
const afterDownArea =
+new Date() > +timeCompare(clockConfig.value[+AttendanceTypeEnum.下午下班]) &&
+new Date() > +timeCompare('23:59:59') &&
!todayClockRecord.value[+AttendanceTypeEnum.下午下班]
// 上午上班打卡
if (!todayClockRecord.value[+AttendanceTypeEnum.上午上班]) {
return '上午上班'
} else if (afterDownArea) {
// 此时已经打了上班卡了-判断是否在下班打卡的区域内并且还没有进行下班打卡
return '下午下班'
} else {
// 进入此处说明 无论在那个区间端-上午已经打卡-下午已经打卡
return '无需打卡'
}
} else if (arr.length === 4) {
// 上午上班 上午下班 下午上班 下午下班
// 上午上班区间 00:00 - 上午下班之前
// 当前在上午上班区段并且没有进行上班打卡
const moringArea =
+new Date() > +timeCompare('00:00:00') &&
+new Date() < +timeCompare(clockConfig.value[+AttendanceTypeEnum.下午上班]) &&
!todayClockRecord.value[+AttendanceTypeEnum.上午上班]
// 上午下班-下午上班 并且没有进行下班打卡(如果没有进行的上班打卡的话,会走上一步)
const moringDownArea =
+new Date() > +timeCompare(clockConfig.value[+AttendanceTypeEnum.上午下班]) &&
+new Date() < +timeCompare(clockConfig.value[+AttendanceTypeEnum.下午上班]) &&
!todayClockRecord.value[+AttendanceTypeEnum.上午下班]
// 上午下班-23:59:59 并且下午上班没有打卡(下午的打卡逻辑不用管上午的)
const afterArea =
+new Date() > +timeCompare(clockConfig.value[+AttendanceTypeEnum.上午下班]) &&
+new Date() < +timeCompare('23:59:59') &&
!todayClockRecord.value[+AttendanceTypeEnum.下午上班]
// 当前在下午下班区段,同时也是下午上班的区段,必须要进行下午上班打卡才会进入此区域(如果下午上班没打卡,则进入到上一步)
const afterDownArea =
+new Date() > +timeCompare(clockConfig.value[+AttendanceTypeEnum.下午下班]) &&
+new Date() < +timeCompare('23:59:59') &&
!todayClockRecord.value[+AttendanceTypeEnum.下午下班]
if (moringArea) {
// 在上午上班区段内,并没有进行上班打卡
return '上午上班'
} else if (moringDownArea) {
// 上午上班以及打卡了-上午下班区间内-并且没有进行下班打卡
return '上午下班'
} else if (afterArea) {
// 在下午上班区间内-并且没有进行上班打卡
return '下午上班'
} else if (afterDownArea) {
// 当前在下午下班区段,同时也是下午上班的区段,必须要进行下午上班打卡才会进入此区域(如果下午上班没打卡,则进入到上一步)
return '下午下班'
} else {
return '无需打卡'
}
} else if (arr.length === 6) {
// 上午上班 上午下班 下午上班 下午下班 加班上班 加班下班
// 当前在上午上班区段并且没有进行上班打卡
const moringArea =
+new Date() > +timeCompare('00:00:00') &&
+new Date() < +timeCompare(clockConfig.value[+AttendanceTypeEnum.下午上班]) &&
!todayClockRecord.value[+AttendanceTypeEnum.上午上班]
// 上午下班-下午上班 并且没有进行下班打卡(如果没有进行的上班打卡的话,会走上一步)
const moringDownArea =
+new Date() > +timeCompare(clockConfig.value[+AttendanceTypeEnum.上午下班]) &&
+new Date() < +timeCompare(clockConfig.value[+AttendanceTypeEnum.下午上班]) &&
!todayClockRecord.value[+AttendanceTypeEnum.上午下班]
// 上午下班-加班上班之前
const afterArea =
+new Date() > +timeCompare(clockConfig.value[+AttendanceTypeEnum.上午下班]) &&
+new Date() < +timeCompare(clockConfig.value[+AttendanceTypeEnum.加班上班]) &&
!todayClockRecord.value[+AttendanceTypeEnum.下午上班]
// 当前在下午下班区段,同时也是下午上班的区段,必须要进行下午上班打卡才会进入此区域(如果下午上班没打卡,则进入到上一步)
const afterDownArea =
+new Date() > +timeCompare(clockConfig.value[+AttendanceTypeEnum.下午下班]) &&
+new Date() < +timeCompare(clockConfig.value[+AttendanceTypeEnum.加班上班]) &&
!todayClockRecord.value[+AttendanceTypeEnum.下午下班]
// 下午下班-23:59:59
const eveintArea =
+new Date() > +timeCompare(clockConfig.value[+AttendanceTypeEnum.下午下班]) &&
+new Date() < +timeCompare('23:59:59') &&
!todayClockRecord.value[+AttendanceTypeEnum.加班上班]
// 加班下班 - 23:59:59
const eveingDownArea =
+new Date() > +timeCompare(clockConfig.value[+AttendanceTypeEnum.加班下班]) &&
+new Date() < +timeCompare('23:59:59') &&
!todayClockRecord.value[+AttendanceTypeEnum.加班下班]
if (moringArea) {
// 在上午上班区段内,并没有进行上班打卡
return '上午上班'
} else if (moringDownArea) {
// 上午上班以及打卡了-上午下班区间内-并且没有进行下班打卡
return '上午下班'
} else if (afterArea) {
// 在下午上班区间内-并且没有进行上班打卡
return '下午上班'
} else if (afterDownArea) {
// 当前在下午下班区段,同时也是下午上班的区段,必须要进行下午上班打卡才会进入此区域(如果下午上班没打卡,则进入到上一步)
return '下午下班'
} else if (eveintArea) {
return '加班上班'
} else if (eveingDownArea) {
return '加班下班'
} else {
return '无需打卡'
}
}
return '无需打卡'
})
function timeCompare(str: string) {
// 创建一个表示当前时间的Date对象
const currentDate = new Date()
const targetDateStr = currentDate.toDateString() + ' ' + str
const targetDate = new Date(targetDateStr)
return targetDate
}