「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战」。
前言
最近接到了一个比较有意思的需求,计算一个员工在规定时间上下班的总时长。我觉得挺有意思的 特此分享给大家。
分析需求
- 用户可以自定义上班打卡的时间以及下班打卡的时间。 当上班打卡时间大于下班打卡时间时,用户为次日下班打卡
- 用户还可以自定义一个最早上班打卡的时间 以及一个最晚下班打卡的时间,最早上班打卡时间晚于上班打卡时间
- 最晚下班打卡时间不得早于下班打卡时间。
- 用户还可以定义多个时间段的休息时间。 比如早上9:00到下午6:00会有一个休息时间。产品这边没有强制要求休息时间的可选范围。
- 计算出用户的总工作时长(上班打卡时间~下班打卡时间区间的总时长 - 各休息时间区间之和)
该需求存在一些不完美的地方:
- 时间区间的选择是不存在跨日期的。前端的页面交互UI只涉及到了小时和分钟
- 休息时间可自定义时间范围(正常是应该在工作时间段内的。)
- 休息时间的重复区间
产品既然没有做这些需求 我们也就不强求 ~ ha ha
综上所述~我们可以定义出6个字段:上班打卡时间、下班打卡时间、最早上班打卡时间、最晚下班打卡时间、休息时间、工作总时长。
定义数据对象
// workTime.vue ..省略 template
<script>
export default {
name:'workTime',
data(){
return {
form:{
//上班打卡时间
signIn:'',
//下班打卡时间
signOut:'',
//最早上班打卡时间
earliestSignIn:'',
//最晚下班打卡时间
earliestSignOut:'',
},
//restTime 休息区间 定义为 数组
restTime: [{startTime:'0000',endTime:'0000'}]
},
computed:{
totalWorkTime(){
return this.calcTotalTime()
}
}
},
methods:{
calcTotalTime(){
}
}
}
</script>
由于工作总时长是根据其他时长动态变化的。 因此我们可以将工作总时长定义在computed中。
下面我们来实现calcTotalTime这个方法:
//...忽略
calcTotalTime() {
const {signIn,signOut} = this.form
//只有用户选择了上班打卡时间和下班打卡时间 总时长才会有值
if (signIn && signOut) {
//使用moment.js获取到上班打卡时间
const _signInTime = this.moment(signIn, 'HH:mm').valueOf()
//使用moment.js获取到下班打卡时间
const _signOutTime = this.moment(signOut, 'HH:mm').valueOf()
//定义一个变量 获取上下班时间的时间戳间隔
let betweenDate = 0;
//然后我们需要判断 下班打卡时间是否小于上班打卡时间 如果小于则说明 用户选择的下班打卡时间是次日
if (_signOutTime < _signInTime) {
// 24小时 - 上班打卡时间 + 下班打卡时间 = 用户当日到次日所打卡的总时长
betweenDate = Number((24 * 3600 * 1000) - _signInTime) + Number(_signOutTime)
} else {
//如果不是次日签到 则直接用 下班打卡时间 - 上班打卡时间 = 用户当日打卡总时长
betweenDate = Number(_signOutTime - _signInTime)
}
// 接下来我们可以获取到总分钟数
let totalMinutes = Math.floor(betweenDate / (60 * 1000))
/*然后我们需要减去休息时间 得到用户真正的总工作时长
由于用户可以选择多个休息区间 因此我们需要用到循环
*/
const restTotalMinutes = this.caclTotalRestTime()
//判断总休息时长是不是大于等于上班工作总时长 大于则 总工作时长为0小时0分钟(产品说的)
return restTotalMinutes >= totalMinutes?"0小时0分钟":`${Math.floor((totalMinutes-
restTotalMinutes) / 60)}小时${((totalMinutes-restTotalMinutes) % 60)}秒`
}
return "0小时0分钟"
},
caclTotalRestTime(){
const efficientRestTime = this.restTime.filter(i => i.startTime && i.endTime && i.startTime
!= '00:00' && i.endTime != '00:00')
let restTotalMinutes = 0;
if (efficientRestTime.length > 0) {
efficientRestTime.map(i => {
let _beginDate = this.moment(i.startTime, 'HH:mm')
let _endDate = this.moment(i.endTime, 'HH:mm')
let betweenDates = 0;
//这里我们同样需要判断休息结束时间是不是小于休息开始时间
if (_endDate < _beginDate) {
betweenDates = Number((24 * 3600 * 1000) - _beginDate
) + Number(_endDate)
} else {
betweenDates = _endDate - _beginDate
}
restTotalMinutes += Math.floor(betweenDates / (60 * 1000))
})
}
return restTotalMinutes
}
综上所示的方法即可算出实际工作的总时长了。当然这个需求不涉及到跨日的,还是比较简单的~~~ 但是挺有意思的 特此分享出来。 如果大家在工作中遇到类似需求,也可以以此作为借鉴。。。
最后
文章若有不足之处,还请大家批评指出。
感谢您观看此篇文章 希望能给个👍评论收藏三连!你的点赞就是我写作的动力。