【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码

1、前言介绍

在如今这个人才需求量大的时代,各方企业为了永葆企业的活力与生机,在不断开 拓进取的同时,又广泛纳用人才,为企业的长久发展奠定了基础。于是,各个企业与部 门机构,都不可避免地会接触到人力资源管理的问题。

Hrm 是一款人力资源管理系统,其主要功能模块有员工个人信息修改、请假、员工 的薪资管理、考勤管理、社保管理。其中考勤管理实现了员工考勤状态的修改与员工考 勤月报表的导出,以及通过员工考勤记录的导入来实现员工考勤状态的判断。社保管理, 主要实现了员工社保的计算以及明细的修改。薪资管理,实现了员工工资的调整,以及 员工月工资报表的导出。 本项目采用了前后端分离的技术,前端是基于 Vue+ElementUI+Axios 开发的,后端 则是基于 Spring Boot+MyBatis Plus+ Jwt+Mysql。本项目实现了权限菜单管理,通过员 工的权限动态渲染菜单,并动态生成路由。通过 Jwt token 来判断当前登录的员工以及 员工的登录状态。

2、主要技术

技术名 作用
SpringBoot 后端框架
Vue 前端框架
MySQL 数据库

3、系统设计

3.1、功能结构设计

本系统主要分四个模块,分别是系统管理和权限管理、薪资管理、考勤管理,系统 管理主要用于日常事务管理管理,权限管理,用于控制员工的访问权限,薪资管理主要 是对员工的五险一金以及社保数据的修改和添加,考勤管理主要是对员工的日常打卡进 行记录和统计。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第1张图片

3.2、前端设计

3.2.1、前端接口封装

本项目对 Axios 进行了全局的封装,对前端请求和后端响应进行了统一的拦截,并人力资源管理系统进行相应的处理。前端调用的 Api 都封装在 src/api 模块下,进行统一的管理。

3.2.2、组件封装

为了解决代码复用的问题,通过结合 Element UI。本项目对 form 表单和 table 数据 表进行了进一步的组件封装。

3.2.3、动态路由

本项目采用了基于后端权限菜单的来实现动态路由,为了保证菜单数据的全局共享, 菜单数据使用 vuex 来保存。当员工访路由时,通过全局路由守卫进行拦截,并向后端 请求该员工的菜单数据。

3.3、后端设计

3.3.1、全局异常处理

为 了 高 效 地 处 理 异 常 , 本 项 目 对 异 常 进 行 了 全 局 的 统 一 处 理 , 使 用

@ControllerAdvice 声明一个全局异常处理器,并通过继承 RuntimeException 实现一个异 常类,在需要异常处理的地方抛出自定义的异常。

3.3.2、数据传输对象

本项目中,后端响应给前端的数据都统一封装在 ResponseDTO 中,然后前端通过 解析得到 ResponseDTO 的 json 对象。通过定义全局的业务状态码枚举类。前端通过后 端响应数据的状态码来判断业务处理是否异常。

3.4、数据库设计

根据《阿里开发手册》,本项目的每张表都包含 id、create_time、update_time 三个 字段。项目统一采用逻辑删除,每张表都包括 is_deleted 字段。根据实际业务需求,项 目分为系统管理、权限管理、薪资管理、考勤管理四大模块。表前缀 sys_(系统管理)、

per_(权限管理)、att_(考勤管理)、sal_(工资管理)、soc_(五险一金)。

3.4.1、系统管理模块

系统管理模块主要涉及 3 张表,负责对员工、部门、以及被上传文件的数据信息进人力资源管理系统行保存。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第2张图片

3.4.2、权限管理模块

权限管理模块主要涉及 5 张表,主要对菜单数据、角色数据进行保存。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第3张图片

3.4.3、考勤管理模块

员工考勤模块主要涉及 9 张表,主要对员工的考勤数据,以及各部门的考勤规则、 加班、请假、工作时间等规则信息的保存。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第4张图片

3.4.4、薪资管理模块 

薪资管理模块主要涉及 7 张表,用于保存参保城市社保信息、员工每个的工资明细、 以及考勤扣款情况。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第5张图片

4、系统实现

4.1、登录

此模块完成了员工的登录功能,员工通过工号和密码进行登录。若员工状态异常则 无法登录。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第6张图片

登录接口:

@PostMapping("/login") public ResponseDTO login(@RequestBody Staff staff)

