当前位置: 首页 > news >正文

Vue前端对请假模块——请假开始时间和请假结束时间的校验处理

开发背景:Vue+element组件开发

业务需求:用户提交请假申请单,请假申请的业务逻辑处理

实现:用户选择开始时间需要大于本地时间,不得大于请假结束时间,请假时长根据每日工作时间实现累加计算

页面布局

在前端页面选择的是el-date-picker组件

 <!-- 请假开始时间表单项 -->
<el-form-itemprop="start_time" <!-- 绑定表单验证规则的属性名 -->label="请假开始时间" <!-- 表单项标签文本 -->style="height: 55px" <!-- 设置表单项高度 -->label-width="120px" <!-- 设置标签宽度 -->:required="true" <!-- 标记为必填项 -->
><el-col :span="11"> <!-- 使用 Element UI 的 Col 布局,设置列宽 --><el-date-picker <!-- 日期时间选择器组件 -->type="datetime" <!-- 设置类型为日期和时间选择 -->placeholder="选择日期" <!-- 提示信息 -->v-model="form.start_time" <!-- 绑定到表单对象的 start_time 属性 -->style="width: 100%" <!-- 设置组件宽度为100% -->value-format="yyyy-MM-dd HH:mm:ss" <!-- 设置选中值的时间格式 -->:picker-options="pickerOptionsStart" <!-- 传入开始时间的选择器选项 -->@change="calculateLeaveHours" <!-- 当选择日期发生改变时触发的方法 -->></el-date-picker></el-col>
</el-form-item><!-- 请假结束时间表单项 -->
<el-form-itemlabel="请假结束时间"style="height: 55px"prop="end_time"label-width="120px":required="true"
><el-col :span="11"><el-date-pickertype="datetime"placeholder="选择日期"v-model="form.end_time" <!-- 绑定到表单对象的 end_time 属性 -->style="width: 100%"value-format="yyyy-MM-dd HH:mm:ss":picker-options="pickerOptionsEnd" <!-- 传入结束时间的选择器选项 -->@change="calculateLeaveHours" <!-- 同样在结束时间改变时触发计算方法 -->></el-date-picker></el-col>
</el-form-item><!-- 请假时长(小时)展示表单项 -->
<el-form-item label="请假时长(小时)" prop="hours" label-width="120px"><el-input <!-- 输入框组件 -->v-model="form.hours" <!-- 绑定到表单对象的 hours 属性 -->disabled <!-- 设置输入框为禁用状态,仅用于显示计算出的请假时长 -->></el-input>
</el-form-item>

用户选择开始时间的范围校验

 :picker-options="pickerOptionsStart"@change="calculateLeaveHours"

通过picker-options  vue动态绑定属性设定了选择器的自定义配置,例如开始时间需大于本地时间且需要小于结束时间

开始时间选择代码如下:

// pickerOptionsStart 定义开始时间选择器的自定义选项
pickerOptionsStart: {// disabledDate 是一个函数,用于决定日期选择器中哪些日期应被禁用(即不可选)disabledDate: (time) => {// 获取表单中结束时间的值let endDateVal = this.form.end_time;// 创建一个新的 Date 对象表示当前本地时间,并将其时间部分设置为0,确保包含今天整天的时间范围let now = new Date();now.setHours(0, 0, 0, 0);// 如果结束时间未设置,则只允许用户选择从当前时间(包含今天)到未来的所有时间if (!endDateVal) {return time.getTime() < now.getTime(); }// 同时满足以下条件时,该日期将被禁用:// 1. 开始时间需大于等于当前本地时间// 2. 开始时间需小于结束时间return (// 时间戳比较:如果开始时间早于当前时间 或者 开始时间晚于已设置的结束时间,则禁用该日期time.getTime() < now.getTime() ||time.getTime() > new Date(endDateVal).getTime());},
},

获取结束时间的值,如果有则从本地时间到结束时间,如果没有就从本地时间到未来的时间,创建Date对象来获取当前本地的时间,至于为什么需要包含今天整体的时间是因为如果只判断开始时间大于本地时间的话,在时间选择器里今天的日期也是被禁止掉了的,这对于用户的体验是不好的,同理,结束时间与开始时间类似,但是这个方法的缺陷便是用户可以在下午选择今天早上的时间,这对于业务是不满足的,后面会有解决方案

结束时间范围选择

如果用户先选择结束时间时,如:2-29,开始时间就只能从26-29进行选择

代码如下:

// pickerOptionsEnd 定义结束时间选择器的自定义选项pickerOptionsEnd: {// disabledDate 是一个函数,用于决定日期选择器中哪些日期应被禁用(即不可选)disabledDate: (time) => {// 获取表单中开始时间的值let beginDateVal = this.form.start_time;// 创建一个新的 Date 对象表示当前本地时间const currentDate = new Date();// 确保结束时间大于开始时间(如果开始时间已设置)if (beginDateVal) {return time.getTime() <= new Date(beginDateVal).getTime();}// 同时允许用户选择今天的日期作为结束时间,因此仅当结束时间早于当前时间才禁用return time.getTime() < currentDate.setHours(0, 0, 0, 0);},},

对于开始时间的校验以及计算请假时长

为了解决用户在当天可以选择任意的时间段以及计算请假时长,在开始时间和结束时间发生变化时便执行方法

