打卡和考勤调整

This commit is contained in:
andy 2025-06-02 13:31:22 +08:00
parent 25098b059d
commit c4a661c281
42 changed files with 1699 additions and 910 deletions

View File

@ -209,7 +209,11 @@
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<version>15.4</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -5,6 +5,7 @@ import com.evo.common.core.controller.BaseController;
import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.AjaxResult;
import com.evo.common.core.page.TableDataInfo; import com.evo.common.core.page.TableDataInfo;
import com.evo.common.enums.BusinessType; import com.evo.common.enums.BusinessType;
import com.evo.common.utils.StringUtils;
import com.evo.common.utils.poi.ExcelUtil; import com.evo.common.utils.poi.ExcelUtil;
import com.evo.attendance.domain.RzAttendanceStatistical; import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.service.IRzAttendanceStatisticalService; import com.evo.attendance.service.IRzAttendanceStatisticalService;
@ -81,7 +82,10 @@ public class RzAttendanceStatisticalController extends BaseController
@RequestMapping(value = "correct") @RequestMapping(value = "correct")
public AjaxResult correct(@RequestBody RzAttendanceStatistical rzAttendanceStatistical) public AjaxResult correct(@RequestBody RzAttendanceStatistical rzAttendanceStatistical)
{ {
return rzAttendanceStatisticalService.correct(rzAttendanceStatistical); if (StringUtils.isNull(rzAttendanceStatistical) || StringUtils.isNull(rzAttendanceStatistical.getMonth())) {
return AjaxResult.error("请输入校正日期!!");
}
return rzAttendanceStatisticalService.autoCalculateTheDayBeforeAttendance(rzAttendanceStatistical.getMonth());
} }
@PreAuthorize("@ss.hasPermi('attendance:statistics:import')") @PreAuthorize("@ss.hasPermi('attendance:statistics:import')")

View File

