人脸考勤签到升级篇

news2024/11/19 15:28:07

目录

编写签到成功页面(移动端)

实现考勤成功页面(持久层)

实现考勤成功页面(业务层)

实现考勤成功页面(Web层)

一、查询用户的入职日期

二、实现查询考勤结果的Web方法

实现考勤成功页面(移动端)

一、为超级管理员设置入职日期

二、修改系统时间

设计用户页面(移动端)

实现用户页面数据加载

一、编写后端项目代码

设计我的考勤页面(移动端)

实现我的考勤页面(Web层 & 业务层)

一、编写业务层代码

二、编写Web层代码

实现我的考勤页面(移动端)


编写签到成功页面(移动端)

        ……

实现考勤成功页面(持久层)

LEFT JOIN:前表可以在后表中无数据。

CASE WHEN … THEN … END as xx:替换查询出的数字为汉字。

CAST(date AS CHAR) AS date:转成字符串要用CHAR。

因为下面代码,所以要转为字符串类型,方便比较日期。

String date=one.toString("yyyy-MM-dd");

for (HashMap<String,String> map:checkinList){
        if(map.containsValue(date)){
                status=map.get("status");
                flag=true;
                break;
        }
}


编写 TbCheckinDao.xml 中的SQL语句,查询员工当天签到情况、员工请考勤日期总数 

  <select id="searchTodayCheckin" parameterType="int" resultType="HashMap">
    SELECT
      u.name,
      u.photo,
      d.dept_name AS deptName,
      ck.address,
      CASE
        WHEN ck.status=1 THEN '正常'
        WHEN ck.status=2 THEN '迟到'
        END as status,
      CASE
        WHEN ck.risk=1 THEN '低风险'
        WHEN ck.risk=2 THEN '中风险'
        WHEN ck.risk=3 THEN '高风险'
        END as risk,
      DATE_FORMAT(ck.create_time,"%H:%i") AS checkinTime,
      ck.date
    FROM tb_user u
           LEFT JOIN tb_dept d ON u.dept_id=d.id
           LEFT JOIN tb_checkin ck ON u.id=ck.user_id AND ck.date=CURRENT_DATE
    WHERE u.id=#{userId} AND u.status=1
  </select>
  <select id="searchCheckinDays" parameterType="int" resultType="long">
    SELECT COUNT(*) AS count
    FROM tb_checkin
    WHERE user_id=#{userId}
  </select>
  <select id="searchWeekCheckin" parameterType="HashMap" resultType="HashMap">
    SELECT
      CAST(date AS CHAR) AS date,
	  IF(status=1,"正常","迟到") AS status
    FROM tb_checkin
    WHERE user_id=#{userId}
      AND date BETWEEN #{startDate} AND #{endDate}
  </select>

编写 TbCheckinDao.java 接口中的抽象方法。 

@Mapper
public interface TbCheckinDao {
    ……
    public HashMap searchTodayCheckin(int userId);
    public long searchCheckinDays(int userId);
    public ArrayList<HashMap> searchWeekCheckin(HashMap param);
}

编写 TbHolidaysDao.xml 文件,添加查询语句。

  <select id="searchHolidaysInRange" parameterType="HashMap" resultType="String">
    SELECT date
    FROM tb_holidays
    WHERE date BETWEEN #{startDate} AND #{endDate}
  </select>

编写 TbHolidaysDao.java 接口,定义抽象方法。 

@Mapper
public interface TbHolidaysDao {
    ……
    public ArrayList<String> searchHolidaysInRange(HashMap param);
}

编写 TbWorkdayDao.xml 文件,添加查询语句。 

  <select id="searchWorkdayInRange" parameterType="HashMap" resultType="String">
    SELECT date
    FROM tb_workday
    WHERE date BETWEEN #{startDate} AND #{endDate}
  </select>

编写 TbWorkdayDao.java 接口,定义抽象方法。

@Mapper
public interface TbWorkdayDao {
    ……
    public ArrayList<String> searchWorkdayInRange(HashMap param);
}

实现考勤成功页面(业务层)

        上一小节,我们在Dao中声明了三个抽象的方法,于是现在我们要在业务层定义三个方法,分别对应Dao的三个抽象方法。 

编写 CheckinService.java 接口,声明三个抽象方法。 

public interface CheckinService {
    ……
    public HashMap searchTodayCheckin(int userId);
    public long searchCheckinDays(int userId);
    public ArrayList<HashMap> searchWeekCheckin(HashMap param);
}