接口说明: 当员工填写好登录账号和密码之后,前端会提交登录表单。后端接收到数据之后, 会进行数据库查询,并将最终的查询结果以状态码的形式封装在 ResponseDTO 之中, 并返回到前端。

核心代码:

public ResponseDTO login(Staff staff) { 
    String password = MD5Util.MD55(staff.getPassword()); 
    StaffDeptVO staffDeptVO = this.staffMapper.findStaffInfo(staff.getCode(), password); 
    if (staffDeptVO != null) { // 验证用户状态
        if (staffDeptVO.getStatus() == 1) { 
            String token = JWTUtil.generateToken(staffDeptVO.getId(),password); 
            return Response.success(staffDeptVO, token); // 返回员工信息和 token 
        } 
        return Response.error(BusinessStatusEnum.STAFF_STATUS_ERROR); 
    } 
    return Response.error("用户名或密码错误!"); 
}

登录流程: 首先通过前端传递的账号和密码进行员工查询,之后对查询到的员工进行状态判断, 如果状态正常,则将用户的信息和生成的 token 返回给前端,前端将 token 保存在

localstorage 中。

4.2、个人信息编辑

此模块实现了员工个人信息的查看与修改,员工可以进行个人头像的修改。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第7张图片

编辑接口:

@PutMapping public ResponseDTO edit(@RequestBody Staff staff)

接口说明:

员工填写的信息会通过 el-form 组件的 data 属性,将数据绑定到一个 json 对象中, 并通过 put 提交,最后后端接收数据,并完成相应员工信息的更新。 核心代码:

public ResponseDTO edit(Staff staff) { 
    if (updateById(staff)) { 
        return Response.success(); 
    } 
    return Response.error(); 
}

流程: 员工填写的信息会通过 el-form 组件的 data 属性,将数据绑定到一个 json 对象中, 并通过 put 提交,最后后端接收数据,并完成相应员工信息的更新。

4.3、修改密码

此模块完成了的员工个人密码的修改,若员工修改的密码与上一次密码项目,则提 示修改失败。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第8张图片

密码检查接口:

@GetMapping("/check/{pwd}/{id}") public ResponseDTO checkPassword(@PathVariable String pwd,@PathVariable Integer id)

接口说明: 通过前端传递的密码和 id,来判断员工填写的密码是否正确。 密码修改接口:

@PutMapping("/pwd") public ResponseDTO updatePassword(@RequestBody Staff staff)

接口说明: 为了保证密码的安全性,使用 put 提交。

核心代码:

public ResponseDTO checkPassword(String pwd, Integer id) { 
    Staff staff = getById(id);
    if(staff != null) {
        if (StrUtil.isNotBlank(pwd)) {
            if (MD5Util.MD55(pwd).equals(staff.getPassword())) {
                return Response.success();
            }
            throw new ServiceException(500,"密码错误!");
        }
        throw new ServiceException(500,"密码不能为空!");
    }
    throw new ServiceException(500,"此员工不存在!");
}

public ResponseDTO updatePassword(Staff staff) {             
    staff.setPassword(MD5Util.MD55(staff.getPassword())); 
    if(updateById(staff)){ 
        return Response.success(); 
    } 
    return Response.error(); 
}

流程: 当员工打开修改密码的对话框,员工需要先正确填写原来的密码,然后填入将要修 改的密码。当你修改的密码与原来的密码相同时,将会提示不能使用原来的密码,并且 修改密码失败。密码修改成功之后,会自动退出登录,需要重新登录。

4.4、首页图表展示

首页主要展示了当前员工的一些基本信息,以及个人在当月的考勤情况。另外显示 了系统的一些基本数据。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第9张图片

图表数据接口:

@GetMapping("/staff") public ResponseDTO getStaffData()

接口说明: 根据员工表的 create_time 字段,获取最近一年内的新增员工数。 统计数据接口:

@GetMapping("/count") public ResponseDTO getCountData()

接口说明: 统计员工总数以及状态正常的员工的数目。

核心代码:

getRegisterData().
    then(response => {
        if (response.code = 200) { 
            const quarters = ['一季度', '二季度', '三季度', '四季度']         
            this.commonOption.xAxis.data = quarters this.commonOption.series.forEach(item => { item.data = response.data }) 
            const registerChart = echarts.init(this.$refs.register);         
            registerChart.setOption(this.commonOption); 
            const commonChart = echarts.init(this.$refs.common);                
            commonChart.setOption(this.commonOption); 
            this.pieOption.series.forEach(item => { item.data = quarters.map((q, i) => ({ name: q, value: response.data[i] })) }) 
            const pieChart = echarts.init(this.$refs.pie);         
            pieChart.setOption(this.pieOption); 
    } else { 
        this.$message.error("获取数据失败!") 
    } 
})

流程: 当前端获取后端提供的数据之后,对数据项进行配置,然后将初始化好的图表挂载 到 dom 元素节点上。

4.5、标签栏页面跳转

通过点击菜单标签,可以完成页面的跳转,以及标签的删除。

核心代码:

ADD_TAG(state, menu) { 
    if (menu.code !== 'home') { 
        const result = state.tagList.findIndex( item => item.code === menu.code ) 
        if (result === -1) { 
            state.tagList.push(menu) 
        } 
    } 
    localStorage.removeItem("tagList") 
    localStorage.setItem("tagList", JSON.stringify(state.tagList))
}, 


CLOSE_TAG(state, menu) { 
    state.tagList = state.tagList.filter(item => item.code !== menu.code)         
    localStorage.removeItem("tagList") 
    localStorage.setItem("tagList", JSON.stringify(state.tagList)) 
}

流程: 当每点击一次侧边栏的菜单项,就将菜单数据存储在 vuex 中。而且为了保证页面 刷新之后,标签栏不会消失,又将菜单数据保存在 localstorage 中。标签栏由 vuex 中存 储的菜单数据动态生成。

4.6、多条件分页查询

选择不同条件,进行多条件分页查询

分页接口:

@PostMapping("/page") public ResponseDTO list(@RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size, @RequestBody Staff staff)

接口说明:

current 代表第几页,size 每次页面所展示的数据的个数,staff 包含了多条件查询的 条件。

核心代码:

public ResponseDTO list(Integer current, Integer size, Staff staff) { 
    IPage pageConfig = new Page<>(current, size); 
    QueryWrapper wrapper = new QueryWrapper<>(); 
    if (staff.getName() != "" && staff.getName() != null) { 
        wrapper.like("name", staff.getName()); 
    } 
    if (staff.getBirthday() != null) { 
        wrapper.ge("birthday", staff.getBirthday()); 
    } 
    if (staff.getDeptId() != null) { 
        wrapper.eq("dept_id", staff.getDeptId()); 
    } 
    if (staff.getStatus() != null) { 
        wrapper.eq("status", staff.getStatus()); 
    } 
    IPage page = page(pageConfig, wrapper); 
    Map map = new HashMap(); 
    map.put("pages", page.getPages()); 
    map.put("total", page.getTotal()); 
    map.put("list", page.getRecords()); 
    return Response.success(map); 
}

流程: 后端根据前端提交的查询数据,然后使用 MyBatis Plus 提供的分页方法进行分页, 然后将满足条件的数据返回给前端。

4.7、角色分配

此模块主要实现了为员工分配角色,一个员工可以分配多个角色。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第10张图片

角色接口:

@GetMapping("/all") public ResponseDTO findAll()

接口说明: 获取所有角色。 员工角色接口:

@GetMapping("/role/{staffId}") public ResponseDTO getRole(@PathVariable Integer staffId)

接口说明: 获取目前员工已拥有的角色。 设置员工角色接口:

@PostMapping("/role/{staffId}") public ResponseDTO setRole(@PathVariable Integer staffId, @RequestBody List roleIds)

接口说明: 员工可以选择多个角色,根据员工的 id 和选择的角色 id,为员工设置角色。 核心代码:

public ResponseDTO setRole(Integer staffId, List roleIds) { 
    QueryWrapper wrapper = new QueryWrapper<>(); 
    wrapper.eq("staff_id",staffId); 
    List list = list(wrapper); 
    for (StaffRole staffRole : list) { 
        if (roleIds.contains(staffRole.getRoleId())){ 
            staffRole.setStatus(1); 
        }else{ 
            staffRole.setStatus(0); 
        } 
        updateById(staffRole); 
    } 
    for (Integer roleId : roleIds) { 
        StaffRole staffRole = new StaffRole(); 
        staffRole.setStaffId(staffId); 
        staffRole.setRoleId(roleId); 
        staffRole.setStatus(1); 
        QueryWrapper queryWrapper = new QueryWrapper<>(); 
        queryWrapper.eq("staff_id",staffId).eq("role_id",roleId);     
        if(!saveOrUpdate(staffRole,queryWrapper)){ 
            throw new ServiceException(500,"添加角色失败!"); 
        } 
    }
    return Response.success(); 
}

