🍊 vue3实现上下班打卡逻辑(打卡次数可配置)

145 阅读5分钟

原文地址: alvis.org.cn/posts/efc40…

前言 📝

本文主要是记录一下上下班打卡的逻辑,该业务场景是通过管理端配置上下班打卡次数,例如: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
}