在 CheckinServiceImpl.java 类中,实现三个抽象方法。

@Service
@Scope("prototype")
@Slf4j
public class CheckinServiceImpl implements CheckinService {
    ……
    @Override
    public HashMap searchTodayCheckin(int userId) {
        HashMap map=checkinDao.searchTodayCheckin(userId);
        return map;
    }

    @Override
    public long searchCheckinDays(int userId) {
        long days=checkinDao.searchCheckinDays(userId);
        return days;
    }

    @Override
    public ArrayList<HashMap> searchWeekCheckin(HashMap param) {
        ArrayList<HashMap> checkinList=checkinDao.searchWeekCheckin(param);
        ArrayList holidaysList=holidaysDao.searchHolidaysInRange(param);
        ArrayList workdayList=workdayDao.searchWorkdayInRange(param);
        DateTime startDate=DateUtil.parseDate(param.get("startDate").toString());
        DateTime endDate=DateUtil.parseDate(param.get("endDate").toString());
        DateRange range=DateUtil.range(startDate,endDate,DateField.DAY_OF_MONTH);
        ArrayList<HashMap> list=new ArrayList<>();
        range.forEach(one->{
            String date=one.toString("yyyy-MM-dd");
            String type="工作日";
            if(one.isWeekend()){
                type="节假日";
            }
            if(holidaysList!=null&&holidaysList.contains(date)){
                type="节假日";
            }
            else if(workdayList!=null&&workdayList.contains(date)){
                type="工作日";
            }
            String status="";
            if(type.equals("工作日")&&DateUtil.compare(one,DateUtil.date())<=0){
                status="缺勤";
                boolean flag=false;
                for (HashMap<String,String> map:checkinList){
                    if(map.containsValue(date)){
                        status=map.get("status");
                        flag=true;
                        break;
                    }
                }
                DateTime endTime=DateUtil.parse(DateUtil.today()+" "+constants.attendanceEndTime);
                String today=DateUtil.today();
                if(date.equals(today)&&DateUtil.date().isBefore(endTime)&&flag==false){
                    status="";
                }
            }
            HashMap map=new HashMap();
            map.put("date",date);
            map.put("status",status);
            map.put("type",type);
            map.put("day",one.dayOfWeekEnum().toChinese("周"));
            list.add(map);
        });
        return list;
    }
}

实现考勤成功页面(Web层)

一、查询用户的入职日期

        因为在Emos系统中,当天没有考勤的员工就算做缺勤。有一种特殊请款我们必须引起注意,假设A员工周三入职的,从周三开始执行人脸考勤。那么在考勤成功页面,我们看到周一和周二的考勤结果都是缺勤,这个是不对的。所以我们要先查询出来员工的入职日期,查询本周考勤的时候,应该从员工入职日期开始算起。 

编写 TbUserDao.xml 文件,查询员工的入职日期。 

<select id="searchUserHiredate" parameterType="int" resultType="String">
    SELECT hiredate FROM tb_user WHERE id=#{userId} AND status = 1
</select>

// MyBatis会把日期格式转为字符串格式。

编写 TbUserDao.java 接口,定义抽象方法。 

public interface TbUserDao { 
    ……
    public String searchUserHiredate(int userId);
} 

在 UserService.java 接口中,声明抽象方法。 

public interface UserService { 
    ……
    public String searchUserHiredate(int userId);
} 

在 UserServiceImpl.java 中,实现抽象方法。 

public class UserServiceImpl implements UserService { 
    ……
    @Override
    public String searchUserHiredate(int userId) { 
        String hiredate = userDao.searchUserHiredate(userId);
        return hiredate; 
    } 
}

二、实现查询考勤结果的Web方法

编写 CheckinController.java 中的Web方法,查询用户签到的结果。

@RequestMapping("/checkin")
@RestController
@Api("签到模块Web接口")
@Slf4j
public class CheckinController {
    ……

    @Autowired
    private UserService userService;

    @Autowired
    private SystemConstants constants;

