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

news2024/9/28 6:30:18

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

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

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

页面布局

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

 <!-- 请假开始时间表单项 -->
<el-form-item
  prop="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-item
  label="请假结束时间"
  style="height: 55px"
  prop="end_time"
  label-width="120px"
  :required="true"
>
  <el-col :span="11">
    <el-date-picker
      type="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.coloradmin.cn/o/1473265.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mistral发布语言大模型Mistral Large;法国新星Mistral挑战 OpenAI 霸主地位

&#x1f989; AI新闻 &#x1f680; Mistral发布语言大模型Mistral Large 摘要&#xff1a;Mistral Large 是 Mistral AI 公司最新发布的旗舰语言模型&#xff0c;具备顶尖水平的推理能力。它主要被设计用于处理复杂的多语言推理任务&#xff0c;比如文本理解、转换和代码生…

“智能语音指令解析“ 基于NLP与语音识别的工单关键信息提取

“智能语音指令解析“ 基于NLP与语音识别的工单关键信息提取 1. 背景介绍1.1 场景痛点1.2 方案选型 2. 准备开发环境3. PaddleSpeech 语音识别快速使用4. PaddleNLP 信息抽取快速使用5. 语音工单信息抽取核心功能实现6. 语音工单信息抽取网页应用6.1 网页前端6.2 网页后端6.3 a…

3. Java中的锁

文章目录 乐观锁与悲观锁乐观锁(无锁编程,版本号机制)悲观锁两种锁的伪代码比较 通过 8 种锁运行案例,了解锁锁相关的 8 种案例演示场景一场景二场景三场景四场景五场景六场景七场景八 synchronized 有三种应用方式8 种锁的案例实际体现在 3 个地方 从字节码角度分析 synchroni…

ARM 版银河麒麟桌面系统下 Qt 开发环境搭建指南

目录 前言安装Linux ARM 版 QtCreator配置 Qt Creator配置构建套件 第一个麒麟 Qt 应用程序小结 前言 在上一篇文章信创ARM架构QT应用开发环境搭建中建议大家使用 Ubuntu X86 系统作为信创 ARM 架构 QT 应用的开发环境&#xff0c;里面使用了交叉编译的方式。这对于自己的 Qt …

AI与大数据:智慧城市安全的护航者与变革引擎

一、引言 在数字化浪潮的席卷下&#xff0c;智慧城市正成为现代城市发展的新方向。作为城市的神经系统&#xff0c;AI与大数据的融合与应用为城市的安全与应急响应带来了革命性的变革。它们如同城市的“智慧之眼”和“聪明之脑”&#xff0c;不仅为城市管理者提供了强大的决策…

【算法与数据结构】684、685、LeetCode冗余连接I II

文章目录 一、684、冗余连接 I二、685、冗余连接 II三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、684、冗余连接 I 思路分析&#xff1a;题目给出一个无向有环图&#xff0c;要求去掉一个边以后构成一个树&#xf…

PyQt6的开发流程(密码生成小程序为例)

PyQt6的开发流程&#xff08;密码生成小程序为例&#xff09; 文章目录 PyQt6的开发流程&#xff08;密码生成小程序为例&#xff09;一、流程介绍与概览1. 界面与逻辑分离的开发流程2. PyQt6的开发流程 二、打开 designer.exe 创建文件三、用QT设计师绘制界面保存成ui1. QT常用…

急中生智:献血200cc没事,为啥出血200cc就可能噶?

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 场地支持 / 声湃轩北京录音间 外伤出血更常见&#xff0c;但同样可能危及生命。 众所周知&#xff0c;出血是一种常见的外伤和急症&…

家装服务管理:Java技术的创新应用

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

ONLYOFFICE 桌面编辑器 v8.0 更新内容详细攻略

文章目录 引言PDF 表单RTL 支持电子表格中的新增功能Moodle 集成用密码保护 PDF 文件从“开始”菜单快速创建文档本地界面主题下载安装桌面编辑工具总结 引言 官网链接&#xff1a; ONLYOFFICE 官方网址 ONLYOFFICE 桌面编辑器是一款免费的文档处理软件&#xff0c;适用于 Li…

APP被针对攻击了,要怎么解决