methods: {//计算请假时长calculateLeaveHours() {}}

当用户选择的开始时间小于本地时间的5分钟之前时(因为涉及到秒数,选择的开始时间会一直小于本地时间,为用户操作保留缓冲区间),提示用户并重置开始时间为本地时间,当结束时间小于本地时间时,则重置结束时间为选择的开始时间后一个小时

 const startTime = new Date(this.form.start_time);const endTime = new Date(this.form.end_time);let now = new Date();const fiveMinutesAgo = new Date();fiveMinutesAgo.setMinutes(now.getMinutes() - 5);fiveMinutesAgo.setSeconds(0);fiveMinutesAgo.setMilliseconds(0);if (startTime < fiveMinutesAgo) {this.$message({message: "开始时间需在当前时间附近,已为您选择当前时间!",type: "warning",});this.form.start_time = new Date();}if (endTime < startTime) {this.$message({message:"结束时间小于开始时间,已为您选择结束时间为开始时间后一个小时!",type: "warning",});this.form.end_time = new Date(startTime.getTime() + 60 * 60 * 1000);}

请假时长的计算

// 初始化请假时长let leaveHours = 0;// 计算每天的工作时间let currentDate = new Date(startTime);while (currentDate < endTime) {const currentHour = currentDate.getHours(); // 获取当前小时数const currentMinute = currentDate.getMinutes(); // 获取当前分钟数// 判断当前时间是否在工作时间段内,若在则加入工作时间if (// 上午工作时间段:8:30 - 11:20(((currentHour === 8 && currentMinute >= 30) || currentHour > 8) &&((currentHour === 11 && currentMinute < 20) || currentHour < 11)) ||// 下午工作时间段:14:00 - 18:00((currentHour === 14 || currentHour === 18) && currentMinute >= 0) ||(currentHour > 14 && currentHour < 18) ||// 晚上工作时间段:19:00 - 20:30(((currentHour === 19 && currentMinute >= 0) || currentHour > 19) &&((currentHour === 20 && currentMinute <= 30) || currentHour < 20))) {// 在工作时间段内,加入工作时间leaveHours += 0.1;}// 将日期增加一小时currentDate.setMinutes(currentMinute + 6); // 以6分钟为间隔加入工作时间}// 更新请假时长this.form.hours = leaveHours.toFixed(1);

这样的基本模块便完善得七七八八了,但在其中依然还是有些小问题,例如如果用户先选择时间结束后,再重置便会导致请假时长会一直计算的问题

最初想的解决方案是如果开始时间为空的话,就重置时间跳出方法,

// 首先检查开始时间和结束时间是否为空,如果任一为空则跳出此方法if (!this.form.start_time || !this.form.end_time) {return this.form.hours=0;}

但是如果用户选择的开始时间小于本地时间的话就不能再进行判断了,所以进行了优化

if (this.form.hours !=0 &&(!this.form.start_time || !this.form.end_time)) {return this.form.hours=0;}

在周末的情况下我们也不应该把周末的时间计算到工作日中,代码优化如下:

const weekends = [0, 6];  
if (weekends.includes(currentDay)) {currentDate.setDate(currentDate.getDate() + 1); // 跳到下一天currentDate.setHours(8); // 设置小时为早上8点currentDate.setMinutes(0); // 设置分钟为0分continue; // 跳过后面的代码,继续下一轮循环}

设置了一个数组只要是周末周六就直接跳到下一天

这样便都解决了

http://www.lryc.cn/news/307110.html

相关文章:

  • 搭建freqtrade量化交易机器人
  • php伪协议 [SWPUCTF 2022 新生赛]ez_ez_php(revenge)
  • 1.1_1 计算机网络的概念、功能、组成和分类
  • pytorch中的各种计算
  • 大数据技术之 Kafka
  • 【GB28181】wvp-GB28181-pro部署安装教程(Ubuntu平台)
  • CentOS删除除了最近5个JAR程序外的所有指定Java程序
  • 面试redis篇-13Redis为什么那么快
  • python Matplotlib Tkinter--pack 框架案例
  • 连接未来:嵌入式系统在物联网时代的应用
  • 自动驾驶中的障碍物时间对齐法
  • 介绍 PIL+IPython.display+mtcnn for 音视频读取、标注
  • C语言中strstr函数的使用!
  • Vue项目中,src目录下的vue.app文件介绍
  • 【Android】坐标系
  • OSCP靶场--Slort
  • 大数据职业技术培训包含哪些
  • 【Java程序设计】【C00313】基于Springboot的物业管理系统(有论文)
  • TensorFlow训练大模型做AI绘图,需要多少的GPU算力支撑
  • docker创建mongodb数据库容器
  • Python并发编程:多线程-线程理论
  • 自定义Chrome的浏览器开发者工具DevTools界面的字体和样式
  • 人事|人事管理系统|基于Springboot的人事管理系统设计与实现(源码+数据库+文档)
  • React18源码: Fiber树中的优先级与帧栈模型
  • Hive 最全面试题及答案(基础篇)
  • 【力扣】整数反转,判断是否溢出的数学解法
  • Jmeter之内置函数__property和__P的区别
  • GPT润色指令
  • Ubuntu中matplotlib显示中文的方法
  • String类-equals和==的区别-遍历-SubString()-StringBuilder-StringJoiner-打乱字符串