    @GetMapping("/searchTodayCheckin")
    @ApiOperation("查询用户当日签到数据")
    public R searchTodayCheckin(@RequestHeader("token") String token){
        int userId=jwtUtil.getUserId(token);
        HashMap map=checkinService.searchTodayCheckin(userId);
        map.put("attendanceTime",constants.attendanceTime);
        map.put("closingTime",constants.closingTime);
        long days=checkinService.searchCheckinDays(userId);
        map.put("checkinDays",days);

        DateTime hiredate=DateUtil.parse(userService.searchUserHiredate(userId));
        DateTime startDate=DateUtil.beginOfWeek(DateUtil.date());
        if(startDate.isBefore(hiredate)){
            startDate=hiredate;
        }
        DateTime endDate=DateUtil.endOfWeek(DateUtil.date());
        HashMap param=new HashMap();
        param.put("startDate",startDate.toString());
        param.put("endDate",endDate.toString());
        param.put("userId",userId);
        ArrayList<HashMap> list=checkinService.searchWeekCheckin(param);
        map.put("weekCheckin",list);
        return R.ok().put("result",map);
    }
}

实现考勤成功页面(移动端)

一、为超级管理员设置入职日期

        因为在查询考勤结果的时候用到了员工入职日期,管理者创建员工记录的时候,要手动设置员工的入职日期,但是注册超级管理员的时候并没有填写入职日期,现在我们还没有做到员工管理页面,所以暂时手工在数据表里面设置超级管理员的入职日期。

二、修改系统时间

        因为Emos系统的签到时间是从08:30到09:30,为了实验签到功能,所以我们要修改系统时间在签到时间段之内。另外,如果你是周六、周日调试项目,需要在 tb_workday 表中加入当天日期,这样原本的周末就变成了工作日,可以考勤了。

设计用户页面(移动端)

        ……

实现用户页面数据加载

一、编写后端项目代码

在 TbUserDao.xml 中定义查询用户概要信息的SQL语句。 

<select id="searchUserSummary" parameterType="int" resultType="HashMap">
    SELECT u.name, u.photo, d.dept_name AS deptName
    FROM tb_user u LEFT JOIN tb_dept d ON u.dept_id=d.id
    WHERE u.id=#{userId} AND u.status=1
</select>

在 TbUserDao.java 接口中,定义抽象方法。 

@Mapper
public interface TbUserDao {
    ……
    public HashMap searchUserSummary(int userId);
}

在 UserService.java 接口中,定义抽象方法。 

public interface UserService { 
    ……
    public HashMap searchUserSummary(int userId);
} 

在 UserServiceImpl.java 中,定义实现方法。 

public class UserServiceImpl implements UserService { 
    ……

    @Override
    public HashMap searchUserSummary(int userId) { 
        HashMap map = userDao.searchUserSummary(userId);
        return map; 
    } 
} 

在 UserController.java 中,定义Web方法。

@RestController
@RequestMapping("/user")
@Api("用户模块Web接口")
public class UserController {
    ……
    @GetMapping("/searchUserSummary")
    @ApiOperation("查询用户摘要信息")
    public R searchUserSummary(@RequestHeader("token") String token){
        int userId=jwtUtil.getUserId(token);
        HashMap map=userService.searchUserSummary(userId);
        return R.ok().put("result",map);
    }
}

设计我的考勤页面(移动端)

        ……

实现我的考勤页面(Web层 & 业务层)

        查询月考勤持久层代码 和 查询周考勤持久层代码相通。

一、编写业务层代码

在 CheckinService.java 接口中添加查询月考勤的抽象方法。 

public interface CheckinService { 
    ……
    public ArrayList<HashMap> searchMonthCheckin(HashMap param);
} 

在 CheckinServiceImpl.java 类中添加实现方法。 

public class CheckinServiceImpl implements CheckinService { 

    ……

    @Override
    public ArrayList<HashMap> searchMonthCheckin(HashMap param) { 
        return this.searchWeekCheckin(param);
    } 
}

二、编写Web层代码

创建 SearchMonthCheckinForm.java 类,接受提交数据。 

@Data
@ApiModel
public class SearchMonthCheckinForm {
    @NotNull
    @Range(min=2000,max = 3000)
    private Integer year;

    @NotNull
    @Range(min=1,max = 12)
    private Integer month;
}

在 CheckinController.java 中,定义Web

@RequestMapping("/checkin")
@RestController
@Api("签到模块Web接口")
@Slf4j
public class CheckinController {
    ……