流程: 当员工点击分配菜单按钮时,前端会向后端请求所有的角色数据,紧接着再查询当 前员工所拥有的角色,并将对应的角色框勾选上。当员工选择好了角色并提交之后,后 端会先禁用不需要的角色,然后再添加或更新。

4.8、菜单分配

此模块实现了为角色分配菜单,一个角色可以选择多个菜单。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第11张图片

菜单接口:

@GetMapping("/all") public ResponseDTO findAll()

接口说明: 获取所有的菜单数据。 角色菜单接口:

@GetMapping("/menu/{roleId}") public ResponseDTO getMenu(@PathVariable Integer roleId)

接口说明:

获取角色的菜单数据。 设置角色菜单接口:

@PostMapping("/menu/{roleId}") public ResponseDTO setMenu(@PathVariable Integer roleId, @RequestBody List menuIds)

接口说明: 根据角色 id,和选择的菜单 id,为角色设置菜单。 核心代码:

public ResponseDTO setMenu(Integer roleId, List menuIds) { 
    QueryWrapper wrapper = new QueryWrapper<>(); 
    wrapper.eq("role_id", roleId); List list = list(wrapper); 
    for (RoleMenu roleMenu : list) { 
        if (menuIds.contains(roleMenu.getMenuId())) { 
            roleMenu.setStatus(1); 
        } else { 
            roleMenu.setStatus(0); 
        } 
        updateById(roleMenu); 
    } 
    for (Integer menuId : menuIds) { 
        RoleMenu roleMenu = new RoleMenu(); 
        roleMenu.setRoleId(roleId); 
        roleMenu.setMenuId(menuId); 
        roleMenu.setStatus(1); 
        QueryWrapper queryWrapper = new QueryWrapper(); 
        queryWrapper.eq("role_id", roleId).eq("menu_id", menuId); 
        if (!saveOrUpdate(roleMenu, queryWrapper)) { 
            throw new ServiceException(500, "角色添加菜单失败!"); 
        } 
    } 
    return Response.success(); 
}

流程: 当点击分配菜单按钮,前端会向后端请求所有的菜单数据,这里只返回了父级菜单, 因为子菜单都作为了父级菜单的 children 属性被携带。当菜单被渲染好之后,紧接着获 取当前角色的所有拥有的菜单,并将对应项勾选。提交之后,后端先将不需要的菜单禁 用,然后再重新更新或设置菜单。

4.9、员工请假

当员工填写请假的基本信息,点击确定,完成了请假申请的提交。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第12张图片

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第13张图片

请假接口:

@PostMapping public ResponseDTO add(@RequestBody StaffLeave staffLeave)

接口说明: 新增一个请假申请人

请假记录接口:

@GetMapping("/staff") public ResponseDTO findByStaffId(@RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size, Integer id)

接口说明: 获取员工的请假记录 请假内容更新接口:

@PutMapping public ResponseDTO edit(@RequestBody StaffLeave staffLeave)

接口说明: 如果请假申请审批通过,那么就将休假日的考勤状态设置为休假状态 核心代码:

public ResponseDTO edit(StaffLeave staffLeave) { 
    if (staffLeave.getStatus() == AuditStatusEnum.APPROVE) { 
        for (int i = 0; i < staffLeave.getDays(); i++) { 
            Date attendanceDate = DateUtil.offsetDay(staffLeave.getStartDate(), i).toSqlDate(); 
            if (!DateUtil.isWeekend(attendanceDate)) { 
                Attendance attendance = new Attendance().setAttendanceDate(attendanceDate).setStaffId(staffLeave.getStaffId()).setStatus (AttendanceStatusEnum.LEAVE); 
                QueryWrapper queryWrapper = new QueryWrapper<>();     
                queryWrapper.eq("staff_id", attendance.getStaffId()).eq("attendance_date", attendance.getAttendanceDate()); 
                if (!this.attendanceService.saveOrUpdate(attendance, queryWrapper)) { 
                    return Response.error(); 
                } 
            } 
        } 
    } 
    if (updateById(staffLeave)) { 
        return Response.success(); 
    } 
    return Response.error(); 
}