随着APP行业的兴起&#xff0c;游戏公司异军突起&#xff0c;不管是在控证还是攻击方面都是属于最复杂的一个场面&#xff0c;游戏APP逐渐成为DDOS流量攻击的“重灾区”。没有提前做好了解就盲目进军游戏APP行业&#xff0c;一旦被攻击就会让公司束手无策。那么&#xff0c;刚上…

基于springboot实现的海鲜销售系统

一、系统架构 前端&#xff1a;html | bootstrap | vue | js | css 后端&#xff1a;springboot | springdata-jpa 环境&#xff1a;jdk1.8 | mysql | maven | redis 二、代码及数据库 三、功能介绍 01. web端-注册 02. web端-登录 03. web端-首页 04. web端-…

k8s节点负载使用情况分析命令kubectl describe node [node-name]

1.到任意安装了kubectl节点命令的节点上执行kubectl describe node [node-name] 上面的Requests最小分配 Limits最大分配是所有pod之和&#xff0c;最小分配之和不能超过服务器实际参数&#xff0c;否则新的pod会因为资源不够起不来&#xff0c;最大分配是预设之和&#xff0…

移动端学习:如何把exe转换成apk

exe转换成apk是怎么实现的呢?-电脑端-一门科技将exe文件转换成apk文件是一个比较常见的需求,尤其是对于一些开发者和用户来说。但是,这个过程并不是简单的复制和粘贴。在本文中,我们将介绍exe转换成apk的原理和详细介绍。首先,我们需要了解什么https://www.yimenapp.net/k…

数据安全-动态加密(不同敏感字段使用不同的加密算法-MySQL、Oracle版本)

动态数据加密 动态加密&#xff08;也称实时加密&#xff0c;透明加密等&#xff0c;其英文名为encrypt on-the-fly&#xff09;&#xff0c;是指数据在使用过程中自动对数据进行加密或解密操作&#xff0c;无需用户的干预&#xff0c;合法用户在使用加密的文件前&#xff0c;…

服务器权限:Error: EACCES: permission denied, open‘/Cardiac/uniquC.csv

背景&#xff1a; 我想在服务器上传一个文件uniquC.csv&#xff0c;但是服务器说我没有权限 解决方案&#xff1a; 1. 查看目前是否存在对文件夹的权限 ls -ld /Cardiac/ # your fold path 此时&#xff0c;我发现 这也意味着root也没有赋予写的权限。 2. 拿到root权限 …

Python爬虫-模拟Github登录并获取个人信息

爬虫系列&#xff1a;http://t.csdnimg.cn/WfCSx 前言 很多情况下&#xff0c;页面的某些信息需要登录才可以查看。对于爬虫来说&#xff0c;需要爬取的信息如果需要登录才可以看到的话&#xff0c;那么我们就需要做一些模拟登录的事情。 在前面我们了解了会话和 Cookies 的…

人脸2D和3D道具SDK解决方案提供商

人脸识别和增强现实技术成为了许多企业和开发者关注的焦点&#xff0c;为了满足市场对高质量、易于集成的人脸识别SDK的需求&#xff0c;美摄科技推出了一系列领先的人脸2D/3D道具SDK解决方案。 一、产品特点 高精度识别&#xff1a;美摄科技的人脸识别技术采用深度学习算法&…

【博士每天一篇文献-综述】A Modified Echo State Network Model Using Non-Random Topology

阅读时间&#xff1a;2023-11-23 1 介绍 年份&#xff1a;2023 作者&#xff1a; Arroyo, Diana Carolina Roca&#xff0c;数学与计算机科学研究所&#xff08;ICMC&#xff09;圣保罗大学 (USP) 期刊&#xff1a; 博士论文 引用量&#xff1a;0 这篇论文是一篇博士论文&am…

PostgreSQL 与MySQL 对比使用

一、前言 博主的系统既有 用到MySQL 也有用到PostgreSQL &#xff0c;之所以用到这两种数据库&#xff0c;主要是现在都是国产替代&#xff0c;虽然说这两款数据库也不是国产的&#xff0c;但是相对开源&#xff0c;oracle是不让用了。所以现在使用比较多的就是这两个关系型数据…