    @PostMapping("/searchMonthCheckin")
    @ApiOperation("查询用户某月签到数据")
    public R searchMonthCheckin(@Valid @RequestBody SearchMonthCheckinForm form,@RequestHeader("token") String token){
        int userId=jwtUtil.getUserId(token);
        DateTime hiredate=DateUtil.parse(userService.searchUserHiredate(userId));
        String month=form.getMonth()<10?"0"+form.getMonth():form.getMonth().toString();
        DateTime startDate=DateUtil.parse(form.getYear()+"-"+month+"-01");
        if(startDate.isBefore(DateUtil.beginOfMonth(hiredate))){
            throw new EmosException("只能查询考勤之后日期的数据");
        }
        if(startDate.isBefore(hiredate)){
            startDate=hiredate;
        }
        DateTime endDate=DateUtil.endOfMonth(startDate);
        HashMap param=new HashMap();
        param.put("userId",userId);
        param.put("startDate",startDate.toString());
        param.put("endDate",endDate.toString());
        ArrayList<HashMap> list=checkinService.searchMonthCheckin(param);
        int sum_1=0,sum_2=0,sum_3=0;
        for(HashMap<String,String> one:list){
            String type=one.get("type");
            String status=one.get("status");
            if("工作日".equals(type)){
                if("正常".equals(status)){
                    sum_1++;
                }
                else if("迟到".equals(status)){
                    sum_2++;
                }
                else if("缺勤".equals(status)){
                    sum_3++;
                }
            }
        }
        return R.ok().put("list",list).put("sum_1",sum_1).put("sum_2",sum_2).put("sum_3",sum_3);
    }
}

实现我的考勤页面(移动端)

        array.length = 0; 清空数组

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/699596.html

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

相关文章

8年资深测试总结,性能测试-性能内存详解,揭秘你的疑惑...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 缓存 从 free 命令…

python实现基于SVD矩阵分解的电影推荐系统设计

大家好&#xff0c;我是带我去滑雪&#xff01; SVD 是一种矩阵分解技术&#xff0c;通过将空间维数从 N 维降到 K 维&#xff08;其中K<N&#xff09;来减少数据集的特征数。在推荐系统中&#xff0c;SVD 被用作一种协同过滤技术。使用矩阵结构&#xff0c;其中行表示用户&…

CC2530 外部中断配置步骤

第一章 硬件原理图分析 第二章 配置按键中断步骤

Python:通过飞书API接口发送通知消息

通过飞书发送应用消息&#xff0c;及时收到线上异常消息 总的来说&#xff0c;飞书消息发送的前戏&#xff0c;要比企业微信和钉钉稍复杂 相关连接 官网 https://www.feishu.cn/管理后台 https://www.feishu.cn/admin开放平台 https://open.feishu.cn/ 参数准备 首先&…

JS中的函数与数组

文章目录 函数的定义与调用①、函数定义②、函数调用 函数的参数与返回值let与var关键字区别创建数组并使用数组遍历 函数的定义与调用 ①、函数定义 函数定义有三种方式&#xff1a; 第一种&#xff1a;function 函数名(){ 函数体 } 第二种&#xff1a;定义变量的语法&…

LITE TRANSFORMER WITH LONG-SHORT RANGE ATTENTION

1.摘要 在这篇论文中&#xff0c;我们提出了一种高效的移动NLP架构——Lite Transformer&#xff0c;以在边缘设备上部署移动NLP应用。Transformer已经成为自然语言处理&#xff08;例如机器翻译、问答系统&#xff09;中无处不在的技术&#xff0c;但要实现高性能需要大量计算…

Elasticsearch 初步使用

本文是 Elasticsearch官方博客文档 阅读笔记记录&#xff0c;详细内容请访问官方链接&#xff0c;本文只做重点记录 index索引 对于经常看 Elastic 英文官方文档的开发者来说&#xff0c;我们经常会看到 index 这个词。在英文中&#xff0c;它即可以做动词&#xff0c;表示建…

ASP.Net Core Web API快速搭建后台服务搭载SQLServer+FreeSQL(一)

目录 一.建立WebAPI所需要的环境 1. IDE编辑器&#xff1a;VisualStudio2019 2.数据库安装&#xff1a;SqlServer 3.下载SQL Server Management Studio (SSMS) 二.创建ASP.Net Core Web API工程 1.创建模板工程 2. 试运行案例接口 3.安装FreeSQL工具包 三.设计数据库 启…

《养生大世界》简介及投稿要求

《养生大世界》简介及投稿要求 《养生大世界》是由国家新闻总署备案&#xff0c;中国老年保健协会主管的国家级学术期刊&#xff0c;全国公开发行正规刊物。 《养生大世界》传播健康中国文化理念&#xff0c;推动健康养生科技创新发展&#xff0c;助力健康产业惠及人民。 主…

蓝桥杯单片机竞赛主观题总结(全)(2.5W字)