流程: 当员工提交一个请假申请之后,申请处于未审核状态,如果员工拥有未被审核的请 假申请时,该员工是不能再次发起请假申请,另外员工也可以将未被审核的申请进行撤 销。当申请被管理员审批通过了之后,系统就会自动地将员工休假期间的考勤状态设置 为休假。

4.10、考勤数据导入

通过导入考勤数据,完成员工考勤状态的记录。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第14张图片

数据导入接口:

@PostMapping("/import") public ResponseDTO imp(MultipartFile file)

接口说明: 此处只需要导入考勤数据表,系统读取数据,来对员工的考勤状态进行判断。 核心代码:

@Transactional(rollbackFor = Exception.class) 
public ResponseDTO imp(MultipartFile file) throws IOException { 
    InputStream inputStream = file.getInputStream();
    List list = HutoolExcelUtil.readExcel(inputStream, 1, Attendance.class); 
    for (Attendance attendance : list) { 
        // 判断是否是周末,如果是周末就不用记录考勤情况,如果不是周末就判断员 工是否请假
        if (attendance.getStaffId() == null || attendance.getAttendanceDate() == null || DateUtil.isWeekend(attendance.getAttendanceDate()) || isLeave(attendance)) { 
            continue; 
        } else { 
            WorkTime workTime = this.workTimeMapper.findDeptWorkTimeByStaffId(attendance.getStaffId()); 
            if (isAbsenteeism(attendance, workTime)) {     
                attendance.setStatus(AttendanceStatusEnum.ABSENTEEISM); 
            } else if (isLate(attendance, workTime)) { 
                attendance.setStatus(AttendanceStatusEnum.LATE); 
            } else if (isLeaveEarly(attendance, workTime)) { 
                attendance.setStatus(AttendanceStatusEnum.LEAVE_EARLY); 
            } else { 
                attendance.setStatus(AttendanceStatusEnum.NORMAL); 
            } 
            QueryWrapper queryWrapper = new QueryWrapper<>(); 
            queryWrapper.eq("staff_id", attendance.getStaffId()).eq("attendance_date", attendance.getAttendanceDate()); 
            if (!saveOrUpdate(attendance, queryWrapper)) { 
                throw new ServiceException(BusinessStatusEnum.DATA_IMPORT_ERROR); 
            } 
        } 
    } 
    return Response.success(); 
}

流程: 当系统将考勤数据读取了之后,会根据员工的 id 获取员工所在部门的上班考勤时间, 然后将员工的打卡时间与部门规定的上班时间进行比对,若员工的四个打卡时间缺少一 个就认定为旷工,如果员工既迟到又早退也视为旷工。判定出员工相应的考勤状态之后, 就将考勤状态更新到数据库。

4.11、考勤月报表导出

通过汇总当月员工的考勤状况得到当月的员工考勤报表。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第15张图片

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第16张图片

数据导出接口:

@GetMapping("/export/{month}") public ResponseDTO export(HttpServletResponse response, @PathVariable String month)

接口说明: 根据月份,导出相应月份的考勤数据。

核心代码:

public ResponseDTO export(HttpServletResponse response, String month) throws IOException { 
    List list = this.staffMapper.findAttendanceMonthVO(); 
    for (AttendanceMonthVO attendanceMonthVO : list) { 
        attendanceMonthVO.setLateTimes(this.attendanceMapper.countTimes(attendanceMonthVO. getStaffId(),AttendanceStatusEnum.LATE.getCode(), month));            
        attendanceMonthVO.setLeaveEarlyTimes(this.attendanceMapper.countTimes(attendanceMon thVO.getStaffId(),AttendanceStatusEnum.LEAVE_EARLY.getCode(), month));
        attendanceMonthVO.setAbsenteeismTimes(this.attendanceMapper.countTimes(attendanceMo nthVO.getStaffId(),AttendanceStatusEnum.ABSENTEEISM.getCode(), month)); 
        List leaveDateList = this.attendanceMapper.findLeaveDate(attendanceMonthVO.getStaffId(), AttendanceStatusEnum.LEAVE.getCode(), month); 
        int count = 0; 
        for (Date date : leaveDateList) { 
            if (!DateUtil.isWeekend(date)) { 
                count++; 
            } 
        } 
        attendanceMonthVO.setLeaveDays(count); 
    } 
    String yearMonth = month.substring(0, 4) + "年" + month.substring(4) + "月"; 
    HutoolExcelUtil.writeExcel(response, list, yearMonth + "考勤报表", AttendanceMonthVO.class); 
    return Response.success(); 
}