@ -1,9 +1,6 @@
package com.evo.attendance.domain; package com.evo.attendance.domain;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.evo.common.annotation.Excel; import com.evo.common.annotation.Excel;
import com.evo.common.core.domain.BaseEntity; import com.evo.common.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
@ -111,7 +108,14 @@ public class RzAttendance extends BaseEntity {
/** /**
* 删除标识 * 删除标识
*/ */
@TableField(fill = FieldFill.INSERT)
private String delFlag; private String delFlag;
/***
* 请假类型
*/
private Long holidayType;
@TableField(exist = false) @TableField(exist = false)
private Date startTime; private Date startTime;
@TableField(exist = false) @TableField(exist = false)

View File

@ -3,6 +3,7 @@ package com.evo.attendance.domain;
import com.evo.common.annotation.Excel; import com.evo.common.annotation.Excel;
import com.evo.common.core.domain.BaseEntity; import com.evo.common.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@ -14,6 +15,7 @@ import java.util.Date;
* @author chenyj * @author chenyj
* @date 2024-09-14 * @date 2024-09-14
*/ */
@Data
public class RzAttendanceDetail extends BaseEntity public class RzAttendanceDetail extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -25,6 +27,10 @@ public class RzAttendanceDetail extends BaseEntity
@Excel(name = "用户id") @Excel(name = "用户id")
private Long staffId; private Long staffId;
/** 考勤记录Id */
@Excel(name = "考勤记录Id")
private Long attendanceId;
/** 姓名 */ /** 姓名 */
@Excel(name = "姓名") @Excel(name = "姓名")
private String name; private String name;
@ -47,79 +53,6 @@ public class RzAttendanceDetail extends BaseEntity
/** 删除标记 */ /** 删除标记 */
private String delFlag; private String delFlag;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setStaffId(Long staffId)
{
this.staffId = staffId;
}
public Long getStaffId()
{
return staffId;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setEquipmentCode(String equipmentCode)
{
this.equipmentCode = equipmentCode;
}
public String getEquipmentCode()
{
return equipmentCode;
}
public void setButtonType(String buttonType)
{
this.buttonType = buttonType;
}
public String getButtonType()
{
return buttonType;
}
public void setDateTime(Date dateTime)
{
this.dateTime = dateTime;
}
public Date getDateTime()
{
return dateTime;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -1,8 +1,11 @@
package com.evo.attendance.domain; package com.evo.attendance.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.evo.common.annotation.Excel; import com.evo.common.annotation.Excel;
import com.evo.common.core.domain.BaseEntity; import com.evo.common.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -15,6 +18,7 @@ import java.util.List;
* @author chenyj * @author chenyj
* @date 2024-09-05 * @date 2024-09-05
*/ */
@Data
public class RzAttendanceStatistical extends BaseEntity public class RzAttendanceStatistical extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -33,9 +37,10 @@ public class RzAttendanceStatistical extends BaseEntity
/** 所属部门 */ /** 所属部门 */
private Long deptId; private Long deptId;
@TableField(exist = false)
private List<Long> deptIds; private List<Long> deptIds;
@Excel(name = "所属部门") @Excel(name = "所属部门")
@TableField(exist = false)
private String deptName; private String deptName;
/** 员工姓名 */ /** 员工姓名 */
@ -62,7 +67,7 @@ public class RzAttendanceStatistical extends BaseEntity
@Excel(name = "请假时长(小时)") @Excel(name = "请假时长(小时)")
private BigDecimal absenteeism; private BigDecimal absenteeism;
/** 请假时长(小时) */ /** 特殊加班(小时) */
@Excel(name = "特殊加班(小时)") @Excel(name = "特殊加班(小时)")
private BigDecimal overTimeHours; private BigDecimal overTimeHours;
@ -87,176 +92,10 @@ public class RzAttendanceStatistical extends BaseEntity
private Long middleShiftNumber; private Long middleShiftNumber;
/** 删除标识 */ /** 删除标识 */
@TableField(fill = FieldFill.INSERT)
private String delFlag; private String delFlag;
public BigDecimal getOverTimeHours() {
return overTimeHours;
}
public void setOverTimeHours(BigDecimal overTimeHours) {
this.overTimeHours = overTimeHours;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public List<Long> getDeptIds() {
return deptIds;
}
public void setDeptIds(List<Long> deptIds) {
this.deptIds = deptIds;
}
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setStaffId(Long staffId)
{
this.staffId = staffId;
}
public Long getStaffId()
{
return staffId;
}
public void setMonth(Date month)
{
this.month = month;
}
public Date getMonth()
{
return month;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setShouldAttendance(BigDecimal shouldAttendance)
{
this.shouldAttendance = shouldAttendance;
}
public BigDecimal getShouldAttendance()
{
return shouldAttendance;
}
public void setRealAttendance(BigDecimal realAttendance)
{
this.realAttendance = realAttendance;
}
public BigDecimal getRealAttendance()
{
return realAttendance;
}
public void setEssentialAttendance(BigDecimal essentialAttendance)
{
this.essentialAttendance = essentialAttendance;
}
public BigDecimal getEssentialAttendance()
{
return essentialAttendance;
}
public void setWorkOvertimeNumber(BigDecimal workOvertimeNumber)
{
this.workOvertimeNumber = workOvertimeNumber;
}
public BigDecimal getWorkOvertimeNumber()
{
return workOvertimeNumber;
}
public void setAbsenteeism(BigDecimal absenteeism)
{
this.absenteeism = absenteeism;
}
public BigDecimal getAbsenteeism()
{
return absenteeism;
}
public void setLateNumber(Long lateNumber)
{
this.lateNumber = lateNumber;
}
public Long getLateNumber()
{
return lateNumber;
}
public void setLeaveEarly(Long leaveEarly)
{
this.leaveEarly = leaveEarly;
}
public Long getLeaveEarly()
{
return leaveEarly;
}
public void setLessNumber(Long lessNumber)
{
this.lessNumber = lessNumber;
}
public Long getLessNumber()
{
return lessNumber;
}
public void setNightNumber(Long nightNumber)
{
this.nightNumber = nightNumber;
}
public Long getNightNumber()
{
return nightNumber;
}
public void setMiddleShiftNumber(Long middleShiftNumber)
{
this.middleShiftNumber = middleShiftNumber;
}
public Long getMiddleShiftNumber()
{
return middleShiftNumber;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
@Override @Override
public String toString() { public String toString() {

View File

@ -8,6 +8,13 @@ public class RzAttendanceData {
return button; return button;
} }
public RzAttendanceData() {
}
public RzAttendanceData(String button) {
this.button = button;
}
public void setButton(String button) { public void setButton(String button) {
this.button = button; this.button = button;
} }

View File

@ -1,28 +1,28 @@
package com.evo.attendance.domain.vo; package com.evo.attendance.domain.vo;
import lombok.Data;
@Data
public class RzAttendanceVo { public class RzAttendanceVo {
private int Result; private int Result;
private String Msg; private String Msg;
private RzAttendanceData Content; private RzAttendanceData Content;
public int getResult() {
return Result; public RzAttendanceVo() {
} }
public void setResult(int result) {
public RzAttendanceVo(int result, String msg) {
Result = result; Result = result;
}
public String getMsg() {
return Msg;
}
public void setMsg(String msg) {
Msg = msg; Msg = msg;
} }
public RzAttendanceData getContent() {
return Content; public RzAttendanceVo(int result, String msg, RzAttendanceData content) {
} Result = result;
public void setContent(RzAttendanceData content) { Msg = msg;
Content = content; Content = content;
} }
@Override @Override
public String toString() { public String toString() {
return "RzAttendanceVo [Result=" + Result + ", Msg=" + Msg + ", Content=" + Content + "]"; return "RzAttendanceVo [Result=" + Result + ", Msg=" + Msg + ", Content=" + Content + "]";

View File

@ -41,15 +41,12 @@ public interface RzAttendanceDetailMapper extends BaseMapper<RzAttendanceDetail>
public int updateRzAttendanceDetail(RzAttendanceDetail rzAttendanceDetail); public int updateRzAttendanceDetail(RzAttendanceDetail rzAttendanceDetail);
/** /**
* 查询员工最后一次上班打卡 计算工时 * 查询员工最后一次上班打卡 计算工时 其他地方不可使用
* *
* @param staffId * @param staffId
* @return 考勤明细集合 * @return 考勤明细集合
*/ */
public default RzAttendanceDetail selectRzAttendanceDetailByStaffId(@Param("staffId") Long staffId) { public RzAttendanceDetail selectRzAttendanceDetailByStaffId(@Param("staffId") Long staffId);
return null;
}
public List<RzAttendanceDetail> selectRzAttendanceDetailByMonth(Date date); public List<RzAttendanceDetail> selectRzAttendanceDetailByMonth(Date date);
} }

View File

@ -1,10 +1,14 @@
package com.evo.attendance.mapper; package com.evo.attendance.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.mapper.Mapper;
import com.evo.attendance.domain.RzAttendance; import com.evo.attendance.domain.RzAttendance;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.springframework.security.core.parameters.P;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 考勤记录Mapper接口 * 考勤记录Mapper接口
@ -80,4 +84,6 @@ public interface RzAttendanceMapper extends BaseMapper<RzAttendance> {
*/ */
public List<RzAttendance> currentDateAllAttendance(); public List<RzAttendance> currentDateAllAttendance();
List<Map<String,Object>> getAttendanceHour(@Param("date") Date date);
} }

View File

@ -1,10 +1,12 @@
package com.evo.attendance.mapper; package com.evo.attendance.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.attendance.domain.RzSpecialAttendance; import com.evo.attendance.domain.RzSpecialAttendance;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 加班考勤记录Mapper接口 * 加班考勤记录Mapper接口
@ -12,7 +14,7 @@ import java.util.List;
* @author evo * @author evo
* @date 2025-04-15 * @date 2025-04-15
*/ */
public interface RzSpecialAttendanceMapper public interface RzSpecialAttendanceMapper extends BaseMapper<RzSpecialAttendance>
{ {
/** /**
* 查询加班考勤记录 * 查询加班考勤记录
@ -46,6 +48,8 @@ public interface RzSpecialAttendanceMapper
*/ */
public int updateRzSpecialAttendance(RzSpecialAttendance rzSpecialAttendance); public int updateRzSpecialAttendance(RzSpecialAttendance rzSpecialAttendance);
public RzSpecialAttendance selectRzSpecialAttendanceByuserIdAndDate(@Param("staffId") Long staffId,@Param("date") Date date); public RzSpecialAttendance selectRzSpecialAttendanceByUserIdAndDate(@Param("staffId") Long staffId,@Param("date") Date date);
List<Map<String,Object>> getSpecialAttendanceHour(@Param("date") Date date);
} }

View File

@ -0,0 +1,88 @@
package com.evo.attendance.processor;
import com.alibaba.fastjson2.JSONObject;
import com.evo.attendance.domain.vo.RzAttendanceData;
import com.evo.attendance.domain.vo.RzAttendanceVo;
import com.evo.common.constant.Constants;
import com.evo.common.utils.Collections;
import com.evo.common.utils.StringUtils;
import com.evo.common.utils.spring.SpringUtils;
import com.evo.equipment.domain.EqButton;
import com.evo.equipment.mapper.EqButtonMapper;
import com.evo.system.domain.SysStaff;
import com.evo.system.mapper.SysStaffMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 打开处理接口
*
* @ClassName:PunchTheClockStrategyExchangeProcessor
* @date: 2025年05月28日 11:58
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public interface PunchTheClockStrategyExchangeProcessor {
Logger logger = LoggerFactory.getLogger(PunchTheClockStrategyExchangeProcessor.class);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd");
boolean accept(String sn);
/***
* 设备按钮下发
* @param userId
* @param sn
* @return
*/
String exchangeButton(String userId, String sn);
/***
* 打卡信息回传
* @param userId
* @param sn
* @param date
* @param button
* @param rules
* @return
*/
String exchangeFace(String userId, String sn, Date date, String button, String rules);
default String checkStaff(SysStaff sysStaff, String sn){
if(sysStaff == null){
return "当前人员不存在";
}
if(Constants.JOB_STATIS_11.equals(sysStaff.getStatus())){
return "当前人员已离职";
}
if(StringUtils.isEmpty(sysStaff.getTimeClock())){
return "当前人员未注册打卡机";
}
if(!sn.equals(com.evo.equipment.constant.Constants.EQ_DEVICE_PUBLIC_CODE) && !sn.equals(sysStaff.getTimeClock())){
return "未设置当前考勤机打卡权限";
}
return "";
}
default String initMessage(Integer result, String meg){
//需要返回的对象, 默认失败
return JSONObject.toJSONString(new RzAttendanceVo(result, meg, null));
}
default String initMessage(Integer result, String meg, String buttonPermission){
//需要返回的对象, 默认失败
if(StringUtils.isNotEmpty(buttonPermission)){
return JSONObject.toJSONString(new RzAttendanceVo(result, meg, new RzAttendanceData(buttonPermission)));
}
return JSONObject.toJSONString(new RzAttendanceVo(result, meg));
}
}

View File

@ -0,0 +1,385 @@
package com.evo.attendance.processor.impl;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.evo.attendance.domain.RzAttendance;
import com.evo.attendance.domain.RzAttendanceDetail;
import com.evo.attendance.mapper.RzAttendanceDetailMapper;
import com.evo.attendance.mapper.RzAttendanceMapper;
import com.evo.attendance.processor.PunchTheClockStrategyExchangeProcessor;
import com.evo.common.constant.Constants;
import com.evo.common.core.domain.entity.SysDept;
import com.evo.common.utils.Collections;
import com.evo.common.utils.DateUtils;
import com.evo.common.utils.ParamUtils;
import com.evo.common.utils.StringUtils;
import com.evo.equipment.domain.EqButton;
import com.evo.equipment.mapper.EqButtonMapper;
import com.evo.personnelMatters.domain.EqOverStaff;
import com.evo.personnelMatters.domain.RzOverTime;
import com.evo.personnelMatters.domain.RzOverTimeDetail;
import com.evo.personnelMatters.mapper.EqOverStaffMapper;
import com.evo.personnelMatters.mapper.RzOverTimeDetailMapper;
import com.evo.personnelMatters.mapper.RzOverTimeMapper;
import com.evo.system.domain.SysStaff;
import com.evo.system.mapper.SysDeptMapper;
import com.evo.system.mapper.SysStaffMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.math.BigDecimal;
import java.util.Date;
/**
* 考勤设备打卡类
*
* @ClassName:TSDeviceExchangeProcessor
* @date: 2025年05月28日 13:13
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Service
public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeProcessor {
@Resource
private SysStaffMapper sysStaffMapper;
@Resource
private RzAttendanceDetailMapper rzAttendanceDetailMapper;
@Resource
private RzOverTimeMapper rzOverTimeMapper;
@Resource
private RzOverTimeDetailMapper rzOverTimeDetailMapper;
@Resource
private RzAttendanceMapper rzAttendanceMapper;
@Resource
private EqButtonMapper eqButtonMapper;
@Resource
private EqOverStaffMapper eqOverStaffMapper;
@Resource
private SysDeptMapper sysDeptMapper;
@Override
public boolean accept(String sn) {
//餐饮打卡机不下发按钮
return !com.evo.equipment.constant.Constants.EQ_DEVICE_OVER_TIME_CODE.equals(sn);
}
@Override
public String exchangeButton(String userId, String sn) {
//根据ID查询在职员工信息
SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));
//员工不存在
if(StringUtils.isNull(sysStaff)){
return initMessage(1,"当前人员不存在", "000000000");
}
if(Constants.JOB_STATIS_11.equals(sysStaff.getStatus())){
return initMessage(1,"当前人员已离职", "000000000");
}
if(StringUtils.isEmpty(sysStaff.getTimeClock())){
return initMessage(1,"当前人员未注册打卡机", "000000000");
}
//当前设备不是公共打卡机, 并且
if(!sn.equals(com.evo.equipment.constant.Constants.EQ_DEVICE_PUBLIC_CODE) && !sn.equals(sysStaff.getTimeClock())){
return initMessage(1,"未设置当前考勤机打卡权限", "000000000");
}
//查询员工的最后一次打卡 按钮切换
RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectLastRzAttendanceDetail(sysStaff.getUserId());
//判断最后一次打卡为下班卡或没有打卡记录则打卡为上班卡
if(StringUtils.isNull(rzAttendanceDetail) || "下班卡".equals(rzAttendanceDetail.getButtonType()) || "撤销".equals(rzAttendanceDetail.getButtonType())){
//如果最后一条数据的卡类型为下班卡则返回上班卡和加班卡权限 or 检查当前人员是否存在特殊加班中 或者 检查当前人员部门是否开启加班
if(ObjectUtils.isNotEmpty(eqOverStaffMapper.selectEqOverStaffByUserId(sysStaff.getUserId())) || ObjectUtils.isEmpty(sysDeptMapper.selectOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDeptId, sysStaff.getDeptId()).eq(SysDept::getIsOverTime,"1")))){
//如果存在特殊加班, 或者当前部门没有开启加班, 则无法打加班卡
return initMessage(0,"验证通过", "111000000");
}
return initMessage(0,"验证通过", "111100000");
}else{
return initMessage(0,"验证通过", "000011000");
}
}
@Override
public String exchangeFace(String userId, String sn, Date date, String button, String rules) {
//根据ID查询员工信息 ,判断员工是否存在不存在返回失败
SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));//打卡记录信息
//检查用户数据
String error = checkStaff(sysStaff, sn);
if(StringUtils.isNotEmpty(error)){
return initMessage(1, error);
}
//员工考勤记录
RzAttendance attendance = rzAttendanceMapper.queryNowDayAttendanceByStatisticalIdAndDate(Long.valueOf(userId),date);
//如果当前打卡是下班卡, 并且当前员工考勤上班时间为空, 则判定为隔天打下班卡
if(rules.contains("下班") && attendance.getWorkStartTime() == null){
//获取最后一次的上班记录
attendance = rzAttendanceMapper.selectLastRzAttendanceByStaffId(Long.valueOf(userId));
}
//获取员工的工作时长
RzAttendanceDetail attendanceDetail = new RzAttendanceDetail();
//打卡明细表中插入数据
attendanceDetail.setButtonType(rules);
attendanceDetail.setName(sysStaff.getName());
attendanceDetail.setAttendanceId(attendance.getId());
attendanceDetail.setDateTime(date);
attendanceDetail.setDelFlag(Constants.DELETE_FLAG_0);
attendanceDetail.setStaffId(sysStaff.getUserId());
attendanceDetail.setEquipmentCode(sn);
attendanceDetail.setCreateTime(new Date());
if(rzAttendanceDetailMapper.insert(attendanceDetail) < 1){
return initMessage(1, "打卡失败");
}
//打的是加班卡加班列表中填写数据
if(rules.contains("加班")){
return overTimeCard(sysStaff, date);
}
//判断是撤销卡
if(rules.contains("撤销")){
return revocationCard(sysStaff, date, attendanceDetail);
}
//上班卡
if(rules.contains("上班")){
return workCard(sysStaff.getUserId(), date, rules);
}
// 查询员工的最后一次上班打卡信息
RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectRzAttendanceDetailByStaffId(Long.valueOf(userId));
//加班的下班卡
if(rzAttendanceDetail.getButtonType().contains("加班")){
return overTimeOffDutyCard(sysStaff, date, sn);
}
//上班的下班卡
if(rzAttendanceDetail.getButtonType().contains("上班")){
return workOffDutyCard( date, rzAttendanceDetail.getButtonType(), attendance);
}
return initMessage(1, "打卡失败");
}
/*** 上班卡
* @param userId
* @param date
* @param rules
* @return
*/
public String workCard(Long userId, Date date, String rules){
//员工考勤记录
RzAttendance attendance = rzAttendanceMapper.queryNowDayAttendanceByStatisticalIdAndDate(Long.valueOf(userId),date);
attendance.setRules(rules);
attendance.setWorkStartTime(date);
try{
if(checkYc("上班", rules, sdf.format(date), sdfd.format(date))){
attendance.setYcsFlag("1");
}
}catch (Exception e){
return initMessage(1, "打卡失败,"+e.getMessage());
}
return (rzAttendanceMapper.updateRzAttendance(attendance) > 0) ? initMessage(0, "打卡成功") : initMessage(1, "打卡失败");
}
/*** 上班卡的下班卡
* @param date
* @param rules
* @return
*/
public String workOffDutyCard(Date date, String rules, RzAttendance attendance){
//计算工时
Long hours = (date.getTime() - attendance.getWorkStartTime().getTime())/1000/60/60;
EqButton eqButton = eqButtonMapper.selectOne(new LambdaQueryWrapper<EqButton>().eq(EqButton::getName, rules));
//判断打卡时间, 添加夜班次数 打卡时间在晚上7点以后
if(eqButton.getWorkHour() ==12 && hours >= 12 && attendance.getWorkStartTime().getHours() > 12){
attendance.setNightNumber(1);
}else if(eqButton.getWorkHour() == 8 && hours >= 8 && attendance.getWorkStartTime().getHours() > 18){
attendance.setMiddleShiftNumber(1);
}
//获取工作时长
BigDecimal res = new BigDecimal(hours);
if(hours.compareTo(Long.valueOf(eqButton.getWorkHour())) >= 0){
res = new BigDecimal(eqButton.getWorkHour());
}
// else if(hours.compareTo(Long.valueOf(eqButton.getWorkHour()/2)) > 0){
// res = new BigDecimal(eqButton.getWorkHour()/2);
// }
//检查是否异常
if(checkYc("下班", rules, sdf.format(date), sdfd.format(date))){
attendance.setYcxFlag("1");
}
attendance.setWorkEndTime(date);
attendance.setWorkSum(res);
return (rzAttendanceMapper.updateRzAttendance(attendance) > 0) ? initMessage(0, "打卡成功") : initMessage(1,"打卡失败");
}
/*** 校验是否上班卡打卡异常
* @param rules
* @param dateTime
* @param date
* @return
*/
public Boolean checkYc(String type, String rules, String dateTime, String date){
String script = ParamUtils.getYcRulesByButtonName(type, rules);
if(StringUtils.isEmpty(script)){
return false;
}
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
try {
Object result = engine.eval(script.replaceAll("dkDateTime",dateTime).replaceAll("dkDate", date));
System.out.println("检查结果"+result);
return new Boolean(String.valueOf(result));
} catch (Exception e) {
logger.error("打卡交易是否异常出现错误{}", e.getMessage());
}
//默认为没有异常
return false;
}
/*** 撤销卡
* @param date
* @return
*/
public String revocationCard(SysStaff sysStaff, Date date, RzAttendanceDetail revocationDetail){
//员工考勤记录
/***
* 倒序获取最后一条打卡详情, 获取最后一次打卡的规则
* 1. 如果是上班卡, 直接走清除规则逻辑并删除打卡详情
* 2. 如果是加班卡, 并倒序获取最后一条加班打卡详情 并删除加班详情
*
* PS. 实际测试中发现, 不存在打完下班卡后打撤销卡
* 3 如果是下班卡,
* 3.1 需要获取倒数第二条的数据,
* 3.2 如果是加班卡, 同步清除加班卡的数据, 并删除加班详情
* 3.3 如果是上班卡, 同步清除上班数据, 并删除打卡详情
*/
// 查询员工的最后一次上班打卡信息
RzAttendanceDetail rzAttendanceDetail = getLastDetailByUserIdAndDate(sysStaff.getUserId(), revocationDetail.getId());
rzAttendanceDetail.setDelFlag(Constants.DELETE_FLAG_1);
// 规则1
if(rzAttendanceDetail.getButtonType().contains("上班")){
RzAttendance attendance = rzAttendanceMapper.queryNowDayAttendanceByStatisticalIdAndDate(sysStaff.getUserId(),date);
attendance.setRules("");
attendance.setYcsFlag("");
//如果是规则1
return ((rzAttendanceMapper.updateById(attendance) > 0 && rzAttendanceDetailMapper.updateById(rzAttendanceDetail) > 0) ? initMessage(0, "打卡成功") : initMessage(1, "打卡失败"));
}
// 规则2
if(rzAttendanceDetail.getButtonType().contains("加班")){
RzOverTimeDetail overTimeDetail = getLastRzOverTimeDetailByUserIdAndDate(sysStaff.getUserId(), revocationDetail.getId());
return ((rzOverTimeDetailMapper.deleteById(overTimeDetail) > 0 && rzAttendanceDetailMapper.updateById(rzAttendanceDetail) > 0) ? initMessage(0, "打卡成功") : initMessage(1, "打卡失败"));
}
//规则3
// if(rzAttendanceDetail.getButtonType().contains("下班")){
// //3.1 获取倒数第二条数据
// RzAttendanceDetail last2AttendanceDetail = getLastDetailByUserIdAndDate(sysStaff.getUserId(), rzAttendanceDetail.getId(), revocationDetail.getId());
// //3.2 加班卡
// if(last2AttendanceDetail.getButtonType().contains("加班")){
// //如果倒数第二条是加班的话, 获取最后一条加班数据
// RzOverTimeDetail overTimeDetail = getLastRzOverTimeDetailByUserIdAndDate(sysStaff.getUserId(), null);
// overTimeDetail.setOverTimeEnd(null);
// //获取加班统计
// RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeById(overTimeDetail.getOverTimeId());
// rzOverTime.setTaskHours(rzOverTime.getOverHours().subtract(overTimeDetail.getOverTimeHours()));
// overTimeDetail.setOverTimeHours(new BigDecimal(0));
// return (rzOverTimeDetailMapper.updateById(overTimeDetail) > 1 && rzOverTimeMapper.updateById(rzOverTime) > 0 && rzAttendanceDetailMapper.updateById(rzAttendanceDetail) > 0) ? initMessage(0, "打卡成功") : initMessage(1, "打卡失败");
// }
// //3.2 上班卡
// if(last2AttendanceDetail.getButtonType().contains("上班")){
// //获取所属哪一个考勤记录
// RzAttendance attendance = rzAttendanceMapper.selectById(rzAttendanceDetail.getAttendanceId());
// //如果是规则1
// attendance.setNightNumber(0);
// attendance.setMiddleShiftNumber(0);
// attendance.setYcxFlag("");
// attendance.setWorkEndTime(null);
// attendance.setWorkSum(new BigDecimal(0));
// return (rzAttendanceMapper.updateById(attendance) > 0 && rzAttendanceDetailMapper.updateById(rzAttendanceDetail) > 0) ? initMessage(0, "打卡成功") : initMessage(1, "打卡失败");
// }
// }
return initMessage(1, "打卡失败");
}
public RzOverTimeDetail getLastRzOverTimeDetailByUserIdAndDate(Long userId, Long notId){
return rzOverTimeDetailMapper.getLastRzOverTimeDetailByUserIdAndNotId(userId, notId);
}
public RzAttendanceDetail getLastDetailByUserIdAndDate(Long userId, Long... notId){
return rzAttendanceDetailMapper.selectOne(new LambdaQueryWrapper<RzAttendanceDetail>().eq(RzAttendanceDetail::getStaffId,userId).notIn(Collections.isNotEmpty(notId), RzAttendanceDetail::getId, notId).orderByDesc(RzAttendanceDetail::getDateTime).last(" limit 1"));
}
/*** 加班卡
* @param sysStaff
* @param date
* @return
*/
public String overTimeCard(SysStaff sysStaff , Date date){
//判断打卡月是否统计过加班
RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(sysStaff.getUserId(),date);
if(rzOverTime == null){
rzOverTime = new RzOverTime();
rzOverTime.setUserId(sysStaff.getUserId());
rzOverTime.setOverHours(new BigDecimal("0.0"));
rzOverTime.setDeptId(sysStaff.getDeptId());
rzOverTime.setName(sysStaff.getName());
rzOverTime.setOverTimeMonth(date);
if(rzOverTimeMapper.insert(rzOverTime) < 1){
return initMessage(1, "打卡失败");
}
}
RzOverTimeDetail rzOverTimeDetail = new RzOverTimeDetail();
rzOverTimeDetail.setOverTimeId(rzOverTime.getId());
rzOverTimeDetail.setOverTimeStart(date);
rzOverTimeDetail.setName(sysStaff.getName());
rzOverTimeDetail.setDelFlag(Constants.DELETE_FLAG_0);
rzOverTimeDetail.setCreateBy("admin");
rzOverTimeDetail.setCreateTime(DateUtils.getNowDate());
return (rzOverTimeDetailMapper.insert(rzOverTimeDetail) < 1) ? initMessage(1, "打卡失败") : initMessage(0, "打卡成功");
}
/*** 加班的下班卡
* @param sysStaff
* @param date
* @return
*/
public String overTimeOffDutyCard(SysStaff sysStaff , Date date, String sn){
//修改加班打卡记录 根据员工ID和时间查找 统计数据
RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(sysStaff.getUserId(),date);
//查找加班详情 加班统计ID和加班开始时间
RzOverTimeDetail rzOverTimeDetail = rzOverTimeDetailMapper.queryRzOverTimeDetailByDateAndOverId(rzOverTime.getId(),date);
rzOverTimeDetail.setOverTimeEnd(date);
//计算加班时长 小时
double hours = (rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60/60;
//获取规则
JSONObject deviceRules = ParamUtils.getDeviceOverTimeRules(sn);
//获取最大加班时长
Integer maxOverTimeHour = deviceRules.getInteger("maxHour");
//记录加班时长
rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(((hours > maxOverTimeHour) ? maxOverTimeHour : hours)));
if(rzOverTimeDetailMapper.updateRzOverTimeDetail(rzOverTimeDetail) < 1){
return initMessage(1, "打卡失败");
}
//加班修改统计
rzOverTime.setOverHours(rzOverTime.getOverHours().add(rzOverTimeDetail.getOverTimeHours()));
if(rzOverTimeMapper.updateRzOverTime(rzOverTime) < 1){
return initMessage(1, "打卡失败");
}
return initMessage(0, "打卡成功");
}
}

View File

@ -0,0 +1,173 @@
package com.evo.attendance.processor.impl;
import com.alibaba.fastjson2.JSONObject;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.domain.RzSpecialAttendance;
import com.evo.attendance.domain.RzSpecialOverTime;
import com.evo.attendance.mapper.RzAttendanceStatisticalMapper;
import com.evo.attendance.mapper.RzSpecialAttendanceMapper;
import com.evo.attendance.mapper.RzSpecialOverTimeMapper;
import com.evo.attendance.processor.PunchTheClockStrategyExchangeProcessor;
import com.evo.common.constant.Constants;
import com.evo.common.utils.DateUtils;
import com.evo.common.utils.ParamUtils;
import com.evo.common.utils.StringUtils;
import com.evo.personnelMatters.domain.EqOverStaff;
import com.evo.personnelMatters.domain.SpecialOverTime;
import com.evo.personnelMatters.mapper.BsOverTimeMapper;
import com.evo.personnelMatters.mapper.EqOverStaffMapper;
import com.evo.system.domain.SysStaff;
import com.evo.system.mapper.SysStaffMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
/**
* 特殊加班类
*
* @ClassName:TSDeviceExchangeProcessor
* @date: 2025年05月28日 13:13
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Service
public class TSDeviceExchangeProcessor implements PunchTheClockStrategyExchangeProcessor {
@Resource
private SysStaffMapper sysStaffMapper;
@Resource
private RzSpecialAttendanceMapper rzSpecialAttendanceMapper;
@Resource
private RzSpecialOverTimeMapper rzSpecialOverTimeMapper;
@Resource
private BsOverTimeMapper bsOverTimeMapper;
@Resource
private EqOverStaffMapper eqOverStaffMapper;
@Override
public boolean accept(String sn) {
return com.evo.equipment.constant.Constants.EQ_DEVICE_OVER_TIME_CODE.equals(sn);
}
@Override
public String exchangeButton(String userId, String sn) {
//根据ID查询在职员工信息
SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));
//检查当前人员是否存在特殊加班中
EqOverStaff eqOverStaff = eqOverStaffMapper.selectEqOverStaffByUserId(Long.valueOf(userId));
if(StringUtils.isNull(eqOverStaff)){
return initMessage(1,"未设置当前考勤机打卡权限", "000000000");
}
if(Constants.JOB_STATIS_11.equals(sysStaff.getStatus())){
return initMessage(1,"当前人员已离职", "000000000");
}
//检查是否有上班的打卡
RzSpecialAttendance rzSpecialAttendance = rzSpecialAttendanceMapper.selectRzSpecialAttendanceByUserIdAndDate(Long.valueOf(userId),new Date());
if(StringUtils.isNull(rzSpecialAttendance)){
return initMessage(0,"验证通过", "000100000");
}else{
return initMessage(0,"验证通过", "000010000");
}
}
@Override
public String exchangeFace(String userId, String sn, Date date, String button, String rules) {
if(!ParamUtils.checkTsDeviceButton(sn, rules)){
return initMessage(1, "无效打卡");
}
SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));
//检查用户数据
String error = checkStaff(sysStaff, sn);
if(StringUtils.isNotEmpty(error)){
return initMessage(1, error);
}
//获取加班详情数据
RzSpecialAttendance rzSpecialAttendance = rzSpecialAttendanceMapper.selectRzSpecialAttendanceByUserIdAndDate(Long.valueOf(userId),new Date());
//如果没有, 则新增
if(rzSpecialAttendance == null){
rzSpecialAttendance = new RzSpecialAttendance();
rzSpecialAttendance.setAttendanceDate(new Date());
rzSpecialAttendance.setStaffId(Long.valueOf(userId));
rzSpecialAttendance.setName(sysStaff.getName());
rzSpecialAttendance.setDeptId(sysStaff.getDeptId());
rzSpecialAttendance.setDelFlag("0");
rzSpecialAttendance.setCreateBy("admin");
rzSpecialAttendance.setCreateTime(new Date());
rzSpecialAttendanceMapper.insertRzSpecialAttendance(rzSpecialAttendance);
}
//获取加班统计数据
RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate());
if(ObjectUtils.isEmpty(rzSpecialOverTime)){
rzSpecialOverTime = new RzSpecialOverTime();
rzSpecialOverTime.setUserId(Long.valueOf(userId));
rzSpecialOverTime.setName(sysStaff.getName());
rzSpecialOverTime.setDeptId(sysStaff.getDeptId());
rzSpecialOverTime.setDelFlag("0");
rzSpecialOverTime.setOverDate(date);
rzSpecialOverTime.setCreateTime(new Date());
rzSpecialOverTime.setCreateBy("admin");
rzSpecialOverTimeMapper.insertRzSpecialOverTime(rzSpecialOverTime);
}
//获取打卡时间范围
SpecialOverTime specialOverTime = bsOverTimeMapper.selectSpecialOverTimeById();
//特殊打卡机, 只有加班和下班, 所有不做其他类型处理
if(rules.contains("加班")){
if(date.compareTo(DateUtils.dateTime("yyyy-MM-dd HH:mm", sdfd.format(date)+" "+specialOverTime.getWorkStart())) < 0){
return initMessage(1, "当前时间不允许打加班卡");
}
rzSpecialAttendance.setWorkStartTime(date);
rzSpecialAttendanceMapper.updateRzSpecialAttendance(rzSpecialAttendance);
return initMessage(0, "打卡成功");
}
if(rules.contains("下班")){
//记录下班时间
rzSpecialAttendance.setWorkEndTime(date);
JSONObject ruleJson = ParamUtils.getDeviceOverTimeRules(sn);
//如果没有规则, 直接设置加班时长为0小时
if(ruleJson == null || !ruleJson.containsKey("endMealTime")){
rzSpecialAttendance.setWorkHours(new BigDecimal(0));
rzSpecialAttendance.setRemarks("没有找到加班规则"+sn);
rzSpecialAttendanceMapper.updateRzSpecialAttendance(rzSpecialAttendance);
return initMessage(0, "打卡成功");
}
//获取餐厅关闭时间, 核减打卡开始时间, 核验是否需要扣减加班时长
String endMealTime = ruleJson.getString("endMealTime");
Integer maxHour = ruleJson.getInteger("maxHour");
Integer minHour = ruleJson.getInteger("minHour");
//根据公司规定, 如果加班卡打卡时间早于19点,则按照19点计算
Date endMealDate = DateUtils.dateTime("yyyy-MM-dd HH:mm", sdfd.format(date)+" "+endMealTime);
if(rzSpecialAttendance.getWorkStartTime().compareTo(endMealDate) > 0){
endMealDate = rzSpecialAttendance.getWorkStartTime();
}
Long overMinutes = DateUtils.getBetweenMinutes(endMealDate, rzSpecialAttendance.getWorkEndTime());
BigDecimal workHours = new BigDecimal(0);
if(overMinutes >= (maxHour*60)){
workHours= new BigDecimal(3);
}else if(overMinutes >= (minHour*60)){
workHours = new BigDecimal(2);
}
rzSpecialAttendance.setWorkHours(workHours);
rzSpecialAttendanceMapper.updateRzSpecialAttendance(rzSpecialAttendance);
//只有当存在打卡时长的时候, 才回去进行数据的计算
if(new BigDecimal(0).compareTo(rzSpecialAttendance.getWorkHours()) != 0){
rzSpecialOverTime.setSickHours(rzSpecialOverTime.getSickHours().add(rzSpecialAttendance.getWorkHours()));
rzSpecialOverTimeMapper.updateRzSpecialOverTime(rzSpecialOverTime);
// RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate());
// if(StringUtils.isNull(rzAttendanceStatistical.getOverTimeHours())){
// rzAttendanceStatistical.setOverTimeHours(new BigDecimal(0.0));
// }
// rzAttendanceStatistical.setOverTimeHours(rzAttendanceStatistical.getOverTimeHours().add(rzSpecialAttendance.getWorkHours()));
// rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical);
}
return initMessage(0, "打卡成功");
}
return initMessage(1, "打卡失败");
}
}

View File

@ -59,4 +59,10 @@ public interface IRzAttendanceStatisticalService
* @return * @return
*/ */
RzAttendanceStatistical createRzAttendance(SysStaff sysStaff, List<String> dayList, Date date); RzAttendanceStatistical createRzAttendance(SysStaff sysStaff, List<String> dayList, Date date);
/***
* 自动计算前一天的考勤情况
*/
AjaxResult autoCalculateTheDayBeforeAttendance(Date date);
} }

View File

@ -3,10 +3,14 @@ package com.evo.attendance.service.impl;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.evo.attendance.domain.*; import com.evo.attendance.domain.*;
import com.evo.attendance.mapper.*; import com.evo.attendance.mapper.*;
import com.evo.attendance.processor.PunchTheClockStrategyExchangeProcessor;
import com.evo.common.constant.Constants; import com.evo.common.constant.Constants;
import com.evo.common.utils.Collections;
import com.evo.common.utils.DateUtils; import com.evo.common.utils.DateUtils;
import com.evo.common.utils.StringUtils; import com.evo.common.utils.StringUtils;
import com.evo.equipment.domain.EqButton;
import com.evo.equipment.domain.EqImages; import com.evo.equipment.domain.EqImages;
import com.evo.equipment.mapper.EqButtonMapper;
import com.evo.equipment.mapper.EqImagesMapper; import com.evo.equipment.mapper.EqImagesMapper;
import com.evo.attendance.domain.vo.RzAttendanceData; import com.evo.attendance.domain.vo.RzAttendanceData;
import com.evo.attendance.domain.vo.RzAttendanceVo; import com.evo.attendance.domain.vo.RzAttendanceVo;
@ -23,17 +27,25 @@ import com.evo.system.domain.SysStaff;
import com.evo.system.mapper.SysStaffDetailMapper; import com.evo.system.mapper.SysStaffDetailMapper;
import com.evo.system.mapper.SysStaffMapper; import com.evo.system.mapper.SysStaffMapper;
import com.evo.utils.DateUtil; import com.evo.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map;
@Service @Service
public class PunchTheClockServiceImpl implements PunchTheClockService { public class PunchTheClockServiceImpl implements PunchTheClockService {
@Resource
private EqButtonMapper eqButtonMapper;
@Resource @Resource
private EqImagesMapper eqImagesMapper; //照片管理 private EqImagesMapper eqImagesMapper; //照片管理
@Resource @Resource
@ -58,6 +70,8 @@ public class PunchTheClockServiceImpl implements PunchTheClockService {
private BsOverTimeMapper bsOverTimeMapper; private BsOverTimeMapper bsOverTimeMapper;
@Resource @Resource
private RzSpecialOverTimeMapper rzSpecialOverTimeMapper; private RzSpecialOverTimeMapper rzSpecialOverTimeMapper;
@Autowired
private ApplicationContext applicationContext;
/** /**
* 刷脸获取打卡按钮权限 * 刷脸获取打卡按钮权限
* sn 设备号 * sn 设备号
@ -84,93 +98,124 @@ public class PunchTheClockServiceImpl implements PunchTheClockService {
JSONObject jsonObject = JSONObject.parseObject(json); JSONObject jsonObject = JSONObject.parseObject(json);
String userId = jsonObject.getString("user_id"); String userId = jsonObject.getString("user_id");
//需要推送的数据 //需要推送的数据
String message = "";
//需要返回的对象
RzAttendanceVo cardV = new RzAttendanceVo();
RzAttendanceData cardD = new RzAttendanceData();
String sn = jsonObject.getString("sn"); String sn = jsonObject.getString("sn");
if(com.evo.equipment.constant.Constants.EQ_DEVICE_OVER_TIME_CODE.equals(sn)){
boolean flag = DateUtil.isSaturday(new Date(),1); Map<String, PunchTheClockStrategyExchangeProcessor> mqttRequestExchangeProcessorMap = applicationContext.getBeansOfType(PunchTheClockStrategyExchangeProcessor.class);
if(flag){ for (PunchTheClockStrategyExchangeProcessor processor : mqttRequestExchangeProcessorMap.values()) {
cardV.setResult(1); if(processor.accept(sn)){
cardV.setMsg("{\"Result\":1,\"Msg\":\"周日不能打卡\"}"); return processor.exchangeButton(userId, sn);
cardD.setButton("000000000");
cardV.setContent(cardD);
//Java对象转换成JSON字符串
message = JSONObject.toJSONString(cardV);
return message;
} }
EqOverStaff eqOverStaff = eqOverStaffMapper.selectEqOverStaffByUserId(Long.valueOf(userId));
if(StringUtils.isNull(eqOverStaff)){
cardV.setResult(1);
cardV.setMsg("{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}");
cardD.setButton("000000000");
cardV.setContent(cardD);
//Java对象转换成JSON字符串
message = JSONObject.toJSONString(cardV);
return message;
}
RzSpecialAttendance rzSpecialAttendance = rzSpecialAttendanceMapper.selectRzSpecialAttendanceByuserIdAndDate(Long.valueOf(userId),new Date());
if(StringUtils.isNull(rzSpecialAttendance)){
cardV.setResult(0);
cardV.setMsg("验证通过");
cardD.setButton("111100000");
cardV.setContent(cardD);
//Java对象转换成JSON字符串
message = JSONObject.toJSONString(cardV);
}else{
cardV.setResult(0);
cardV.setMsg("验证通过");
cardD.setButton("000011000");
cardV.setContent(cardD);
//Java对象转换成JSON字符串
message = JSONObject.toJSONString(cardV);
}
return message;
} }
//根据ID查询在职员工信息 return initMessage(1,"未找到打卡机信息", "000000000");
SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));
//员工不存在说明离职没有打卡权限 /***
if(StringUtils.isNull(sysStaff)){ * PS: 注解为原代码逻辑
cardV.setResult(1); * //解析收到的数据
cardV.setMsg("{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}"); * JSONObject jsonObject = JSONObject.parseObject(json);
cardD.setButton("000000000"); * String userId = jsonObject.getString("user_id");
cardV.setContent(cardD); * //需要推送的数据
//Java对象转换成JSON字符串 * String message = "";
message = JSONObject.toJSONString(cardV); * //需要返回的对象
return message; * RzAttendanceVo cardV = new RzAttendanceVo();
* RzAttendanceData cardD = new RzAttendanceData();
* String sn = jsonObject.getString("sn");
* if(com.evo.equipment.constant.Constants.EQ_DEVICE_OVER_TIME_CODE.equals(sn)){
* boolean flag = DateUtil.isSaturday(new Date(),1);
* if(flag){
* cardV.setResult(1);
* cardV.setMsg("{\"Result\":1,\"Msg\":\"周日不能打卡\"}");
* cardD.setButton("000000000");
* cardV.setContent(cardD);
* //Java对象转换成JSON字符串
* message = JSONObject.toJSONString(cardV);
* return message;
* }
* EqOverStaff eqOverStaff = eqOverStaffMapper.selectEqOverStaffByUserId(Long.valueOf(userId));
* if(StringUtils.isNull(eqOverStaff)){
* cardV.setResult(1);
* cardV.setMsg("{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}");
* cardD.setButton("000000000");
* cardV.setContent(cardD);
* //Java对象转换成JSON字符串
* message = JSONObject.toJSONString(cardV);
* return message;
* }
* RzSpecialAttendance rzSpecialAttendance = rzSpecialAttendanceMapper.selectRzSpecialAttendanceByuserIdAndDate(Long.valueOf(userId),new Date());
* if(StringUtils.isNull(rzSpecialAttendance)){
* cardV.setResult(0);
* cardV.setMsg("验证通过");
* cardD.setButton("111100000");
* cardV.setContent(cardD);
* //Java对象转换成JSON字符串
* message = JSONObject.toJSONString(cardV);
* }else{
* cardV.setResult(0);
* cardV.setMsg("验证通过");
* cardD.setButton("000011000");
* cardV.setContent(cardD);
* //Java对象转换成JSON字符串
* message = JSONObject.toJSONString(cardV);
* }
* return message;
* }
* //根据ID查询在职员工信息
* SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));
* //员工不存在说明离职没有打卡权限
* if(StringUtils.isNull(sysStaff)){
* cardV.setResult(1);
* cardV.setMsg("{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}");
* cardD.setButton("000000000");
* cardV.setContent(cardD);
* //Java对象转换成JSON字符串
* message = JSONObject.toJSONString(cardV);
* return message;
* }
* //根据id查询当前员工不是员工列表中的人返回提示
* EqImages userImg = eqImagesMapper.selectEqImagesByStaffId(Long.valueOf(userId));
* if(StringUtils.isNull(userImg)){
* cardV.setResult(1);
* cardV.setMsg("{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}");
* cardD.setButton("000000000");
* cardV.setContent(cardD);
* //Java对象转换成JSON字符串
* message = JSONObject.toJSONString(cardV);
* return message;
* }
* //查询员工的最后一次打卡 按钮切换
* RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectLastRzAttendanceDetail(Long.valueOf(userId));
* //判断最后一次打卡为下班卡或没有打卡记录则打卡为上班卡
* if(StringUtils.isNull(rzAttendanceDetail) || "下班卡".equals(rzAttendanceDetail.getButtonType()) || "撤销".equals(rzAttendanceDetail.getButtonType())){
* //如果最后一条数据的卡类型为下班卡则返回上班卡和加班卡权限
* cardV.setResult(0);
* cardV.setMsg("验证通过");
* cardD.setButton("111100000");
* cardV.setContent(cardD);
* //Java对象转换成JSON字符串
* message = JSONObject.toJSONString(cardV);
* }else{
* cardV.setResult(0);
* cardV.setMsg("验证通过");
* cardD.setButton("000011000");
* cardV.setContent(cardD);
* //Java对象转换成JSON字符串
* message = JSONObject.toJSONString(cardV);
* }
*/
}
private String initMessage(Integer result, String meg){
//需要返回的对象, 默认失败
return JSONObject.toJSONString(new RzAttendanceVo(result, meg, null));
}
private String initMessage(Integer result, String meg, String buttonPermission){
//需要返回的对象, 默认失败
if(StringUtils.isNotEmpty(buttonPermission)){
return JSONObject.toJSONString(new RzAttendanceVo(result, meg, new RzAttendanceData(buttonPermission)));
} }
//根据id查询当前员工不是员工列表中的人返回提示 return JSONObject.toJSONString(new RzAttendanceVo(result, meg));
EqImages userImg = eqImagesMapper.selectEqImagesByStaffId(Long.valueOf(userId));
if(StringUtils.isNull(userImg)){
cardV.setResult(1);
cardV.setMsg("{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}");
cardD.setButton("000000000");
cardV.setContent(cardD);
//Java对象转换成JSON字符串
message = JSONObject.toJSONString(cardV);
return message;
}
//查询员工的最后一次打卡 按钮切换
RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectLastRzAttendanceDetail(Long.valueOf(userId));
//判断最后一次打卡为下班卡或没有打卡记录则打卡为上班卡
if(StringUtils.isNull(rzAttendanceDetail) || "下班卡".equals(rzAttendanceDetail.getButtonType()) || "撤销".equals(rzAttendanceDetail.getButtonType())){
//如果最后一条数据的卡类型为下班卡则返回上班卡和加班卡权限
cardV.setResult(0);
cardV.setMsg("验证通过");
cardD.setButton("111100000");
cardV.setContent(cardD);
//Java对象转换成JSON字符串
message = JSONObject.toJSONString(cardV);
}else{
cardV.setResult(0);
cardV.setMsg("验证通过");
cardD.setButton("000011000");
cardV.setContent(cardD);
//Java对象转换成JSON字符串
message = JSONObject.toJSONString(cardV);
}
return message;
} }
/** /**
* 用户点击打卡按钮后请求的接口 * 用户点击打卡按钮后请求的接口
@ -205,359 +250,392 @@ public class PunchTheClockServiceImpl implements PunchTheClockService {
date = sdf.parse(jsonObject.getString("recog_time")); date = sdf.parse(jsonObject.getString("recog_time"));
}catch (Exception e){ }catch (Exception e){
e.printStackTrace(); e.printStackTrace();
return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; return initMessage(1,"打卡失败");
} }
String rules = ""; //打卡规则
String button = jsonObject.getString("button"); String button = jsonObject.getString("button");
switch (button){ List<EqButton> bt_list = eqButtonMapper.selectEqButtonList(null);
case "1": if(Collections.isEmpty(bt_list)){
rules = "上班卡(单班制)"; return initMessage(1,"打卡失败");
break;
case "2":
rules = "上班卡(双班制)";
break;
case "3":
rules = "上班卡(三班制)";
break;
case "4":
rules = "加班卡";
break;
case "5":
rules = "下班卡";
break;
default:
rules = "撤销";
break;
} }
//根据顺序获取打卡规则
EqButton eqButton = bt_list.get(Integer.parseInt(button)-1);
String rules = eqButton.getName(); //打卡规则
//判断是打特殊加班卡 Map<String, PunchTheClockStrategyExchangeProcessor> mqttRequestExchangeProcessorMap = applicationContext.getBeansOfType(PunchTheClockStrategyExchangeProcessor.class);
if(com.evo.equipment.constant.Constants.EQ_DEVICE_OVER_TIME_CODE.equals(sn)){ for (PunchTheClockStrategyExchangeProcessor processor : mqttRequestExchangeProcessorMap.values()) {
RzSpecialAttendance rzSpecialAttendance = null; if(processor.accept(sn)){
SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId)); return processor.exchangeFace(userId, sn, date, button, rules);
if("1".equals(button) || "2".equals(button) || "3".equals(button) || "6".equals(button)){
return "{\"Result\":1,\"Msg\":\"无效打卡\"}";
}
if("4".equals(button)){
rzSpecialAttendance = new RzSpecialAttendance();
rzSpecialAttendance.setAttendanceDate(new Date());
rzSpecialAttendance.setStaffId(Long.valueOf(userId));
rzSpecialAttendance.setName(sysStaff.getName());
rzSpecialAttendance.setWorkStartTime(date);
rzSpecialAttendance.setDeptId(sysStaff.getDeptId());
rzSpecialAttendance.setDelFlag("0");
rzSpecialAttendance.setCreateBy("admin");
rzSpecialAttendance.setCreateTime(new Date());
rzSpecialAttendanceMapper.insertRzSpecialAttendance(rzSpecialAttendance);
RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate());
if(StringUtils.isNull(rzSpecialOverTime)){
rzSpecialOverTime = new RzSpecialOverTime();
rzSpecialOverTime.setUserId(Long.valueOf(userId));
rzSpecialOverTime.setName(sysStaff.getName());
rzSpecialOverTime.setDeptId(sysStaff.getDeptId());
rzSpecialOverTime.setDelFlag("0");
rzSpecialOverTime.setOverDate(date);
rzSpecialOverTime.setCreateTime(new Date());
rzSpecialOverTime.setCreateBy("admin");
rzSpecialOverTimeMapper.insertRzSpecialOverTime(rzSpecialOverTime);
}
return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
}else {
rzSpecialAttendance = rzSpecialAttendanceMapper.selectRzSpecialAttendanceByuserIdAndDate(Long.valueOf(userId),new Date());
rzSpecialAttendance.setWorkEndTime(date);
SpecialOverTime specialOverTime = bsOverTimeMapper.selectSpecialOverTimeById();
try{
Date overDate_s = sdf.parse(sdfd.format(rzSpecialAttendance.getWorkStartTime())+" "+specialOverTime.getWorkStart());
Date overDate_e = sdf.parse(sdfd.format(date)+" "+specialOverTime.getWorkEnd());
Long minutes = 0l;
if(overDate_s.after(rzSpecialAttendance.getWorkStartTime()) && overDate_e.before(date)){
minutes = (overDate_e.getTime() - overDate_s.getTime())/1000/60;
}else {
if(overDate_s.before(rzSpecialAttendance.getWorkStartTime()) && overDate_e.after(date)){
minutes = (date.getTime() - rzSpecialAttendance.getWorkStartTime().getTime())/1000/60;
}else{
if(overDate_e.after(date)){
minutes = (date.getTime() - overDate_s.getTime())/1000/60;
}else {
minutes = (overDate_e.getTime() - rzSpecialAttendance.getWorkStartTime().getTime())/1000/60;
}
}
}
if(minutes >= 180){
rzSpecialAttendance.setWorkHours(new BigDecimal(3));
}else if(minutes >= 120){
rzSpecialAttendance.setWorkHours(new BigDecimal(2));
}
rzSpecialAttendanceMapper.updateRzSpecialAttendance(rzSpecialAttendance);
RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate());
rzSpecialOverTime.setSickHours(rzSpecialOverTime.getSickHours().add(rzSpecialAttendance.getWorkHours()));
rzSpecialOverTimeMapper.updateRzSpecialOverTime(rzSpecialOverTime);
RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate());
if(StringUtils.isNull(rzAttendanceStatistical.getOverTimeHours())){
rzAttendanceStatistical.setOverTimeHours(new BigDecimal(0.0));
}
rzAttendanceStatistical.setOverTimeHours(rzAttendanceStatistical.getOverTimeHours().add(rzSpecialAttendance.getWorkHours()));
rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical);
return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
}catch (Exception e){
e.printStackTrace();
return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
}
} }
} }
return initMessage(1,"打卡失败");
//根据ID查询员工信息 ,判断员工是否存在不存在返回失败 /***
SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));//打卡记录信息 * PS: 注解为原代码逻辑
if(sysStaff == null){ * //解析收到的数据
return "{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}"; * JSONObject jsonObject = JSONObject.parseObject(json);
} * String userId = jsonObject.getString("user_id");
//获取员工的工作时长 * String sn = jsonObject.getString("sn");
EqImages eqImages = eqImagesMapper.selectEqImagesByStaffId(Long.valueOf(userId)); * SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//打卡明细 * SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd");
RzAttendanceDetail attendanceDetail = new RzAttendanceDetail(); * Date date = null; //打卡时间
//打卡明细表中插入数据 * try{
attendanceDetail.setButtonType(rules); * date = sdf.parse(jsonObject.getString("recog_time"));
attendanceDetail.setName(sysStaff.getName()); * }catch (Exception e){
attendanceDetail.setDateTime(date); * e.printStackTrace();
attendanceDetail.setDelFlag(Constants.DELETE_FLAG_0); * return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
attendanceDetail.setStaffId(Long.valueOf(userId)); * }
attendanceDetail.setEquipmentCode(sn); * String rules = ""; //打卡规则
attendanceDetail.setCreateTime(new Date()); * String button = jsonObject.getString("button");
int i = rzAttendanceDetailMapper.insertRzAttendanceDetail(attendanceDetail); * switch (button){
if(i < 1){ * case "1":
return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; * rules = "上班卡(单班制)";
} * break;
//考勤加班统计 * case "2":
RzOverTime rzOverTime = null; * rules = "上班卡(双班制)";
RzOverTimeDetail rzOverTimeDetail = null; * break;
* case "3":
//打的是加班卡加班列表中填写数据 * rules = "上班卡(三班制)";
if("4".equals(button)){ * break;
//判断打卡月是否统计过加班 * case "4":
rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.valueOf(userId),date); * rules = "加班卡";
if(rzOverTime == null){ * break;
rzOverTime = new RzOverTime(); * case "5":
rzOverTime.setUserId(Long.valueOf(userId)); * rules = "下班卡";
rzOverTime.setOverHours(new BigDecimal("0.0")); * break;
rzOverTime.setDeptId(sysStaff.getDeptId()); * default:
rzOverTime.setName(sysStaff.getName()); * rules = "撤销";
rzOverTime.setOverTimeMonth(date); * break;
rzOverTime.setDelFlag(Constants.DELETE_FLAG_0); * }
rzOverTime.setCreateBy("admin"); *
rzOverTime.setCreateTime(DateUtils.getNowDate()); * //判断是打特殊加班卡
i = rzOverTimeMapper.insertRzOverTime(rzOverTime); * if(com.evo.equipment.constant.Constants.EQ_DEVICE_OVER_TIME_CODE.equals(sn)){
if(i < 1){ * RzSpecialAttendance rzSpecialAttendance = null;
return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; * SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));
} * if("1".equals(button) || "2".equals(button) || "3".equals(button) || "6".equals(button)){
} * return "{\"Result\":1,\"Msg\":\"无效打卡\"}";
rzOverTimeDetail = new RzOverTimeDetail(); * }
rzOverTimeDetail.setOverTimeId(rzOverTime.getId()); * if("4".equals(button)){
rzOverTimeDetail.setOverTimeStart(date); * rzSpecialAttendance = new RzSpecialAttendance();
rzOverTimeDetail.setName(sysStaff.getName()); * rzSpecialAttendance.setAttendanceDate(new Date());
rzOverTimeDetail.setDelFlag(Constants.DELETE_FLAG_0); * rzSpecialAttendance.setStaffId(Long.valueOf(userId));
rzOverTimeDetail.setCreateBy("admin"); * rzSpecialAttendance.setName(sysStaff.getName());
rzOverTimeDetail.setCreateTime(DateUtils.getNowDate()); * rzSpecialAttendance.setWorkStartTime(date);
i = rzOverTimeDetailMapper.insertRzOverTimeDetail(rzOverTimeDetail); * rzSpecialAttendance.setDeptId(sysStaff.getDeptId());
if(i < 1){ * rzSpecialAttendance.setDelFlag("0");
return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; * rzSpecialAttendance.setCreateBy("admin");
} * rzSpecialAttendance.setCreateTime(new Date());
return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; * rzSpecialAttendanceMapper.insertRzSpecialAttendance(rzSpecialAttendance);
} *
* RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate());
//员工考勤记录 * if(StringUtils.isNull(rzSpecialOverTime)){
RzAttendance attendance = rzAttendanceMapper.queryNowDayAttendanceByStatisticalIdAndDate(Long.valueOf(userId),date); * rzSpecialOverTime = new RzSpecialOverTime();
//判断是撤销卡 * rzSpecialOverTime.setUserId(Long.valueOf(userId));
if("6".equals(button)){ * rzSpecialOverTime.setName(sysStaff.getName());
attendance.setRules(""); * rzSpecialOverTime.setDeptId(sysStaff.getDeptId());
i = rzAttendanceMapper.updateRzAttendance(attendance); * rzSpecialOverTime.setDelFlag("0");
if(i < 1){ * rzSpecialOverTime.setOverDate(date);
return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; * rzSpecialOverTime.setCreateTime(new Date());
} * rzSpecialOverTime.setCreateBy("admin");
return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; * rzSpecialOverTimeMapper.insertRzSpecialOverTime(rzSpecialOverTime);
} * }
* return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
//判断是上班卡 * }else {
if("1".equals(button) || "2".equals(button) || "3".equals(button)){ * rzSpecialAttendance = rzSpecialAttendanceMapper.selectRzSpecialAttendanceByuserIdAndDate(Long.valueOf(userId),new Date());
if(StringUtils.isNotNull(attendance.getWorkStartTime())){ * rzSpecialAttendance.setWorkEndTime(date);
attendance.setRules(rules); * SpecialOverTime specialOverTime = bsOverTimeMapper.selectSpecialOverTimeById();
}else{ * try{
attendance.setRules(rules); * Date overDate_s = sdf.parse(sdfd.format(rzSpecialAttendance.getWorkStartTime())+" "+specialOverTime.getWorkStart());
attendance.setWorkStartTime(date); * Date overDate_e = sdf.parse(sdfd.format(date)+" "+specialOverTime.getWorkEnd());
} *
try{ * Long minutes = 0l;
//判断三种上班卡 * if(overDate_s.after(rzSpecialAttendance.getWorkStartTime()) && overDate_e.before(date)){
Date db_pre = sdf.parse(sdfd.format(date) + " 08:30:00"); * minutes = (overDate_e.getTime() - overDate_s.getTime())/1000/60;
Date sb_pre = sdf.parse(sdfd.format(date) + " 17:00:00"); * }else {
Date sbz_pre = sdf.parse(sdfd.format(date) + " 20:30:00"); * if(overDate_s.before(rzSpecialAttendance.getWorkStartTime()) && overDate_e.after(date)){
if("上班卡(单班制)".equals(rules) && date.after(db_pre) * minutes = (date.getTime() - rzSpecialAttendance.getWorkStartTime().getTime())/1000/60;
|| ("上班卡(双班制)".equals(rules) && ((date.after(db_pre) && date.getHours() < 12) || (date.after(sb_pre) && date.getHours() <21))) * }else{
|| ("上班卡(三班制)".equals(rules) && ((date.after(db_pre) && date.getHours() < 12) || (date.after(sbz_pre) && date.getHours() < 24)))){ * if(overDate_e.after(date)){
attendance.setYcsFlag("1"); * minutes = (date.getTime() - overDate_s.getTime())/1000/60;
} * }else {
}catch (Exception e){ * minutes = (overDate_e.getTime() - rzSpecialAttendance.getWorkStartTime().getTime())/1000/60;
e.printStackTrace(); * }
} * }
i = rzAttendanceMapper.updateRzAttendance(attendance); * }
if(i < 1){ * if(minutes >= 180){
return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; * rzSpecialAttendance.setWorkHours(new BigDecimal(3));
} * }else if(minutes >= 120){
return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; * rzSpecialAttendance.setWorkHours(new BigDecimal(2));
} * }
* rzSpecialAttendanceMapper.updateRzSpecialAttendance(rzSpecialAttendance);
// 查询员工的最后一次上班打卡信息 *
RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectRzAttendanceDetailByStaffId(Long.valueOf(userId)); * RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate());
* rzSpecialOverTime.setSickHours(rzSpecialOverTime.getSickHours().add(rzSpecialAttendance.getWorkHours()));
//下班卡 * rzSpecialOverTimeMapper.updateRzSpecialOverTime(rzSpecialOverTime);
//最后一次打卡为加班卡 跨月加班按上个月加班计算 *
if("加班卡".equals(rzAttendanceDetail.getButtonType())){ * RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate());
//修改加班打卡记录 根据员工ID和时间查找 统计数据 * if(StringUtils.isNull(rzAttendanceStatistical.getOverTimeHours())){
rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.valueOf(userId),rzAttendanceDetail.getDateTime()); * rzAttendanceStatistical.setOverTimeHours(new BigDecimal(0.0));
//查找加班详情 加班统计ID和加班开始时间 * }
rzOverTimeDetail = rzOverTimeDetailMapper.queryRzOverTimeDetailByDateAndOverId(rzOverTime.getId(),rzAttendanceDetail.getDateTime()); * rzAttendanceStatistical.setOverTimeHours(rzAttendanceStatistical.getOverTimeHours().add(rzSpecialAttendance.getWorkHours()));
rzOverTimeDetail.setOverTimeEnd(date); * rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical);
//计算加班时长 小时 * return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
double hours = (rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60/60; * }catch (Exception e){
if(hours > 4){ * e.printStackTrace();
rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(4)); * return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
}else{ * }
rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(hours)); * }
} * }
*
i = rzOverTimeDetailMapper.updateRzOverTimeDetail(rzOverTimeDetail); * //根据ID查询员工信息 ,判断员工是否存在不存在返回失败
if(i < 1){ * SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));//打卡记录信息
return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; * if(sysStaff == null){
} * return "{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}";
//加班修改统计 * }
rzOverTime.setOverHours(rzOverTime.getOverHours().add(rzOverTimeDetail.getOverTimeHours())); * //获取员工的工作时长
i = rzOverTimeMapper.updateRzOverTime(rzOverTime); * EqImages eqImages = eqImagesMapper.selectEqImagesByStaffId(Long.valueOf(userId));
if(i < 1){ * //打卡明细
return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; * RzAttendanceDetail attendanceDetail = new RzAttendanceDetail();
} * //打卡明细表中插入数据
//反写考勤汇总 * attendanceDetail.setButtonType(rules);
RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(Long.valueOf(userId),rzOverTime.getOverTimeMonth()); * attendanceDetail.setName(sysStaff.getName());
rzAttendanceStatistical.setWorkOvertimeNumber(rzOverTime.getOverHours()); * attendanceDetail.setDateTime(date);
i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); * attendanceDetail.setDelFlag(Constants.DELETE_FLAG_0);
if(i < 1){ * attendanceDetail.setStaffId(Long.valueOf(userId));
return"{\"Result\":1,\"Msg\":\"打卡失败\"}"; * attendanceDetail.setEquipmentCode(sn);
} * attendanceDetail.setCreateTime(new Date());
return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; * int i = rzAttendanceDetailMapper.insertRzAttendanceDetail(attendanceDetail);
} * if(i < 1){
* return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
BigDecimal res = new BigDecimal("0.0"); //记录工时 * }
//计算工时 * //考勤加班统计
Long hours = (date.getTime() - rzAttendanceDetail.getDateTime().getTime())/1000/60/60; * RzOverTime rzOverTime = null;
//判断不是当天的下班卡 * RzOverTimeDetail rzOverTimeDetail = null;
if(StringUtils.isNull(attendance.getWorkStartTime())){ *
//最后一次上班卡打卡时间 * //打的是加班卡加班列表中填写数据
attendance = rzAttendanceMapper.selectLastRzAttendanceByStaffId(Long.valueOf(userId)); * if("4".equals(button)){
//判断是单班双班还是三班 * //判断打卡月是否统计过加班
if("上班卡(三班制)".equals(attendance.getRules())){ * rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.valueOf(userId),date);
if(hours >= eqImages.getHours().longValue() -1){ * if(rzOverTime == null){
res = eqImages.getHours(); * rzOverTime = new RzOverTime();
}else if(hours >= 5){ * rzOverTime.setUserId(Long.valueOf(userId));
res = new BigDecimal(6); * rzOverTime.setOverHours(new BigDecimal("0.0"));
} * rzOverTime.setDeptId(sysStaff.getDeptId());
//判断打卡时间, 添加夜班次数 打卡时间在晚上7点以后 * rzOverTime.setName(sysStaff.getName());
if(hours > 8 && attendance.getWorkStartTime().getHours() > 18){ * rzOverTime.setOverTimeMonth(date);
attendance.setNightNumber(1); * rzOverTime.setDelFlag(Constants.DELETE_FLAG_0);
} * rzOverTime.setCreateBy("admin");
}else if("上班卡(双班制)".equals(attendance.getRules())){ * rzOverTime.setCreateTime(DateUtils.getNowDate());
if(hours >= 7.5){ * i = rzOverTimeMapper.insertRzOverTime(rzOverTime);
res = new BigDecimal("8"); * if(i < 1){
}else if(hours >= 3.5){ * return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
res = new BigDecimal(4); * }
} * }
//判断打卡时间, 添加中班次数 打卡时间在下午3点以后 * rzOverTimeDetail = new RzOverTimeDetail();
if(hours > 6.5 && attendance.getWorkStartTime().getHours() > 15){ * rzOverTimeDetail.setOverTimeId(rzOverTime.getId());
attendance.setMiddleShiftNumber(1); * rzOverTimeDetail.setOverTimeStart(date);
} * rzOverTimeDetail.setName(sysStaff.getName());
}else{ * rzOverTimeDetail.setDelFlag(Constants.DELETE_FLAG_0);
if(hours >= 8){ * rzOverTimeDetail.setCreateBy("admin");
res = new BigDecimal("8"); * rzOverTimeDetail.setCreateTime(DateUtils.getNowDate());
}else if(hours >= 3){ * i = rzOverTimeDetailMapper.insertRzOverTimeDetail(rzOverTimeDetail);
res = new BigDecimal(4); * if(i < 1){
} * return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
} * }
}else{ * return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
try{ * }
if("上班卡(单班制)".equals(rzAttendanceDetail.getButtonType())){ *
if(attendance.getWorkStartTime().getTime() - sdf.parse(sdfd.format(date) + " 08:30:00").getTime() > 1000*60*+60 * //员工考勤记录
|| sdf.parse(sdfd.format(date) + " 17:30:00").getTime() - date.getTime() > 1000*60*+60){ * RzAttendance attendance = rzAttendanceMapper.queryNowDayAttendanceByStatisticalIdAndDate(Long.valueOf(userId),date);
if(hours >= 3){ * //判断是撤销卡
res = new BigDecimal("4"); * if("6".equals(button)){
} * attendance.setRules("");
}else{ * i = rzAttendanceMapper.updateRzAttendance(attendance);
if(hours >= 8){ * if(i < 1){
res = new BigDecimal("8.0"); * return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
}else if(hours >= 4){ * }
res = new BigDecimal(4); * return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
} * }
} *
}else if("上班卡(双班制)".equals(rzAttendanceDetail.getButtonType())){ * //判断是上班卡
if(attendance.getWorkStartTime().getTime() - sdf.parse(sdfd.format(date) + " 08:30:00").getTime() > 1000*60*+60 * if("1".equals(button) || "2".equals(button) || "3".equals(button)){
|| sdf.parse(sdfd.format(date) + " 17:30:00").getTime() - date.getTime() > 1000*60*+60){ * if(StringUtils.isNotNull(attendance.getWorkStartTime())){
if(hours >= 4){ * attendance.setRules(rules);
res = new BigDecimal("4"); * }else{
} * attendance.setRules(rules);
}else{ * attendance.setWorkStartTime(date);
if(hours >= 8){ * }
res = new BigDecimal("8.0"); * try{
}else if(hours >= 4){ * //判断三种上班卡
res = new BigDecimal(4); * Date db_pre = sdf.parse(sdfd.format(date) + " 08:30:00");
} * Date sb_pre = sdf.parse(sdfd.format(date) + " 17:00:00");
} * Date sbz_pre = sdf.parse(sdfd.format(date) + " 20:30:00");
}else if("上班卡(三班制)".equals(rzAttendanceDetail.getButtonType())){ * if("上班卡(单班制)".equals(rules) && date.after(db_pre)
if(attendance.getWorkStartTime().getTime() - sdf.parse(sdfd.format(date) + " 08:30:00").getTime() > 1000*60*+60 * || ("上班卡(双班制)".equals(rules) && ((date.after(db_pre) && date.getHours() < 12) || (date.after(sb_pre) && date.getHours() <21)))
|| sdf.parse(sdfd.format(date) + " 20:30:00").getTime() - date.getTime() > 1000*60*+60){ * || ("上班卡(三班制)".equals(rules) && ((date.after(db_pre) && date.getHours() < 12) || (date.after(sbz_pre) && date.getHours() < 24)))){
if(hours >= 5){ * attendance.setYcsFlag("1");
res = new BigDecimal("6"); * }
} * }catch (Exception e){
}else{ * e.printStackTrace();
if(hours >= eqImages.getHours().longValue()-1){ * }
res = eqImages.getHours(); * i = rzAttendanceMapper.updateRzAttendance(attendance);
}else if(hours >= 5){ * if(i < 1){
res = new BigDecimal(6); * return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
} * }
} * return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
} * }
}catch (Exception e){ *
* // 查询员工的最后一次上班打卡信息
} * RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectRzAttendanceDetailByStaffId(Long.valueOf(userId));
} *
try{ * //下班卡
//下班卡异常 * //最后一次打卡为加班卡 跨月加班按上个月加班计算
Date db_pre = sdf.parse(sdfd.format(date) + " 08:30:00"); * if("加班卡".equals(rzAttendanceDetail.getButtonType())){
Date sb_pre = sdf.parse(sdfd.format(date) + " 17:00:00"); * //修改加班打卡记录 根据员工ID和时间查找 统计数据
Date db_pre_2 = sdf.parse(sdfd.format(date) + " 17:30:00"); * rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.valueOf(userId),rzAttendanceDetail.getDateTime());
Date sbz_pre = sdf.parse(sdfd.format(date) + " 20:30:00"); * //查找加班详情 加班统计ID和加班开始时间
Date sbz_pre_2 = sdf.parse(sdfd.format(date) + " 01:30:00"); * rzOverTimeDetail = rzOverTimeDetailMapper.queryRzOverTimeDetailByDateAndOverId(rzOverTime.getId(),rzAttendanceDetail.getDateTime());
if(("上班卡(单班制)".equals(rzAttendanceDetail.getButtonType()) && date.before(db_pre_2)) * rzOverTimeDetail.setOverTimeEnd(date);
|| ("上班卡(双班制)".equals(rzAttendanceDetail.getButtonType()) * //计算加班时长 小时
&& ((date.before(sb_pre) && date.after(db_pre)) || ((date.before(sbz_pre_2)) && date.after(sb_pre)))) * double hours = (rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60/60;
|| ("上班卡(三班制)".equals(rzAttendanceDetail.getButtonType()) && ((date.before(sbz_pre) && date.getHours() > 14) || date.before(db_pre)))){ * if(hours > 4){
attendance.setYcxFlag("1"); * rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(4));
} * }else{
}catch (Exception e){ * rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(hours));
e.printStackTrace(); * }
} *
//修改打卡记录 * i = rzOverTimeDetailMapper.updateRzOverTimeDetail(rzOverTimeDetail);
attendance.setWorkEndTime(date); * if(i < 1){
attendance.setWorkSum(res); * return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
i = rzAttendanceMapper.updateRzAttendance(attendance); * }
if(i < 1){ * //加班修改统计
return "{\"Result\":1,\"Msg\":\"打卡失败\"}"; * rzOverTime.setOverHours(rzOverTime.getOverHours().add(rzOverTimeDetail.getOverTimeHours()));
} * i = rzOverTimeMapper.updateRzOverTime(rzOverTime);
//反写考勤汇总 * if(i < 1){
RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(Long.valueOf(userId),attendance.getAttendanceDate()); * return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
rzAttendanceStatistical.setRealAttendance(rzAttendanceStatistical.getRealAttendance().add(attendance.getWorkSum())); * }
i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); * //反写考勤汇总
if(i < 1){ * RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(Long.valueOf(userId),rzOverTime.getOverTimeMonth());
return"{\"Result\":1,\"Msg\":\"打卡失败\"}"; * rzAttendanceStatistical.setWorkOvertimeNumber(rzOverTime.getOverHours());
} * i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical);
return "{\"Result\":0,\"Msg\":\"打卡成功\"}"; * if(i < 1){
* return"{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
* }
*
* BigDecimal res = new BigDecimal("0.0"); //记录工时
* //计算工时
* Long hours = (date.getTime() - rzAttendanceDetail.getDateTime().getTime())/1000/60/60;
* //判断不是当天的下班卡
* if(StringUtils.isNull(attendance.getWorkStartTime())){
* //最后一次上班卡打卡时间
* attendance = rzAttendanceMapper.selectLastRzAttendanceByStaffId(Long.valueOf(userId));
* //判断是单班双班还是三班
* if("上班卡(三班制)".equals(attendance.getRules())){
* if(hours >= eqImages.getHours().longValue() -1){
* res = eqImages.getHours();
* }else if(hours >= 5){
* res = new BigDecimal(6);
* }
* //判断打卡时间, 添加夜班次数 打卡时间在晚上7点以后
* if(hours > 8 && attendance.getWorkStartTime().getHours() > 18){
* attendance.setNightNumber(1);
* }
* }else if("上班卡(双班制)".equals(attendance.getRules())){
* if(hours >= 7.5){
* res = new BigDecimal("8");
* }else if(hours >= 3.5){
* res = new BigDecimal(4);
* }
* //判断打卡时间, 添加中班次数 打卡时间在下午3点以后
* if(hours > 6.5 && attendance.getWorkStartTime().getHours() > 15){
* attendance.setMiddleShiftNumber(1);
* }
* }else{
* if(hours >= 8){
* res = new BigDecimal("8");
* }else if(hours >= 3){
* res = new BigDecimal(4);
* }
* }
* }else{
* try{
* if("上班卡(单班制)".equals(rzAttendanceDetail.getButtonType())){
* if(attendance.getWorkStartTime().getTime() - sdf.parse(sdfd.format(date) + " 08:30:00").getTime() > 1000*60*+60
* || sdf.parse(sdfd.format(date) + " 17:30:00").getTime() - date.getTime() > 1000*60*+60){
* if(hours >= 3){
* res = new BigDecimal("4");
* }
* }else{
* if(hours >= 8){
* res = new BigDecimal("8.0");
* }else if(hours >= 4){
* res = new BigDecimal(4);
* }
* }
* }else if("上班卡(双班制)".equals(rzAttendanceDetail.getButtonType())){
* if(attendance.getWorkStartTime().getTime() - sdf.parse(sdfd.format(date) + " 08:30:00").getTime() > 1000*60*+60
* || sdf.parse(sdfd.format(date) + " 17:30:00").getTime() - date.getTime() > 1000*60*+60){
* if(hours >= 4){
* res = new BigDecimal("4");
* }
* }else{
* if(hours >= 8){
* res = new BigDecimal("8.0");
* }else if(hours >= 4){
* res = new BigDecimal(4);
* }
* }
* }else if("上班卡(三班制)".equals(rzAttendanceDetail.getButtonType())){
* if(attendance.getWorkStartTime().getTime() - sdf.parse(sdfd.format(date) + " 08:30:00").getTime() > 1000*60*+60
* || sdf.parse(sdfd.format(date) + " 20:30:00").getTime() - date.getTime() > 1000*60*+60){
* if(hours >= 5){
* res = new BigDecimal("6");
* }
* }else{
* if(hours >= eqImages.getHours().longValue()-1){
* res = eqImages.getHours();
* }else if(hours >= 5){
* res = new BigDecimal(6);
* }
* }
* }
* }catch (Exception e){
*
* }
* }
* try{
* //下班卡异常
* Date db_pre = sdf.parse(sdfd.format(date) + " 08:30:00");
* Date sb_pre = sdf.parse(sdfd.format(date) + " 17:00:00");
* Date db_pre_2 = sdf.parse(sdfd.format(date) + " 17:30:00");
* Date sbz_pre = sdf.parse(sdfd.format(date) + " 20:30:00");
* Date sbz_pre_2 = sdf.parse(sdfd.format(date) + " 01:30:00");
* if(("上班卡(单班制)".equals(rzAttendanceDetail.getButtonType()) && date.before(db_pre_2))
* || ("上班卡(双班制)".equals(rzAttendanceDetail.getButtonType())
* && ((date.before(sb_pre) && date.after(db_pre)) || ((date.before(sbz_pre_2)) && date.after(sb_pre))))
* || ("上班卡(三班制)".equals(rzAttendanceDetail.getButtonType()) && ((date.before(sbz_pre) && date.getHours() > 14) || date.before(db_pre)))){
* attendance.setYcxFlag("1");
* }
* }catch (Exception e){
* e.printStackTrace();
* }
* //修改打卡记录
* attendance.setWorkEndTime(date);
* attendance.setWorkSum(res);
* i = rzAttendanceMapper.updateRzAttendance(attendance);
* if(i < 1){
* return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* //反写考勤汇总
* RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(Long.valueOf(userId),attendance.getAttendanceDate());
* rzAttendanceStatistical.setRealAttendance(rzAttendanceStatistical.getRealAttendance().add(attendance.getWorkSum()));
* i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical);
* if(i < 1){
* return"{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
*/
} }
} }

View File

@ -13,7 +13,10 @@ import com.evo.common.utils.DateUtils;
import com.evo.common.utils.ParamUtils; import com.evo.common.utils.ParamUtils;
import com.evo.common.utils.SecurityUtils; import com.evo.common.utils.SecurityUtils;
import com.evo.common.utils.StringUtils; import com.evo.common.utils.StringUtils;
import com.evo.personnelMatters.domain.RzLeaveDetail;
import com.evo.personnelMatters.mapper.RzLeaveDetailMapper;
import com.evo.utils.DateUtil; import com.evo.utils.DateUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -44,7 +47,9 @@ public class RzAbnormalDetailServiceImpl implements IRzAbnormalDetailService
@Resource @Resource
private RzAbnormalMapper rzAbnormalMapper; //异常汇总 private RzAbnormalMapper rzAbnormalMapper; //异常汇总
@Resource @Resource
private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //考勤统计 private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //考勤统计
@Resource
private RzLeaveDetailMapper rzLeaveDetailMapper;
/** /**
* 查询考勤异常详情 * 查询考勤异常详情
* *
@ -68,30 +73,6 @@ public class RzAbnormalDetailServiceImpl implements IRzAbnormalDetailService
{ {
return rzAbnormalDetailMapper.selectRzAbnormalDetailList(rzAbnormalDetail); return rzAbnormalDetailMapper.selectRzAbnormalDetailList(rzAbnormalDetail);
} }
public static void main(String[] args) {
int year = 2025;
YearMonth yearMonth = YearMonth.of(year,1);
LocalDate date = yearMonth.atDay(1);
while (date.getYear() == year){
if(date.getDayOfWeek() == DayOfWeek.SUNDAY){
System.out.println(date);
}
date = date.plusDays(1);
}
// Year yearObject = Year.of(year); // 获取年份对象
// IntStream.rangeClosed(1, 12) // 遍历1到12月
// .forEach(month -> {
// YearMonth yearMonth = YearMonth.of(year, month);
// LocalDate firstDayOfMonth = yearMonth.atDay(1); // 获取当月的第1天
// LocalDate firstSunday = firstDayOfMonth // 从第1天开始找第一个周日
// .with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
// System.out.println("Month: " + yearMonth + ", First Sunday: " + firstSunday);
// });
}
/** /**
* 新增考勤异常详情 * 新增考勤异常详情
* @return 结果 * @return 结果
@ -101,16 +82,27 @@ public class RzAbnormalDetailServiceImpl implements IRzAbnormalDetailService
//获取所有人的考勤信息 //获取所有人的考勤信息
List<RzAttendance> res_list = rzAttendanceMapper.currentDateAllAttendance(); List<RzAttendance> res_list = rzAttendanceMapper.currentDateAllAttendance();
try{ try{
Date checkDate = res_list.get(0).getAttendanceDate();
//检查是否为假期 //检查是否为假期
Boolean isHoliday = ParamUtils.checkHoliday(res_list.get(0).getAttendanceDate()); Boolean isHoliday = ParamUtils.checkHoliday(checkDate);
for (RzAttendance rzAttendance : res_list) { for (RzAttendance rzAttendance : res_list) {
//判断是否为假期 //判断是否为假期
if(isHoliday){ if(isHoliday){
//如果是假期, 有打卡, 标识为加班, 没有打卡标识为公休
//判断未打卡, 做加班还是公休备注 //判断未打卡, 做加班还是公休备注
rzAttendance.setRemarks((rzAttendance.getWorkStartTime() == null ? "公休": "加班")); rzAttendance.setRemarks((rzAttendance.getWorkStartTime() == null ? "公休": "加班"));
rzAttendanceMapper.updateRzAttendance(rzAttendance); rzAttendanceMapper.updateRzAttendance(rzAttendance);
continue; continue;
} }
//检查是否请假
RzLeaveDetail rzLeaveDetail = rzLeaveDetailMapper.selectRzLeaveDetailByUserIdAndDate(rzAttendance.getStaffId(), checkDate);
if(ObjectUtils.isNotEmpty(rzLeaveDetail)){
//如果不为空, 则证明存在请假情况 记录请假类型,
rzAttendance.setHolidayType(rzLeaveDetail.getType());
rzAttendance.setRemarks("请假");
rzAttendanceMapper.updateRzAttendance(rzAttendance);
continue;
}
//判断有没有异常打卡 //判断有没有异常打卡
if(anomalyCheckIn(rzAttendance)){ if(anomalyCheckIn(rzAttendance)){
//判断员工当月是否存在异常情况 //判断员工当月是否存在异常情况

View File

@ -3,6 +3,7 @@ package com.evo.attendance.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.domain.RzAttendanceDetail; import com.evo.attendance.domain.RzAttendanceDetail;
import com.evo.attendance.domain.vo.RzAttendanceDetailVO; import com.evo.attendance.domain.vo.RzAttendanceDetailVO;
import com.evo.attendance.mapper.RzAttendanceDetailMapper; import com.evo.attendance.mapper.RzAttendanceDetailMapper;
@ -43,9 +44,7 @@ import static com.evo.framework.datasource.DynamicDataSourceContextHolder.log;
* @date 2024-09-05 * @date 2024-09-05
*/ */
@Service @Service
public class RzAttendanceServiceImpl implements IRzAttendanceService { public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzAttendance> implements IRzAttendanceService {
@Resource
private RzAttendanceMapper rzAttendanceMapper;
@Resource @Resource
private SysDeptMapper deptMapper; //部门 private SysDeptMapper deptMapper; //部门
@Resource @Resource
@ -70,7 +69,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
*/ */
@Override @Override
public RzAttendance selectRzAttendanceById(Long id) { public RzAttendance selectRzAttendanceById(Long id) {
return rzAttendanceMapper.selectRzAttendanceById(id); return getBaseMapper().selectRzAttendanceById(id);
} }
/** /**
@ -82,7 +81,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
@DataScope(deptAlias = "d") @DataScope(deptAlias = "d")
@Override @Override
public List<RzAttendance> selectRzAttendanceList(RzAttendance rzAttendance) { public List<RzAttendance> selectRzAttendanceList(RzAttendance rzAttendance) {
List<RzAttendance> res_list = rzAttendanceMapper.selectRzAttendanceList(rzAttendance); List<RzAttendance> res_list = getBaseMapper().selectRzAttendanceList(rzAttendance);
for (RzAttendance attendance : res_list) { for (RzAttendance attendance : res_list) {
SysDept sysDept = deptMapper.selectDeptById(attendance.getDeptId()); SysDept sysDept = deptMapper.selectDeptById(attendance.getDeptId());
attendance.setDeptName(sysDept.getDeptName()); attendance.setDeptName(sysDept.getDeptName());
@ -114,7 +113,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
rzAttendance.setYcxFlag("0"); rzAttendance.setYcxFlag("0");
rzAttendance.setUpdateBy(SecurityUtils.getUsername()); rzAttendance.setUpdateBy(SecurityUtils.getUsername());
rzAttendance.setUpdateTime(DateUtils.getNowDate()); rzAttendance.setUpdateTime(DateUtils.getNowDate());
return rzAttendanceMapper.updateRzAttendance(rzAttendance); return getBaseMapper().updateRzAttendance(rzAttendance);
} }
/** /**
@ -124,7 +123,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
*/ */
@Override @Override
public int attendenceCount() { public int attendenceCount() {
List<RzAttendance> list = rzAttendanceMapper.attendenceCount(); List<RzAttendance> list = getBaseMapper().attendenceCount();
return list.size(); return list.size();
} }
@ -140,7 +139,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
return AjaxResult.error("请选择批量修改的时间!!"); return AjaxResult.error("请选择批量修改的时间!!");
} }
//根据时间查询打卡信息 //根据时间查询打卡信息
List<RzAttendance> list = rzAttendanceMapper.selectRzAttendanceList(rzAttendance); List<RzAttendance> list = getBaseMapper().selectRzAttendanceList(rzAttendance);
//获取当天12点的时间和830的时间 //获取当天12点的时间和830的时间
SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat sdft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@ -162,7 +161,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
if (attendance.getWorkEndTime() == null) { if (attendance.getWorkEndTime() == null) {
attendance.setWorkStartTime(pre_date); attendance.setWorkStartTime(pre_date);
attendance.setYcsFlag("0"); attendance.setYcsFlag("0");
rzAttendanceMapper.updateRzAttendance(attendance); getBaseMapper().updateRzAttendance(attendance);
continue; continue;
} }
BigDecimal old = attendance.getWorkSum(); BigDecimal old = attendance.getWorkSum();
@ -197,7 +196,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
attendance.setWorkStartTime(pre_date); attendance.setWorkStartTime(pre_date);
attendance.setYcsFlag("0"); attendance.setYcsFlag("0");
attendance.setWorkSum(res); attendance.setWorkSum(res);
int i = rzAttendanceMapper.updateRzAttendance(attendance); int i = getBaseMapper().updateRzAttendance(attendance);
if (i < 1) { if (i < 1) {
continue; continue;
} }
@ -214,7 +213,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
*/ */
public List<RzAttendance> listAttendanceByParams(RzAttendance rzAttendance) { public List<RzAttendance> listAttendanceByParams(RzAttendance rzAttendance) {
return rzAttendanceMapper.listAttendanceByParams(rzAttendance); return getBaseMapper().listAttendanceByParams(rzAttendance);
} }
/** /**
@ -255,7 +254,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
} }
SysStaff sysUser = sysStaffService.selectSysStaffByName(vo.getEmployeeName()); SysStaff sysUser = sysStaffService.selectSysStaffByName(vo.getEmployeeName());
if (sysUser == null) { if (sysUser == null) {
log.warn("未找到员工:{}", vo.getEmployeeName()); log.warn(String.format("未找到员工:{}", vo.getEmployeeName()));
failCount++; failCount++;
continue; continue;
} }
@ -270,7 +269,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
// 构建查询条件 // 构建查询条件
LambdaQueryWrapper<RzAttendanceDetail> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<RzAttendanceDetail> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(RzAttendanceDetail::getStaffId, sysUser.getUserId()) queryWrapper.eq(RzAttendanceDetail::getStaffId, sysUser.getUserId())
.apply("DATE(create_time) = DATE({0})", replacementDate); // 按天匹配 .apply(" DATE(create_time) = DATE({0})", replacementDate); // 按天匹配
if ("下班卡".equals(vo.getReissueType())) { if ("下班卡".equals(vo.getReissueType())) {
queryWrapper.eq(RzAttendanceDetail::getButtonType, NIGHT_CARD) queryWrapper.eq(RzAttendanceDetail::getButtonType, NIGHT_CARD)
@ -349,7 +348,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
} }
//写表 //写表
rzAttendanceMapper.update(attendance, new LambdaUpdateWrapper<RzAttendance>() getBaseMapper().update(attendance, new LambdaUpdateWrapper<RzAttendance>()
.eq(RzAttendance::getId, attendance.getId())); .eq(RzAttendance::getId, attendance.getId()));
rzAttendanceDetailMapper.update(rzAttendanceDetail, new LambdaUpdateWrapper<RzAttendanceDetail>() rzAttendanceDetailMapper.update(rzAttendanceDetail, new LambdaUpdateWrapper<RzAttendanceDetail>()
.eq(RzAttendanceDetail::getId, rzAttendanceDetail.getId())); .eq(RzAttendanceDetail::getId, rzAttendanceDetail.getId()));
@ -359,7 +358,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
RzAttendance attendance = selectRzAttendanceBySfIdAndNameAndTime(sysUser.getUserId(), vo.getEmployeeName(), replacementDate, true); RzAttendance attendance = selectRzAttendanceBySfIdAndNameAndTime(sysUser.getUserId(), vo.getEmployeeName(), replacementDate, true);
LambdaQueryWrapper<RzAttendanceDetail> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<RzAttendanceDetail> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(RzAttendanceDetail::getStaffId, sysUser.getUserId()) queryWrapper.eq(RzAttendanceDetail::getStaffId, sysUser.getUserId())
.apply(" and date_format(create_time,'%Y%m%d') = date_format({0},'%Y%m%d')", replacementDate) .apply(" date_format(create_time,'%Y%m%d') = date_format({0},'%Y%m%d')", replacementDate)
.in(vo.getReissueType().equals("加班卡"), RzAttendanceDetail::getButtonType, "加班卡") .in(vo.getReissueType().equals("加班卡"), RzAttendanceDetail::getButtonType, "加班卡")
.orderBy(vo.getReissueType().contains("加班卡"), true, RzAttendanceDetail::getDateTime); .orderBy(vo.getReissueType().contains("加班卡"), true, RzAttendanceDetail::getDateTime);
List<RzAttendanceDetail> details = rzAttendanceDetailMapper.selectList(queryWrapper); List<RzAttendanceDetail> details = rzAttendanceDetailMapper.selectList(queryWrapper);
@ -425,7 +424,7 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
} }
} }
rzAttendanceMapper.update(attendance, new LambdaUpdateWrapper<RzAttendance>() getBaseMapper().update(attendance, new LambdaUpdateWrapper<RzAttendance>()
.eq(RzAttendance::getId, attendance.getId())); .eq(RzAttendance::getId, attendance.getId()));
rzAttendanceDetailMapper.update(rzAttendanceDetail, new LambdaUpdateWrapper<RzAttendanceDetail>() rzAttendanceDetailMapper.update(rzAttendanceDetail, new LambdaUpdateWrapper<RzAttendanceDetail>()
.eq(RzAttendanceDetail::getId, rzAttendanceDetail.getId())); .eq(RzAttendanceDetail::getId, rzAttendanceDetail.getId()));
@ -452,14 +451,14 @@ public class RzAttendanceServiceImpl implements IRzAttendanceService {
wrapper.eq(RzAttendance::getStaffId, userId) wrapper.eq(RzAttendance::getStaffId, userId)
.eq(RzAttendance::getName, employeeName) .eq(RzAttendance::getName, employeeName)
.eq(RzAttendance::getAttendanceDate, replacementTime); .eq(RzAttendance::getAttendanceDate, replacementTime);
rzAttendance = rzAttendanceMapper.selectOne(wrapper); rzAttendance = getBaseMapper().selectOne(wrapper);
} else { } else {
LambdaQueryWrapper<RzAttendance> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<RzAttendance> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(RzAttendance::getStaffId, userId) wrapper.eq(RzAttendance::getStaffId, userId)
.eq(RzAttendance::getName, employeeName) .eq(RzAttendance::getName, employeeName)
.eq(RzAttendance::getAttendanceDate, replacementTime) .eq(RzAttendance::getAttendanceDate, replacementTime)
.eq(RzAttendance::getRemarks, "加班"); .eq(RzAttendance::getRemarks, "加班");
rzAttendance = rzAttendanceMapper.selectOne(wrapper); rzAttendance = getBaseMapper().selectOne(wrapper);
} }
return rzAttendance; return rzAttendance;

View File

@ -1,29 +1,37 @@
package com.evo.attendance.service.impl; package com.evo.attendance.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.domain.RzAttendance; import com.evo.attendance.domain.RzAttendance;
import com.evo.attendance.domain.RzAttendanceStatistical; import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.mapper.RzAttendanceMapper; import com.evo.attendance.mapper.RzAttendanceMapper;
import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; import com.evo.attendance.mapper.RzAttendanceStatisticalMapper;
import com.evo.attendance.mapper.RzSpecialAttendanceMapper;
import com.evo.attendance.service.IRzAttendanceStatisticalService; import com.evo.attendance.service.IRzAttendanceStatisticalService;
import com.evo.common.annotation.DataScope; import com.evo.common.annotation.DataScope;
import com.evo.common.constant.Constants; import com.evo.common.constant.Constants;
import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.AjaxResult;
import com.evo.common.core.domain.entity.SysDept; import com.evo.common.core.domain.entity.SysDept;
import com.evo.common.utils.*; import com.evo.common.utils.*;
import com.evo.common.utils.Collections;
import com.evo.personnelMatters.domain.RzLeaveDetail;
import com.evo.personnelMatters.domain.RzOverTime; import com.evo.personnelMatters.domain.RzOverTime;
import com.evo.personnelMatters.domain.RzOverTimeDetail;
import com.evo.personnelMatters.mapper.RzLeaveDetailMapper;
import com.evo.personnelMatters.mapper.RzOverTimeDetailMapper;
import com.evo.personnelMatters.mapper.RzOverTimeMapper; import com.evo.personnelMatters.mapper.RzOverTimeMapper;
import com.evo.system.domain.SysStaff; import com.evo.system.domain.SysStaff;
import com.evo.system.mapper.SysDeptMapper; import com.evo.system.mapper.SysDeptMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.beans.Transient;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.*;
import java.util.Calendar; import java.util.stream.Collectors;
import java.util.Date;
import java.util.List;
/** /**
* 考勤统计Service业务层处理 * 考勤统计Service业务层处理
@ -40,6 +48,13 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
private RzAttendanceMapper rzAttendanceMapper; //打卡记录 private RzAttendanceMapper rzAttendanceMapper; //打卡记录
@Resource @Resource
private RzOverTimeMapper rzOverTimeMapper; private RzOverTimeMapper rzOverTimeMapper;
@Resource
private RzOverTimeDetailMapper rzOverTimeDetailMapper;
@Resource
private RzSpecialAttendanceMapper rzSpecialAttendanceMapper;
@Resource
private RzLeaveDetailMapper rzLeaveDetailMapper;
/** /**
* 查询考勤统计 * 查询考勤统计
* *
@ -139,6 +154,7 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
} }
@Override @Override
@Transient
public RzAttendanceStatistical createRzAttendance(SysStaff sysStaff, List<String> dayList, Date date) { public RzAttendanceStatistical createRzAttendance(SysStaff sysStaff, List<String> dayList, Date date) {
if(date == null){ if(date == null){
date = DateUtils.getNowDate(); date = DateUtils.getNowDate();
@ -173,11 +189,8 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
rzAttendanceStatistical.setMonth(date); rzAttendanceStatistical.setMonth(date);
rzAttendanceStatistical.setShouldAttendance(new BigDecimal(ParamUtils.getMonthWorkDayNum(getMonthWorkDayNum(date))).multiply(new BigDecimal("8.00"))); rzAttendanceStatistical.setShouldAttendance(new BigDecimal(ParamUtils.getMonthWorkDayNum(getMonthWorkDayNum(date))).multiply(new BigDecimal("8.00")));
rzAttendanceStatistical.setDeptId(sysStaff.getDeptId()); rzAttendanceStatistical.setDeptId(sysStaff.getDeptId());
rzAttendanceStatistical.setDelFlag(Constants.DELETE_FLAG_0);
rzAttendanceStatistical.setCreateBy(SecurityUtils.getUsername());
rzAttendanceStatistical.setCreateTime(date);
rzAttendanceStatistical.setAbsenteeism(new BigDecimal(0)); rzAttendanceStatistical.setAbsenteeism(new BigDecimal(0));
getBaseMapper().insertRzAttendanceStatistical(rzAttendanceStatistical); getBaseMapper().insert(rzAttendanceStatistical);
//新增考勤详情 //新增考勤详情
SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd");
RzAttendance rzAttendance = null; RzAttendance rzAttendance = null;
@ -194,7 +207,7 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
} }
rzAttendance.setDelFlag(Constants.DELETE_FLAG_0); rzAttendance.setDelFlag(Constants.DELETE_FLAG_0);
rzAttendance.setCreateTime(DateUtils.getNowDate()); rzAttendance.setCreateTime(DateUtils.getNowDate());
rzAttendance.setCreateBy(SecurityUtils.getUsername()); rzAttendance.setCreateBy("admin");
pa_list.add(rzAttendance); pa_list.add(rzAttendance);
} }
rzAttendanceMapper.insertBatchRzAttendance(pa_list); rzAttendanceMapper.insertBatchRzAttendance(pa_list);
@ -202,6 +215,65 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
return rzAttendanceStatistical; return rzAttendanceStatistical;
} }
@Override
public AjaxResult autoCalculateTheDayBeforeAttendance(Date date) {
/***
* 1. 首先当前时间-1天, 获取到前一天的数据
* 2. 根据前一天查询统计表数据
* 3, 根据统计表的ID 分组查询考勤时长
* 4. 根据前一天时间, 分组查询加班时长
* 5. 根据前一天时间, 分组查询特殊加班时长
* 6. 根据前一天时间, 分组查询请假时长
* 7, 组装考勤统计数据
*/
//因为是前一天的数据, 所以需要-1
//查询当天的所有加班, 查询当天的所有
List<RzAttendanceStatistical> list = getBaseMapper().selectList(new LambdaQueryWrapper<RzAttendanceStatistical>().eq(RzAttendanceStatistical::getDelFlag, Constants.DELETE_FLAG_0).apply(" DATE_FORMAT(create_time,'%Y%m') = DATE_FORMAT({0},'%Y%m')", date));
//查询加班
Map<String ,Map<String, Object>> specialAttendanceMap = rzSpecialAttendanceMapper.getSpecialAttendanceHour(date).stream().collect(Collectors.toMap(d-> String.valueOf(d.get("staffId")), d->d, (k1,k2)->k1));
//查询统计汇总数据
Map<String ,Map<String, Object>> attendanceMap = rzAttendanceMapper.getAttendanceHour(date).stream().collect(Collectors.toMap(d-> String.valueOf(d.get("staffId")), d->d, (k1,k2)->k1));
//查询加班汇总数据
Map<String ,Map<String, Object>> overTimeMap = rzOverTimeDetailMapper.getOverTimeHour(date).stream().collect(Collectors.toMap(d-> String.valueOf(d.get("staffId")), d->d, (k1,k2)->k1));
//获取请假信息及详情
Map<String ,Map<String, Object>> leaveMap = rzLeaveDetailMapper.getLeaveHour(date).stream().collect(Collectors.toMap(d-> String.valueOf(d.get("staffId")), d->d, (k1,k2)->k1));;
//查询特殊加班汇总数据
list.stream().forEach(statistical ->{
//首选抓取员工考勤记录
Map<String, Object> attendance = attendanceMap.get(statistical.getStaffId());
if(attendance != null){
statistical.setRealAttendance(getValue(attendance,"workNum"));
statistical.setNightNumber(getValue(attendance,"nightNumber").longValue());
statistical.setMiddleShiftNumber(getValue(attendance,"middleShiftNumber").longValue());
}
//继续计算加班数据
Map<String, Object> overTime = overTimeMap.get(statistical.getStaffId());
if(overTime != null){
statistical.setWorkOvertimeNumber(getValue(overTime,"overTimeHours"));
}
//继续计算特殊加班数据
Map<String, Object> specialAttendance = specialAttendanceMap.get(statistical.getStaffId());
if(specialAttendance != null){
statistical.setOverTimeHours(getValue(specialAttendance,"workHours"));
}
//继续计算特殊加班数据
Map<String, Object> leave = leaveMap.get(statistical.getStaffId());
if(leave != null){
statistical.setAbsenteeism(getValue(leave,"leaveHour"));
}
});
//更新全部考勤
updateBatchById(list);
return AjaxResult.success();
}
public BigDecimal getValue(Map<String, Object> map, String key){
return new BigDecimal(ObjectUtils.isEmpty(map.get(key)) ? "0" : String.valueOf(map.get(key)));
}
public Integer getMonthWorkDayNum(Date date){ public Integer getMonthWorkDayNum(Date date){
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTime(date); calendar.setTime(date);

View File

@ -25,13 +25,14 @@ public class InsertAndUpdateMybatisHandler implements MetaObjectHandler {
@Override @Override
public void insertFill(MetaObject metaObject) { public void insertFill(MetaObject metaObject) {
try { try {
String userName = SecurityUtils.getUsername(); String name = "admin";
if(StringUtils.isEmpty(userName)){ try {
log.info("当前操作未登录, 无需执行"); name = SecurityUtils.getUsername();
return; } catch (Exception e) {
log.error("获取当前登录用户异常"+e.getMessage());
} }
if(ObjectUtils.isNotEmpty(metaObject)){ if(ObjectUtils.isNotEmpty(metaObject)){
mySetFieldValByName("createBy",SecurityUtils.getUsername(),metaObject); mySetFieldValByName("createBy", name,metaObject);
mySetFieldValByName("createTime",DateUtils.getNowDate(),metaObject); mySetFieldValByName("createTime",DateUtils.getNowDate(),metaObject);
mySetFieldValByName("delFlag",Constants.DELETE_FLAG_0,metaObject); mySetFieldValByName("delFlag",Constants.DELETE_FLAG_0,metaObject);
} }
@ -52,13 +53,14 @@ public class InsertAndUpdateMybatisHandler implements MetaObjectHandler {
@Override @Override
public void updateFill(MetaObject metaObject) { public void updateFill(MetaObject metaObject) {
try { try {
String userName = SecurityUtils.getUsername(); String name = "admin";
if(StringUtils.isEmpty(userName)){ try {
log.info("当前操作未登录, 无需执行"); name = SecurityUtils.getUsername();
return; } catch (Exception e) {
log.error("获取当前登录用户异常"+e.getMessage());
} }
if(ObjectUtils.isNotEmpty(metaObject)){ if(ObjectUtils.isNotEmpty(metaObject)){
mySetFieldValByName("updateBy",userName,metaObject); mySetFieldValByName("updateBy",name,metaObject);
mySetFieldValByName("updateTime",DateUtils.getNowDate(),metaObject); mySetFieldValByName("updateTime",DateUtils.getNowDate(),metaObject);
} }
} catch (Exception e) { } catch (Exception e) {

View File

@ -223,6 +223,21 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
return monthsDiff; return monthsDiff;
} }
public static Date getMonthFirst(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_MONTH, 1);
return calendar.getTime();
}
public static Date getMonthEnd(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.MONTH, 1);
calendar.add(Calendar.DAY_OF_MONTH, -1);
return calendar.getTime();
}
public static Long getBetweenDays(Date start, Date end){ public static Long getBetweenDays(Date start, Date end){
Calendar currentDate = Calendar.getInstance(); Calendar currentDate = Calendar.getInstance();
@ -234,6 +249,15 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
return calculateDifferenceInDays(endCalendar, currentDate); return calculateDifferenceInDays(endCalendar, currentDate);
} }
public static Long getBetweenMinutes(Date start, Date end){
Calendar currentDate = Calendar.getInstance();
currentDate.setTime(start);
// 将输入的Date转换为Calendar以便获取年月信息
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(end);
long diffInMillis = endCalendar.getTimeInMillis() - currentDate.getTimeInMillis();
return diffInMillis / (60 * 1000);
}
public static long calculateDifferenceInDays(Calendar date1, Calendar date2) { public static long calculateDifferenceInDays(Calendar date1, Calendar date2) {
long diffInMillies = Math.abs(date1.getTimeInMillis() - date2.getTimeInMillis()); long diffInMillies = Math.abs(date1.getTimeInMillis() - date2.getTimeInMillis());

View File

@ -7,6 +7,7 @@ import com.evo.personnelMatters.domain.RzHoliday;
import com.evo.personnelMatters.service.IRzHolidayService; import com.evo.personnelMatters.service.IRzHolidayService;
import com.evo.system.service.ISysDictDataService; import com.evo.system.service.ISysDictDataService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -78,6 +79,61 @@ public class ParamUtils {
RzSysParam param= paramService.getRzSysParam("需要自动计算请假时长的请假类型", "auto_calculation_holiday_type","54,56,57,58,59","需要自动计算请假时长的请假类型, 多个参数使用,隔开"); RzSysParam param= paramService.getRzSysParam("需要自动计算请假时长的请假类型", "auto_calculation_holiday_type","54,56,57,58,59","需要自动计算请假时长的请假类型, 多个参数使用,隔开");
return Collections.asList(param.getParamValue().split(",")); return Collections.asList(param.getParamValue().split(","));
} }
/***
* 检查特殊打卡机的规则
* sn 设备号
* rules 规则
* @return
*/
public static Boolean checkTsDeviceButton(String sn, String rules){
if(StringUtils.isEmpty(rules))return true;
RzSysParam param= paramService.getRzSysParam("特殊打卡机的打卡按钮规则", "ts_device_button_rules","{\"ET74336\":\"加班卡,下班卡\"}","特殊打卡机的打卡按钮规则, 使用json格式, 如果打卡机存在多个按钮规则用,分割");
String val = param.getParamValue();
JSONObject jsonObject = JSONObject.parseObject(val);
String rulesVal = jsonObject.getString(sn);
if(StringUtils.isEmpty(rulesVal)) return false;
return Collections.asList(rulesVal.split(",")).contains(rules);
}
/***
* 获取特殊加班的考勤规则
* sn 设备号
* rules 规则
* @return
*/
public static JSONObject getDeviceOverTimeRules(String sn){
if(StringUtils.isEmpty(sn)) return null;
RzSysParam param= paramService.getRzSysParam("特殊加班的考勤规则", "device_over_time_rules","{\"ET74336\":{\"minHour\":2, \"maxHour\":3,\"endMealTime\":\"19:00\"}}","特殊加班的考勤规则, minHour:最小加班时长. maxHour: 最大加班时长, endMealTime: 餐厅闭厅时间");
String val = param.getParamValue();
JSONObject jsonObject = JSONObject.parseObject(val);
JSONObject rules = jsonObject.getJSONObject(sn);
return (ObjectUtils.isEmpty(rules) ? JSONObject.parseObject("{\"maxHour\":4}") : rules);
}
/***
* 获取特殊加班的考勤规则
* sn 设备号
* rules 规则
* @return
*/
public static String getYcRulesByButtonName(String type, String buttonName){
if(StringUtils.isEmpty(type) || StringUtils.isEmpty(buttonName)) return null;
RzSysParam param= paramService.getRzSysParam("打卡按钮的打卡异常规则", "device_button_yc_rules",
"{\"上班\":{" +
"\"上班卡(单班制)\":\"function greet() { return new Date('dkDateTime') > new Date('dkDate'+' 08:30:00'); } greet();\"," +
"\"上班卡倒班8时制\":\"function greet() { return ((new Date('dkDateTime') > new Date('dkDate'+' 08:30:00') && new Date('dkDateTime').getHours() < 12) || (new Date('dkDateTime') > new Date('dkDate'+' 17:00:00') && new Date('dkDateTime').getHours() < 21)); } greet();\"," +
"\"上班卡倒班12时制\":\"function greet() { return ((new Date('dkDateTime') > new Date('dkDate'+' 08:30:00') && new Date('dkDateTime').getHours() < 12) || (new Date('dkDateTime') > new Date('dkDate'+' 20:30:00') && new Date('dkDateTime').getHours() < 24)); } greet();\"," +
"},\"下班\":{" +
"\"上班卡(单班制)\":\"function greet() { return new Date('dkDateTime') < new Date('dkDate'+' 17:30:00'); } greet();\"," +
"\"上班卡倒班8时制\":\"function greet() { return ((new Date('dkDateTime') < new Date('dkDate'+' 17:00:00') && new Date('dkDateTime') > new Date('dkDate'+' 08:30:00')) || (new Date('dkDateTime') < new Date('dkDate'+' 01:30:00') && new Date('dkDateTime') > new Date('dkDate'+' 17:00:00'))); } greet();\"," +
"\"上班卡倒班12时制\":\"function greet() { return ((new Date('dkDateTime') < new Date('dkDate'+' 20:30:00') && new Date('dkDateTime').getHours() > 14) || new Date('dkDateTime') < new Date('dkDate'+' 08:30:00')); } greet();\"," +
"}}","特殊加班的考勤规则, minHour:最小加班时长. maxHour: 最大加班时长, endMealTime: 餐厅闭厅时间");
String val = param.getParamValue();
JSONObject jsonObject = JSONObject.parseObject(val);
JSONObject typeJson = jsonObject.getJSONObject(type);
return typeJson != null ? typeJson.getString(buttonName) : null;
}
/*** /***
* 获取每月的工作天数 * 获取每月的工作天数

View File

@ -2,6 +2,7 @@ package com.evo.equipment.domain;
import com.evo.common.annotation.Excel; import com.evo.common.annotation.Excel;
import com.evo.common.core.domain.BaseEntity; import com.evo.common.core.domain.BaseEntity;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@ -11,6 +12,7 @@ import org.apache.commons.lang3.builder.ToStringStyle;
* @author chenyj * @author chenyj
* @date 2024-08-15 * @date 2024-08-15
*/ */
@Data
public class EqButton extends BaseEntity public class EqButton extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -26,6 +28,11 @@ public class EqButton extends BaseEntity
@Excel(name = "按钮名称") @Excel(name = "按钮名称")
private String name; private String name;
/***
* 工作时长
*/
private Integer workHour;
/** 图标地址 */ /** 图标地址 */
@Excel(name = "图标地址") @Excel(name = "图标地址")
private String image; private String image;
@ -37,61 +44,6 @@ public class EqButton extends BaseEntity
@Excel(name = "备注") @Excel(name = "备注")
private String remarks; private String remarks;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setNum(String num)
{
this.num = num;
}
public String getNum()
{
return num;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setImage(String image)
{
this.image = image;
}
public String getImage()
{
return image;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
public void setRemarks(String remarks)
{
this.remarks = remarks;
}
public String getRemarks()
{
return remarks;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -1,5 +1,6 @@
package com.evo.equipment.mapper; package com.evo.equipment.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.equipment.domain.EqButton; import com.evo.equipment.domain.EqButton;
import java.util.List; import java.util.List;
@ -10,7 +11,7 @@ import java.util.List;
* @author chenyj * @author chenyj
* @date 2024-08-15 * @date 2024-08-15
*/ */
public interface EqButtonMapper public interface EqButtonMapper extends BaseMapper<EqButton>
{ {
/** /**
* 查询按钮信息 * 查询按钮信息

View File

@ -64,5 +64,5 @@ public interface IEqSnDetailService
/*** /***
* 检查设备在线情况 * 检查设备在线情况
*/ */
public void checkDevice(); public void checkDevice(String sessionId);
} }

View File

@ -120,8 +120,13 @@ public class EqSnDetailServiceImpl extends ServiceImpl<EqSnDetailMapper, EqSnDet
Map<Long, RzUpload> longRzUploadMap = rzUploadService.selectListByBusinessIdAndyType(userList.stream().map(SysStaff::getUserId).collect(Collectors.toList()), "avatar").stream().collect(Collectors.toMap(RzUpload::getBusinessId, d->d, (k1,k2) ->k1)); Map<Long, RzUpload> longRzUploadMap = rzUploadService.selectListByBusinessIdAndyType(userList.stream().map(SysStaff::getUserId).collect(Collectors.toList()), "avatar").stream().collect(Collectors.toMap(RzUpload::getBusinessId, d->d, (k1,k2) ->k1));
String url = ParamUtils.getGlobalStaticUrl(); String url = ParamUtils.getGlobalStaticUrl();
for(SysStaff user : userList){ for(SysStaff user : userList){
userPhotoList.add(Collections.asMap("userId", String.valueOf(user.getUserId()), "name", user.getName(), "photoUrl", url+longRzUploadMap.get(user.getUserId()).getFileName())); try {
// userPhotoList.add(Collections.asMap("userId", String.valueOf(user.getUserId()), "name", user.getName(), "photoUrl", longRzUploadMap.get(user.getUserId()).getUrl())); // userPhotoList.add(Collections.asMap("userId", String.valueOf(user.getUserId()), "name", user.getName(), "photoUrl", url+longRzUploadMap.get(user.getUserId()).getFileName()));
userPhotoList.add(Collections.asMap("userId", String.valueOf(user.getUserId()), "name", user.getName(), "photoUrl", longRzUploadMap.get(user.getUserId()).getUrl()));
} catch (Exception e) {
log.error("员工:"+String.valueOf(user.getUserId())+" 的照片拼装出现问题:"+e.getMessage());
}
//
} }
return userPhotoList; return userPhotoList;
} }
@ -255,7 +260,7 @@ public class EqSnDetailServiceImpl extends ServiceImpl<EqSnDetailMapper, EqSnDet
public Boolean sendButtons(List<String> snList) { public Boolean sendButtons(List<String> snList) {
Map<String, Session> sessionMap = checkSession(snList); Map<String, Session> sessionMap = checkSession(snList);
List<EqButton> bt_list = this.eqButtonMapper.selectEqButtonList(null); List<EqButton> bt_list = eqButtonMapper.selectEqButtonList(null);
CwButtonVo cbv = new CwButtonVo(); CwButtonVo cbv = new CwButtonVo();
CwButtonData cbd = new CwButtonData(); CwButtonData cbd = new CwButtonData();
cbv.setCmd("to_device"); cbv.setCmd("to_device");
@ -278,8 +283,7 @@ public class EqSnDetailServiceImpl extends ServiceImpl<EqSnDetailMapper, EqSnDet
} }
@Override @Override
public void checkDevice() { public void checkDevice(String sessionId) {
List<String> sessionIds = WebSocketUsers.getUsers().keySet().stream().collect(Collectors.toList()); update(new UpdateWrapper<EqSnDetail>().set("type","连接已断开").set("session_id","").eq( "session_id", sessionId));
update(new UpdateWrapper<EqSnDetail>().set("type","连接已断开").notIn(Collections.isNotEmpty(sessionIds), "session_id", sessionIds));
} }
} }

View File

@ -76,6 +76,8 @@ public class WebSocketServer{
public void onClose(Session session) public void onClose(Session session)
{ {
LOGGER.info("\n 关闭连接 - {}", session); LOGGER.info("\n 关闭连接 - {}", session);
//做设备掉线标记
snDetailService.checkDevice(session.getId());
// 移除用户 // 移除用户
WebSocketUsers.remove(session.getId()); WebSocketUsers.remove(session.getId());
// 获取到信号量则需释放 // 获取到信号量则需释放
@ -96,6 +98,8 @@ public class WebSocketServer{
String sessionId = session.getId(); String sessionId = session.getId();
LOGGER.info("\n 连接异常 - {}", sessionId); LOGGER.info("\n 连接异常 - {}", sessionId);
LOGGER.info("\n 异常信息 - {}", exception); LOGGER.info("\n 异常信息 - {}", exception);
//做设备掉线标记
snDetailService.checkDevice(sessionId);
// 移出用户 // 移出用户
WebSocketUsers.remove(sessionId); WebSocketUsers.remove(sessionId);
// 获取到信号量则需释放 // 获取到信号量则需释放

View File

@ -50,6 +50,11 @@ public class RzLeaveDetail extends BaseEntity
private String delFlag; private String delFlag;
/***
* 扩展字段
*/
private String extension;
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -1,5 +1,7 @@
package com.evo.personnelMatters.domain; package com.evo.personnelMatters.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.evo.common.annotation.Excel; import com.evo.common.annotation.Excel;
import com.evo.common.core.domain.BaseEntity; import com.evo.common.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
@ -47,6 +49,7 @@ public class RzOverTime extends BaseEntity
private BigDecimal taskHours; private BigDecimal taskHours;
/** 删除标识 */ /** 删除标识 */
@TableField(fill = FieldFill.INSERT)
private String delFlag; private String delFlag;

View File

@ -5,7 +5,7 @@ import com.evo.personnelMatters.domain.EqOverStaff;
import java.util.List; import java.util.List;
/** /**
* 照片管理Mapper接口 * 特殊加班Mapper接口
* *
* @author evo * @author evo
* @date 2025-04-17 * @date 2025-04-17

View File

@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.personnelMatters.domain.RzLeaveDetail; import com.evo.personnelMatters.domain.RzLeaveDetail;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 请假管理详情Mapper接口 * 请假管理详情Mapper接口
@ -63,4 +65,14 @@ public interface RzLeaveDetailMapper extends BaseMapper<RzLeaveDetail>
public List<RzLeaveDetail> selectRzLeaveDetailByName(@Param("deptId") Long deptId,@Param("name") String name); public List<RzLeaveDetail> selectRzLeaveDetailByName(@Param("deptId") Long deptId,@Param("name") String name);
/**
* 查询日期是否请假
*
* @param id 请假管理详情主键
* @return 请假管理详情
*/
public RzLeaveDetail selectRzLeaveDetailByUserIdAndDate(@Param("userId") Long userId,@Param("date") Date date);
List<Map<String,Object>> getLeaveHour(@Param("date") Date date);
} }

View File

@ -1,9 +1,11 @@
package com.evo.personnelMatters.mapper; package com.evo.personnelMatters.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.personnelMatters.domain.RzOverTimeDetail; import com.evo.personnelMatters.domain.RzOverTimeDetail;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 加班详情Mapper接口 * 加班详情Mapper接口
@ -11,7 +13,7 @@ import java.util.List;
* @author chenyj * @author chenyj
* @date 2024-09-09 * @date 2024-09-09
*/ */
public interface RzOverTimeDetailMapper public interface RzOverTimeDetailMapper extends BaseMapper<RzOverTimeDetail>
{ {
/** /**
* 查询加班详情 * 查询加班详情
@ -59,5 +61,12 @@ public interface RzOverTimeDetailMapper
*/ */
public List<RzOverTimeDetail> queryRzOverTimeDetailByOverId(Long overId); public List<RzOverTimeDetail> queryRzOverTimeDetailByOverId(Long overId);
/**
* 根据加班统计ID和加班开始时间查询加班情况
* @return
*/
public RzOverTimeDetail getLastRzOverTimeDetailByUserIdAndNotId(@Param("userId") Long userId,@Param("notId") Long notId);
List<Map<String,Object>> getOverTimeHour(@Param("date") Date date);
} }

View File

@ -1,7 +1,9 @@
package com.evo.personnelMatters.service.impl; package com.evo.personnelMatters.service.impl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.common.constant.Constants; import com.evo.common.constant.Constants;
import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.AjaxResult;
import com.evo.common.core.domain.entity.SysDictData; import com.evo.common.core.domain.entity.SysDictData;
@ -16,6 +18,7 @@ import com.evo.personnelMatters.mapper.RzLeaveDetailMapper;
import com.evo.personnelMatters.mapper.RzLeaveMapper; import com.evo.personnelMatters.mapper.RzLeaveMapper;
import com.evo.personnelMatters.mapper.RzOverTimeMapper; import com.evo.personnelMatters.mapper.RzOverTimeMapper;
import com.evo.personnelMatters.service.IRzLeaveDetailService; import com.evo.personnelMatters.service.IRzLeaveDetailService;
import com.evo.system.domain.SysStaff;
import com.evo.system.service.ISysDictDataService; import com.evo.system.service.ISysDictDataService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -23,8 +26,12 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 请假管理详情Service业务层处理 * 请假管理详情Service业务层处理
@ -129,19 +136,7 @@ public class RzLeaveDetailServiceImpl extends ServiceImpl<RzLeaveDetailMapper, R
} }
//不再反写考勤汇总, 由定时器, 每天执行查找 //不再反写考勤汇总, 由定时器, 每天执行查找
//这里需要做特殊处理, 如果时间范围跨月了, 需要每个月的考勤都要处理 //这里需要做特殊处理, 如果时间范围跨月了, 需要每个月的考勤都要处理
// Integer betweenMonth = DateUtils.getBetweenMonth(rzLeaveDetail.getLeaveStartTime(), rzLeaveDetail.getLeaveEndTime()); buildExtension(rzLeaveDetail);
// Date date = rzLeaveDetail.getLeaveStartTime();
// for (int i = 0; i <= betweenMonth; i++) {
// date = DateUtils.addMonths(date, i>0 ? 1 : 0);
// System.out.println(DateUtils.parseDateToStr("yyyy-MM-dd", date));
// RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzLeave.getUserId(),date);
// if(rzAttendanceStatistical == null){
// SysStaff sysStaff = sysStaffService.selectSysStaffByUserId(rzLeave.getUserId());
// rzAttendanceStatistical = sysStaffService.createRzAttendance(sysStaff, Collections.emptyList(), date);
// }
// rzAttendanceStatistical.setAbsenteeism(rzAttendanceStatistical.getAbsenteeism().add(new BigDecimal(holidayHour)));
// rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical);
// }
return AjaxResult.success(); return AjaxResult.success();
} }
@ -150,6 +145,59 @@ public class RzLeaveDetailServiceImpl extends ServiceImpl<RzLeaveDetailMapper, R
return new BigDecimal(baseNum).add(new BigDecimal(addNum)).intValue(); return new BigDecimal(baseNum).add(new BigDecimal(addNum)).intValue();
} }
public static void main(String[] args) {
YearMonth yearMonth = YearMonth.of(2025, 5);
LocalDate firsDay = yearMonth.atDay(1);
System.out.println(firsDay);
LocalDate endDay = yearMonth.atEndOfMonth();
System.out.println(endDay);
}
public void buildExtension(RzLeaveDetail rzLeaveDetail){
SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat ym = new SimpleDateFormat("yyyy-MM");
SimpleDateFormat m = new SimpleDateFormat("MM");
String flag = String.valueOf(rzLeaveDetail.getType());
Map<String, Object> extensionMap = Collections.emptyMap();
//先计算相差几个月
Integer betweenMonth = DateUtils.getBetweenMonth(rzLeaveDetail.getLeaveStartTime(), rzLeaveDetail.getLeaveEndTime());
Date startDate = rzLeaveDetail.getLeaveStartTime();
for (int i = 0; i <= betweenMonth; i++) {
startDate = DateUtils.addMonths(startDate, i>0 ? 1 : 0);
//获取月的开始时间和结束时间
Date firsDay = DateUtils.getMonthFirst(startDate);
if(firsDay.compareTo(rzLeaveDetail.getLeaveStartTime())<0){
firsDay = rzLeaveDetail.getLeaveStartTime();
}
Date endDay = DateUtils.getMonthEnd(startDate);
if(endDay.compareTo(rzLeaveDetail.getLeaveEndTime())>0){
endDay = rzLeaveDetail.getLeaveEndTime();
}
//获取相差天数 因为包含开始结束, 所以需要加1
Long dayNum = DateUtils.getBetweenDays(firsDay,endDay)+1;
List<String> dayList = Collections.emptyList();
for (int j = 0; j < dayNum; j++) {
dayList.add(ymd.format(DateUtils.addDays(firsDay, j>0 ? 1 : 0)));
}
List<String> holidays = Collections.emptyList();
if(ParamUtils.getLeaveTypeNotIncludedFaXiuAndPublicHoliday().contains(flag)){
holidays.addAll(ParamUtils.getHoliddayList(firsDay.getYear(), 0));
}else if(ParamUtils.getLeaveTypeNotIncludedFaXiu().contains(flag)){
holidays.addAll(ParamUtils.getHoliddayList(firsDay.getYear(), 1));
}else{
holidays.addAll(ParamUtils.getHoliddayList(firsDay.getYear(), 2));
}
//获取假期里的重复天数
Integer doubleDayNum = Collections.findDuplicatesList(holidays, dayList).size();
//计算实际放假天数
Integer holidayNum = dayList.size()-doubleDayNum;
extensionMap.put("month"+m.format(firsDay), ym.format(firsDay));
extensionMap.put("hours"+m.format(firsDay), holidayNum*8);
}
rzLeaveDetail.setExtension(JSON.toJSONString(extensionMap));
getBaseMapper().updateById(rzLeaveDetail);
}
/** /**
@ -173,7 +221,7 @@ public class RzLeaveDetailServiceImpl extends ServiceImpl<RzLeaveDetailMapper, R
// return false; // return false;
// //
//查询加班时长, 核实当前 //查询加班时长, 核实当前
RzOverTime rzOverTime = overTimeMapper.selectOne(new LambdaQueryWrapper<RzOverTime>().eq(RzOverTime::getUserId, staffId).apply(" and date_format(over_time_month,'%Y%m') = date_format({0},'%Y%m')", date)); RzOverTime rzOverTime = overTimeMapper.selectOne(new LambdaQueryWrapper<RzOverTime>().eq(RzOverTime::getUserId, staffId).apply(" date_format(over_time_month,'%Y%m') = date_format({0},'%Y%m')", date));
if(rzOverTime != null && rzOverTime.getOverHours().compareTo(rzOverTime.getTaskHours().add(new BigDecimal(hours))) <=0){ if(rzOverTime != null && rzOverTime.getOverHours().compareTo(rzOverTime.getTaskHours().add(new BigDecimal(hours))) <=0){
rzOverTime.setTaskHours(rzOverTime.getTaskHours().add(new BigDecimal(hours))); rzOverTime.setTaskHours(rzOverTime.getTaskHours().add(new BigDecimal(hours)));
return overTimeMapper.updateById(rzOverTime) > 0; return overTimeMapper.updateById(rzOverTime) > 0;
@ -207,7 +255,7 @@ public class RzLeaveDetailServiceImpl extends ServiceImpl<RzLeaveDetailMapper, R
//如果小于0 并且是调休, 需要反加加班 //如果小于0 并且是调休, 需要反加加班
//验证调休 //验证调休
if(Long.valueOf(55).equals(rzLeaveDetail.getType())){ if(Long.valueOf(55).equals(rzLeaveDetail.getType())){
RzOverTime rzOverTime = overTimeMapper.selectOne(new LambdaQueryWrapper<RzOverTime>().eq(RzOverTime::getUserId, rzLeave.getUserId()).apply(" and date_format(over_time_month,'%Y%m') = date_format({0},'%Y%m')", rzLeaveDetail.getLeaveStartTime())); RzOverTime rzOverTime = overTimeMapper.selectOne(new LambdaQueryWrapper<RzOverTime>().eq(RzOverTime::getUserId, rzLeave.getUserId()).apply(" date_format(over_time_month,'%Y%m') = date_format({0},'%Y%m')", rzLeaveDetail.getLeaveStartTime()));
rzOverTime.setOverHours(rzOverTime.getTaskHours().add(new BigDecimal(Math.abs(newHolidayHour)))); rzOverTime.setOverHours(rzOverTime.getTaskHours().add(new BigDecimal(Math.abs(newHolidayHour))));
rzOverTime.setTaskHours(rzOverTime.getTaskHours().subtract(new BigDecimal(Math.abs(newHolidayHour)))); rzOverTime.setTaskHours(rzOverTime.getTaskHours().subtract(new BigDecimal(Math.abs(newHolidayHour))));
overTimeMapper.updateById(rzOverTime); overTimeMapper.updateById(rzOverTime);

View File

@ -90,10 +90,10 @@ public interface ISysStaffService extends IService<SysStaff>
*/ */
public List<SysStaff> queryysStaffByDeptId(Long deptId); public List<SysStaff> queryysStaffByDeptId(Long deptId);
/** // /**
* 自动计算工龄 // * 自动计算工龄
*/ // */
public void calculationOfSeniority(); // public void calculationOfSeniority();
public SysStaff selectSysStaffByName(String employeeName); public SysStaff selectSysStaffByName(String employeeName);

View File

@ -825,38 +825,38 @@ public class SysStaffServiceImpl extends ServiceImpl<SysStaffMapper, SysStaff> i
/** /**
* 自动计算工龄 * 自动计算工龄
*/ */
@Override // @Override
public void calculationOfSeniority(){ // public void calculationOfSeniority(){
//获取在职员工数据 // //获取在职员工数据
List<SysStaff> params_list = getBaseMapper().selectSysStaffListAll(); // List<SysStaff> params_list = getBaseMapper().selectSysStaffListAll();
//当前日期减去一个月计算工龄计算工资比实际工龄延后一个月 // //当前日期减去一个月计算工龄计算工资比实际工龄延后一个月
Calendar calendar = Calendar.getInstance(); // Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, -1); // calendar.add(Calendar.MONTH, -1);
SimpleDateFormat sdfm = new SimpleDateFormat("yyyy-MM"); // SimpleDateFormat sdfm = new SimpleDateFormat("yyyy-MM");
SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); // SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd");
try{ // try{
String str = sdfm.format(calendar.getTime()); // String str = sdfm.format(calendar.getTime());
Date date = sdfd.parse(str + "-01"); // Date date = sdfd.parse(str + "-01");
for (SysStaff sysStaff : params_list) { // for (SysStaff sysStaff : params_list) {
//获取入职日期计算入职日期到当前时间差 // //获取入职日期计算入职日期到当前时间差
int years = date.getYear() - sysStaff.getEmploymentDate().getYear(); // int years = date.getYear() - sysStaff.getEmploymentDate().getYear();
int months = date.getMonth() - sysStaff.getEmploymentDate().getMonth(); // int months = date.getMonth() - sysStaff.getEmploymentDate().getMonth();
int days = date.getDate() - sysStaff.getEmploymentDate().getDate(); // int days = date.getDate() - sysStaff.getEmploymentDate().getDate();
//判断月份和日期 // //判断月份和日期
if (months < 0 || (months == 0 && days < 0)) { // if (months < 0 || (months == 0 && days < 0)) {
years -= 1; // years -= 1;
} // }
if(years > 0){ // if(years > 0){
sysStaff.setSeniority(Long.valueOf(years)); // sysStaff.setSeniority(Long.valueOf(years));
}else{ // }else{
sysStaff.setSeniority(0l); // sysStaff.setSeniority(0l);
} // }
getBaseMapper().updateSysStaff(sysStaff); // getBaseMapper().updateSysStaff(sysStaff);
} // }
}catch(Exception e){ // }catch(Exception e){
e.printStackTrace(); // e.printStackTrace();
} // }
} // }
@Override @Override
public SysStaff selectSysStaffByName(String employeeName) { public SysStaff selectSysStaffByName(String employeeName) {

View File

@ -34,26 +34,34 @@ public class SubsidyCalculationUtils {
public static final String ht = "12"; public static final String ht = "12";
public static final String gl = "14"; public static final String gl = "14";
public static final String xnh = "13";
public static SysStaffDetail subsidyCalculation(SysStaff staff, SysStaffDetail staffDetail, List<RzSubsidyInfo> subsidyInfoList){ public static SysStaffDetail subsidyCalculation(SysStaff staff, SysStaffDetail staffDetail, List<RzSubsidyInfo> subsidyInfoList){
//正式员工并且有补助信息 //正式员工并且有补助信息
if(Constants.JOB_STATIS_1.equals(staff.getStatus()) && StringUtils.isNotEmpty(staff.getSubsidys())){ if(Constants.JOB_STATIS_1.equals(staff.getStatus())){
Map<Long, RzSubsidyInfo> map = subsidyInfoList.stream().collect(Collectors.toMap(RzSubsidyInfo::getId, d->d, (k1, K2)->k1)); if(StringUtils.isNotEmpty(staff.getSubsidys())){
for(String subsidyId : staff.getSubsidys().split(",")){ Map<Long, RzSubsidyInfo> map = subsidyInfoList.stream().collect(Collectors.toMap(RzSubsidyInfo::getId, d->d, (k1, K2)->k1));
RzSubsidyInfo rzSubsidyInfo = map.get(Long.valueOf(subsidyId)); Boolean isAdd = true;
String key = rzSubsidyInfo.getName(); for(String subsidyId : staff.getSubsidys().split(",")){
BigDecimal value = rzSubsidyInfo.getValue(); isAdd = true;
if(ht.equals(subsidyId)){ RzSubsidyInfo rzSubsidyInfo = map.get(Long.valueOf(subsidyId));
Integer year= DateUtils.getBetweenYear(staff.getContractStart(), staff.getContractEnd()); String key = rzSubsidyInfo.getName();
value = value.multiply(new BigDecimal(year)); BigDecimal value = rzSubsidyInfo.getValue();
}else if(gl.equals(subsidyId)){ if(ht.equals(subsidyId)){
Integer year= DateUtils.getBetweenYear(staff.getEmploymentDate(), new Date()); Integer year= DateUtils.getBetweenYear(staff.getContractStart(), staff.getContractEnd());
//最多只允许10年的工龄补贴 value = value.multiply(new BigDecimal(year));
if(year > 10) year=10; }else if(gl.equals(subsidyId)){
value = value.multiply(new BigDecimal(year)); Integer year= DateUtils.getBetweenYear(staff.getEmploymentDate(), new Date());
//最多只允许10年的工龄补贴
if(year > 10) year=10;
value = value.multiply(new BigDecimal(year));
}else if(xnh.equals(subsidyId)){
isAdd = "新农合".equals(staff.getSocialType()) && ("".equals(staff.getSocialSubsidy()) || "享有".equals(staff.getSocialSubsidy()));
}
if(isAdd) staffDetail.getExtendeds().put(key, value);
} }
staffDetail.getExtendeds().put(key, value);
} }
//计算学历补助 //计算学历补助
if(StringUtils.isNotEmpty(staff.getLevel())){ if(StringUtils.isNotEmpty(staff.getLevel())){

View File

@ -1,6 +1,9 @@
package com.evo.task; package com.evo.task;
import com.evo.attendance.service.IRzAbnormalDetailService; import com.evo.attendance.service.IRzAbnormalDetailService;
import com.evo.attendance.service.IRzAttendanceService;
import com.evo.attendance.service.IRzAttendanceStatisticalService;
import com.evo.common.utils.DateUtils;
import com.evo.equipment.service.IEqSnDetailService; import com.evo.equipment.service.IEqSnDetailService;
import com.evo.restaurant.service.IRzRestaurantStatisticsService; import com.evo.restaurant.service.IRzRestaurantStatisticsService;
import com.evo.system.service.ISysStaffService; import com.evo.system.service.ISysStaffService;
@ -8,6 +11,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Date;
@Component @Component
public class TaskController { public class TaskController {
@ -19,8 +23,7 @@ public class TaskController {
@Resource @Resource
private IRzAbnormalDetailService abnormalDetailService; private IRzAbnormalDetailService abnormalDetailService;
@Resource @Resource
private IEqSnDetailService eqSnDetailService; //异常卡 private IRzAttendanceStatisticalService rzAttendanceStatisticalService;
/** /**
* 每月1号 020 自动生成考勤数据 * 每月1号 020 自动生成考勤数据
*/ */
@ -35,6 +38,16 @@ public class TaskController {
public void insertRzRestaurantStatistics(){ public void insertRzRestaurantStatistics(){
rzRestaurantStatisticsService.insertRzRestaurantStatistics(); rzRestaurantStatisticsService.insertRzRestaurantStatistics();
} }
/**
* 每天凌晨3点核算前一天的考勤情况
*/
//@Scheduled(cron = "0 0/30 * * * ?")
@Scheduled(cron = "0 0 3 * * ?")
public void autoCalculateTheDayBeforeAttendance(){
rzAttendanceStatisticalService.autoCalculateTheDayBeforeAttendance(DateUtils.addDays(new Date(),-1));
}
/** /**
* 每天 110 计算转正,离职日期 * 每天 110 计算转正,离职日期
*/ */
@ -44,7 +57,7 @@ public class TaskController {
}; };
/** /**
* 每天2300 计算当天的异常 * 每天2300 核验考勤情况, 异常
*/ */
//@Scheduled(cron = "0 0/30 * * * ?") //@Scheduled(cron = "0 0/30 * * * ?")
@Scheduled(cron = "0 0 23 * * ?") @Scheduled(cron = "0 0 23 * * ?")
@ -52,19 +65,20 @@ public class TaskController {
abnormalDetailService.insertRzAbnormalDetail(); abnormalDetailService.insertRzAbnormalDetail();
} }
/** // /**
* 每月10号2点自动计算工龄 // * 每月10号2点自动计算工龄
*/ // */
@Scheduled(cron = "0 0 2 10 * ?") // @Scheduled(cron = "0 0 2 10 * ?")
public void calculationOfSeniority(){ // public void calculationOfSeniority(){
sysStaffService.calculationOfSeniority(); // sysStaffService.calculationOfSeniority();
} // }
// /**
// * 每10秒检查一次设备在线情况
// */
// @Scheduled(fixedRate = 10000)
// public void checkDevice(){
// eqSnDetailService.checkDevice();
// };
/**
* 每月1号 020 自动生成考勤数据
*/
@Scheduled(fixedRate = 5000)
public void checkDevice(){
eqSnDetailService.checkDevice();
};
} }

View File

@ -125,4 +125,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where del_flag = '0' and DATE_FORMAT( attendance_date, '%Y%m%d' ) = DATE_FORMAT(NOW() , '%Y%m%d' ) where del_flag = '0' and DATE_FORMAT( attendance_date, '%Y%m%d' ) = DATE_FORMAT(NOW() , '%Y%m%d' )
and staff_id in (select user_id from sys_staff where status != '-1') and staff_id in (select user_id from sys_staff where status != '-1')
</select> </select>
<select id="getAttendanceHour" resultType="java.util.Map">
select sum(work_sum) as workSum,sum(night_number) as nightNumber,sum(middle_shift_number) as middleShiftNumber,staff_id as staffId,name
from rz_attendance
where del_flag = '0' and DATE_FORMAT(attendance_date,"%y-%m") = DATE_FORMAT(#{date},"%y-%m") GROUP BY staff_id, name
</select>
</mapper> </mapper>

View File

@ -95,9 +95,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{id} where id = #{id}
</update> </update>
<select id="selectRzSpecialAttendanceByuserIdAndDate" resultMap="RzSpecialAttendanceResult"> <select id="selectRzSpecialAttendanceByUserIdAndDate" resultMap="RzSpecialAttendanceResult">
<include refid="selectRzSpecialAttendanceVo"/> <include refid="selectRzSpecialAttendanceVo"/>
where del_flag = '0' and staff_id = #{staffId} and date_format(attendance_date,'%y%M%d') = date_format(#{date},'%y%M%d') where del_flag = '0' and staff_id = #{staffId} and date_format(work_start_time,'%y%M%d') = date_format(#{date},'%y%M%d') and work_end_time is null
<!-- where del_flag = '0' and staff_id = #{staffId} and date_format(attendance_date,'%y%M%d') = date_format(#{date},'%y%M%d') -->
</select> </select>
<select id="getSpecialAttendanceHour" resultType="java.util.Map">
select sum(work_hours) as workHours,staff_id as staffId,name
from rz_special_attendance
where del_flag = '0' and DATE_FORMAT(work_start_time,"%y-%m") = DATE_FORMAT(#{date},"%y-%m") GROUP BY staff_id, name
</select>
</mapper> </mapper>

View File

@ -27,6 +27,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
del_flag = '0' del_flag = '0'
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if> <if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
</where> </where>
order by num asc
</select> </select>
<select id="selectEqButtonById" parameterType="Long" resultMap="EqButtonResult"> <select id="selectEqButtonById" parameterType="Long" resultMap="EqButtonResult">

View File

@ -101,4 +101,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where l.id = d.leave_id and l.dept_id = #{deptId} and l.name = #{name} and DATE_FORMAT( l.leave_date, '%Y%m' ) = DATE_FORMAT(Now() , '%Y%m' ) and l.del_flag = '0' where l.id = d.leave_id and l.dept_id = #{deptId} and l.name = #{name} and DATE_FORMAT( l.leave_date, '%Y%m' ) = DATE_FORMAT(Now() , '%Y%m' ) and l.del_flag = '0'
</select> </select>
<select id="selectRzLeaveDetailByUserIdAndDate" resultMap="RzLeaveDetailResult">
select d.*
from rz_leave_detail d left join rz_leave l on d.leave_id = l.id,
where l.user_id = #{userId}
and l.del_flag = '0'
and DATE_FORMAT( d.leave_start_time, '%Y%m%d' ) &lt;= DATE_FORMAT(#{date} , '%Y%m%d' )
and DATE_FORMAT( d.leave_end_time, '%Y%m%d' ) &gt;= DATE_FORMAT(#{date} , '%Y%m%d' )
</select>
<select id="getLeaveHour" resultType="java.util.Map">
SELECT l.user_id as staffId, sum(JSON_EXTRACT(ld.extension,CONCAT('$.',CONCAT("hours",DATE_FORMAT(#{date},'%m'))))) as leaveHour
FROM `rz_leave_detail` ld left join rz_leave l on l.id = ld.leave_id
where JSON_EXTRACT(extension,CONCAT('$.',CONCAT("month",DATE_FORMAT(#{date},'%m'))))=DATE_FORMAT(#{date},'%m-%d')
GROUP BY l.user_id
</select>
</mapper> </mapper>

View File

@ -89,6 +89,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectRzOverTimeDetailVo"/> <include refid="selectRzOverTimeDetailVo"/>
where where
del_flag = '0' and over_time_id = #{overId} and DATE_FORMAT(over_time_start, '%Y%m%d' ) = DATE_FORMAT(#{date} , '%Y%m%d' ) del_flag = '0' and over_time_id = #{overId} and DATE_FORMAT(over_time_start, '%Y%m%d' ) = DATE_FORMAT(#{date} , '%Y%m%d' )
order by over_time_start desc limit 1
</select> </select>
<!-- 根据加班统计ID查询加班情况 --> <!-- 根据加班统计ID查询加班情况 -->
<select id="queryRzOverTimeDetailByOverId" resultMap="RzOverTimeDetailResult"> <select id="queryRzOverTimeDetailByOverId" resultMap="RzOverTimeDetailResult">
@ -97,4 +98,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
del_flag = '0' and over_time_id = #{overId} del_flag = '0' and over_time_id = #{overId}
</select> </select>
<select id="getLastRzOverTimeDetailByUserIdAndNotId" resultMap="RzOverTimeDetailResult">
select otd.*
from rz_over_time_detail otd
left join rz_over_time ot on ot.id=otd.over_time_id
where
otd.del_flag = '0' and ot.user_id = #{userId}
<if test="notId != null"> and otd.id != #{notId}</if>
order by otd.create_time desc
</select>
<select id="getOverTimeHour" resultType="java.util.Map">
select sum(otd.over_time_hours) as overTimeHours,ot.user_id as staffId,ot.name
from rz_over_time_detail otd
left join rz_over_time ot on ot.id=otd.over_time_id
where otd.del_flag = '0' and DATE_FORMAT(otd.over_time_start,"%y-%m") = DATE_FORMAT(#{date},"%y-%m") GROUP BY ot.user_id, ot.name
</select>
</mapper> </mapper>

View File

@ -52,7 +52,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap> </resultMap>
<sql id="selectSysStaffVo"> <sql id="selectSysStaffVo">
select user_id,company_name, dept_id, code, name, id_card,is_leader, sex, age, phone, address, level, major, school, bank_number,social_subsidy, bank, employment_date, experience, worker_term, regular_date, quit_date, contract_start, contract_end, contract_type, social_type, seniority, is_overtime_pay, zs_flag, secrecy, injury, insurance, introducer, clock_in, status, wages_ratio_date, remarks, del_flag, create_by, create_time, update_by, update_time, image_url from sys_staff select user_id,company_name, dept_id, code, name, id_card,is_leader, sex, age, phone, address, level, major, school, bank_number,social_subsidy, bank, employment_date, experience, worker_term, regular_date, quit_date, contract_start, contract_end, contract_type, social_type, seniority, is_overtime_pay, zs_flag, secrecy, injury, insurance, introducer, clock_in, status, wages_ratio_date, remarks, del_flag, create_by, create_time, update_by, update_time, image_url,time_clock from sys_staff
</sql> </sql>
<select id="selectSysStaffList" parameterType="com.evo.system.domain.SysStaff" resultMap="SysStaffResult"> <select id="selectSysStaffList" parameterType="com.evo.system.domain.SysStaff" resultMap="SysStaffResult">