前言 对于蓝桥杯的单片机竞赛&#xff0c;主观题很重要&#xff0c;占了百分之70-80的大头&#xff0c;因此主观题做得怎么样决定了比赛是否能拿奖&#xff0c;而客观题的正确率很大程度上决定了你能否获得省一&#xff0c;从而进入决赛。因此我在这里分享一期关于主观题中各个…

95道MongoDB面试题

1、mongodb是什么&#xff1f; MongoDB 是由 C语言编写的&#xff0c;是一个基于分布式文件存储的开源数据库系统。 再高负载的情况下&#xff0c;添加更多的节点&#xff0c;可以保证服务器性能。 MongoDB 旨在给 WEB 应用提供可扩展的高性能数据存储解决方案。 MongoDB 将数…

前端技术栈 - ES6 - Promise -模块化编程

文章目录 &#x1f55b;ES6⚡let变量⚡const常量⚡数组解构⚡对象解构⚡模板字符串⚡对象声明简写⚡对象方法简写⚡对象运算符扩展⚡箭头函数&#x1f98a;传统函数>箭头函数&#x1f98a;箭头函数对象解构 ⚡作业布置 &#x1f550;Promise⚡需求分析⚡传统ajax回调嵌套⚡p…

GO、KEGG(批量分组)分析及可视化

这篇帖子其实是更新、补充、解决一下问题的。我们号写过很多GO、KEGG富集分析的可视化&#xff0c;数不胜数&#xff0c;可以在公众号检索“富集”了解更多。我们演示的时候都是直接提供了富集的结果文件&#xff0c;一般演示为了图方便&#xff0c;也是利用在线工具cytoscape做…

网络工程师的副业,能有多野?

大家好&#xff0c;我是许公子。 在网工这行做了这么久&#xff0c;经常会有同事或者朋友来问我&#xff0c;有没有什么搞副业的路子。 别说&#xff0c;选择还真挺多。 前两天的文章里&#xff0c;这位朋友就秀了一波&#xff0c;这工作速度、便捷程度、收款金额&#xff0c…

Java并发编程-线程基础

哈喽,大家好,这篇文章主要讲解Java并发编程,线程基础的知识点,讲解知识点的同时也会穿插面试题的讲解. 主要讲解以下内容 进程,线程基础常见的一些区别比较如何使用和查看线程理解线程如何运行以及线程上下文切换的知识线程方法线程状态 希望能给大家带来帮助.加油~~~ 目录 进…

自学黑客(网络安全),一般人我劝你还是算了吧(自学网络安全学习路线--第十九章 口令破解与防御技术下)【建议收藏】

文章目录 一、自学网络安全学习的误区和陷阱二、学习网络安全的一些前期准备三、自学网络安全学习路线一、口令攻击的综合应用1、Windows NT, 2000口令攻击2、Windows XP, 2003口令攻击3、Unix系统口令攻击4、远程口令攻击 二、口令攻击的防御1、口令攻击防御概述2、保持口令的…

RS485转Profinet通讯

RS485转Profinet通讯 概述系统组成流量积算仪网关 软件总结 概述 一个支持RS485的流量积算仪的数据要被Profinet的PLC读取。制作一个网关&#xff0c;实现RS485到Profinet的转换。 系统组成 流量积算仪 支持RS485通讯&#xff0c;通讯协议是modbus RTU。采用功能码3可以读取…

非GUI模式下如何传参

非GUI模式下如何传参 Jmeter 有两种模式&#xff0c;GUI模式和非GUI模式&#xff0c;通常使用GUI模式编辑脚本&#xff0c;使用非GUI模式运行压测&#xff0c;官网上有强调&#xff0c;尽量使用非GUI模式&#xff0c;因为GUI模式下&#xff0c;jmeter UI组件本身在压测过程中会…

论文浅尝 | SimKGC:基于预训练语言模型的简单对比知识图谱补全

笔记整理&#xff1a;李雅新&#xff0c;天津大学硕士&#xff0c;研究方向为知识图谱补全 链接&#xff1a;https://dl.acm.org/doi/10.1145/3539597.3570483 动机 知识图谱补全 (KGC) 旨在对已知事实进行推理并推断缺失的链接。基于文本的方法从自然语言描述中学习实体表示&a…

Spring Boot 中的 @EnableConfigurationProperties 注解

Spring Boot 中的 EnableConfigurationProperties 注解 在 Spring Boot 中&#xff0c;EnableConfigurationProperties 注解是一个非常有用的注解&#xff0c;它可以用于启用对特定配置类的支持。在本文中&#xff0c;我们将深入探讨 EnableConfigurationProperties 注解&…