流程: 首先获取所有员工的基本数据信息,然后根据员工 id 和月份查询员工在此月份迟到、 早退、旷工的次数和休假的天数,此处休假的天数不包含周末。

4.12、工资调整

通过修改基本工资、以及生活补贴、奖金完成员工工资的基本调整。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第17张图片

工资保存接口:

@PostMapping("/set") public ResponseDTO setSalary(@RequestBody Salary salary)

接口说明: 当员工的基本工资信息填写完毕之后,将员工的工资数据保存到数据库。

核心代码:

public ResponseDTO setSalary(Salary salary) { 
    QueryWrapper query = new QueryWrapper<>(); 
    query.eq("month", salary.getMonth()).eq("staff_id", salary.getStaffId()); 
    if (saveOrUpdate(salary, query)) { 
        return Response.success(); 
    } 
    return Response.error(); 
}

流程: 当员工工资信息被提交之后,首先根据月份和员工 id 查询是否有当前员工的工资信 息,如果没有就添加,有则更新。

4.13、月工资报表导出

通过汇总当月员工的考勤状况、以及社保、基本工资,得到员工当月的工资报表。

【毕业设计】基于SpringBoot+Vue+ElementUI的人力资源管理系统源码_第18张图片

报表导出接口:

@GetMapping("/export/{month}") public ResponseDTO export(HttpServletResponse response, @PathVariable String month)

接口说明: 如果不选择月份,默认导出当前月份的工资报表。

核心代码:

private void setSalaryInfo(String month, List list) {
    for (StaffSalaryVO staffSalaryVO : list) { 
        BigDecimal lateDeduct = BigDecimal.valueOf(this.attendanceMapper.countTimes(staffSalaryVO.getStaffId(), AttendanceStatusEnum.LATE.getCode(), month) * 50); 
        staffSalaryVO.setLateDeduct(lateDeduct); 
        BigDecimal leaveEarlyDeduct = BigDecimal.valueOf(this.attendanceMapper.countTimes(staffSalaryVO.getStaffId(), AttendanceStatusEnum.LEAVE_EARLY.getCode(), month) * 50);
        staffSalaryVO.setLeaveEarlyDeduct(leaveEarlyDeduct); 
        BigDecimal absenteeismDeduct = BigDecimal.valueOf(this.attendanceMapper.countTimes(staffSalaryVO.getStaffId(), AttendanceStatusEnum.ABSENTEEISM.getCode(), month) * 100);
        staffSalaryVO.setAbsenteeismDeduct(absenteeismDeduct); 
        List leaveDateList = this.attendanceMapper.findLeaveDate(staffSalaryVO.getStaffId(), AttendanceStatusEnum.LEAVE.getCode(), month); int count = 0; 
        for (Date date : leaveDateList) { 
            if (!DateUtil.isWeekend(date)) { 
                count++; 
            } 
        } 
        BigDecimal leaveDeduct = (BigDecimal.valueOf(count * 80));
        staffSalaryVO.setLeaveDeduct(leaveDeduct); 
        QueryWrapper queryWrapper = new QueryWrapper<>(); 
        queryWrapper.eq("staff_id", staffSalaryVO.getStaffId()).eq("month", month); Salary one = getOne(queryWrapper); 
        if (one != null) {
            staffSalaryVO.setBaseSalary(one.getBaseSalary()).setSubsidy(one.getSubsidy()) .setBonus(one.getBonus()).setRemark(one.getRemark()) .setTotalSalary(one.getBaseSalary() .add(one.getBonus()) .add(one.getSubsidy()) .subtract(lateDeduct) .subtract(leaveEarlyDeduct) .subtract(absenteeismDeduct) .subtract(leaveDeduct) .subtract(staffSalaryVO.getSocialPay()) .subtract(staffSalaryVO.getHousePay())); 
        } 
    } 
}

流程: 当进行数据导出时,系统首先统计员工当前月的迟到、早退、旷工的次数和休假的 天数,再根据罚款规则得到相应的扣款金额。

5、源码获取

https://download.csdn.net/download/tyxjolin/87615754

你可能感兴趣的:(vue.js,spring,boot,elementui)