打卡和考勤调整

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>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<version>15.4</version>
</dependency>
</dependencies>
<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.page.TableDataInfo;
import com.evo.common.enums.BusinessType;
import com.evo.common.utils.StringUtils;
import com.evo.common.utils.poi.ExcelUtil;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.service.IRzAttendanceStatisticalService;
@ -81,7 +82,10 @@ public class RzAttendanceStatisticalController extends BaseController
@RequestMapping(value = "correct")
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')")

View File

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

View File

@ -3,6 +3,7 @@ package com.evo.attendance.domain;
import com.evo.common.annotation.Excel;
import com.evo.common.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -14,6 +15,7 @@ import java.util.Date;
* @author chenyj
* @date 2024-09-14
*/
@Data
public class RzAttendanceDetail extends BaseEntity
{
private static final long serialVersionUID = 1L;
@ -25,6 +27,10 @@ public class RzAttendanceDetail extends BaseEntity
@Excel(name = "用户id")
private Long staffId;
/** 考勤记录Id */
@Excel(name = "考勤记录Id")
private Long attendanceId;
/** 姓名 */
@Excel(name = "姓名")
private String name;
@ -47,79 +53,6 @@ public class RzAttendanceDetail extends BaseEntity
/** 删除标记 */
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
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -1,8 +1,11 @@
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.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.math.BigDecimal;
@ -15,6 +18,7 @@ import java.util.List;
* @author chenyj
* @date 2024-09-05
*/
@Data
public class RzAttendanceStatistical extends BaseEntity
{
private static final long serialVersionUID = 1L;
@ -33,9 +37,10 @@ public class RzAttendanceStatistical extends BaseEntity
/** 所属部门 */
private Long deptId;
@TableField(exist = false)
private List<Long> deptIds;
@Excel(name = "所属部门")
@TableField(exist = false)
private String deptName;
/** 员工姓名 */
@ -62,7 +67,7 @@ public class RzAttendanceStatistical extends BaseEntity
@Excel(name = "请假时长(小时)")
private BigDecimal absenteeism;
/** 请假时长(小时) */
/** 特殊加班(小时) */
@Excel(name = "特殊加班(小时)")
private BigDecimal overTimeHours;
@ -87,176 +92,10 @@ public class RzAttendanceStatistical extends BaseEntity
private Long middleShiftNumber;
/** 删除标识 */
@TableField(fill = FieldFill.INSERT)
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
public String toString() {

View File

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

View File

@ -1,28 +1,28 @@
package com.evo.attendance.domain.vo;
import lombok.Data;
@Data
public class RzAttendanceVo {
private int Result;
private String Msg;
private RzAttendanceData Content;
public int getResult() {
return Result;
public RzAttendanceVo() {
}
public void setResult(int result) {
public RzAttendanceVo(int result, String msg) {
Result = result;
}
public String getMsg() {
return Msg;
}
public void setMsg(String msg) {
Msg = msg;
}
public RzAttendanceData getContent() {
return Content;
}
public void setContent(RzAttendanceData content) {
public RzAttendanceVo(int result, String msg, RzAttendanceData content) {
Result = result;
Msg = msg;
Content = content;
}
@Override
public String toString() {
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);
/**
* 查询员工最后一次上班打卡 计算工时
* 查询员工最后一次上班打卡 计算工时 其他地方不可使用
*
* @param staffId
* @return 考勤明细集合
*/
public default RzAttendanceDetail selectRzAttendanceDetailByStaffId(@Param("staffId") Long staffId) {
return null;
}
public RzAttendanceDetail selectRzAttendanceDetailByStaffId(@Param("staffId") Long staffId);
public List<RzAttendanceDetail> selectRzAttendanceDetailByMonth(Date date);
}

View File

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

View File

@ -1,10 +1,12 @@
package com.evo.attendance.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.attendance.domain.RzSpecialAttendance;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 加班考勤记录Mapper接口
@ -12,7 +14,7 @@ import java.util.List;
* @author evo
* @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 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
*/
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.evo.attendance.domain.*;
import com.evo.attendance.mapper.*;
import com.evo.attendance.processor.PunchTheClockStrategyExchangeProcessor;
import com.evo.common.constant.Constants;
import com.evo.common.utils.Collections;
import com.evo.common.utils.DateUtils;
import com.evo.common.utils.StringUtils;
import com.evo.equipment.domain.EqButton;
import com.evo.equipment.domain.EqImages;
import com.evo.equipment.mapper.EqButtonMapper;
import com.evo.equipment.mapper.EqImagesMapper;
import com.evo.attendance.domain.vo.RzAttendanceData;
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.SysStaffMapper;
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.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
public class PunchTheClockServiceImpl implements PunchTheClockService {
@Resource
private EqButtonMapper eqButtonMapper;
@Resource
private EqImagesMapper eqImagesMapper; //照片管理
@Resource
@ -58,6 +70,8 @@ public class PunchTheClockServiceImpl implements PunchTheClockService {
private BsOverTimeMapper bsOverTimeMapper;
@Resource
private RzSpecialOverTimeMapper rzSpecialOverTimeMapper;
@Autowired
private ApplicationContext applicationContext;
/**
* 刷脸获取打卡按钮权限
* sn 设备号
@ -84,93 +98,124 @@ public class PunchTheClockServiceImpl implements PunchTheClockService {
JSONObject jsonObject = JSONObject.parseObject(json);
String userId = jsonObject.getString("user_id");
//需要推送的数据
String 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;
Map<String, PunchTheClockStrategyExchangeProcessor> mqttRequestExchangeProcessorMap = applicationContext.getBeansOfType(PunchTheClockStrategyExchangeProcessor.class);
for (PunchTheClockStrategyExchangeProcessor processor : mqttRequestExchangeProcessorMap.values()) {
if(processor.accept(sn)){
return processor.exchangeButton(userId, sn);
}
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;
return initMessage(1,"未找到打卡机信息", "000000000");
/***
* PS: 注解为原代码逻辑
* //解析收到的数据
* JSONObject jsonObject = JSONObject.parseObject(json);
* String userId = jsonObject.getString("user_id");
* //需要推送的数据
* String 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查询当前员工不是员工列表中的人返回提示
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;
return JSONObject.toJSONString(new RzAttendanceVo(result, meg));
}
/**
* 用户点击打卡按钮后请求的接口
@ -205,359 +250,392 @@ public class PunchTheClockServiceImpl implements PunchTheClockService {
date = sdf.parse(jsonObject.getString("recog_time"));
}catch (Exception e){
e.printStackTrace();
return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
return initMessage(1,"打卡失败");
}
String rules = ""; //打卡规则
String button = jsonObject.getString("button");
switch (button){
case "1":
rules = "上班卡(单班制)";
break;
case "2":
rules = "上班卡(双班制)";
break;
case "3":
rules = "上班卡(三班制)";
break;
case "4":
rules = "加班卡";
break;
case "5":
rules = "下班卡";
break;
default:
rules = "撤销";
break;
List<EqButton> bt_list = eqButtonMapper.selectEqButtonList(null);
if(Collections.isEmpty(bt_list)){
return initMessage(1,"打卡失败");
}
//根据顺序获取打卡规则
EqButton eqButton = bt_list.get(Integer.parseInt(button)-1);
String rules = eqButton.getName(); //打卡规则
//判断是打特殊加班卡
if(com.evo.equipment.constant.Constants.EQ_DEVICE_OVER_TIME_CODE.equals(sn)){
RzSpecialAttendance rzSpecialAttendance = null;
SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));
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\":\"打卡失败\"}";
}
Map<String, PunchTheClockStrategyExchangeProcessor> mqttRequestExchangeProcessorMap = applicationContext.getBeansOfType(PunchTheClockStrategyExchangeProcessor.class);
for (PunchTheClockStrategyExchangeProcessor processor : mqttRequestExchangeProcessorMap.values()) {
if(processor.accept(sn)){
return processor.exchangeFace(userId, sn, date, button, rules);
}
}
return initMessage(1,"打卡失败");
//根据ID查询员工信息 ,判断员工是否存在不存在返回失败
SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));//打卡记录信息
if(sysStaff == null){
return "{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}";
}
//获取员工的工作时长
EqImages eqImages = eqImagesMapper.selectEqImagesByStaffId(Long.valueOf(userId));
//打卡明细
RzAttendanceDetail attendanceDetail = new RzAttendanceDetail();
//打卡明细表中插入数据
attendanceDetail.setButtonType(rules);
attendanceDetail.setName(sysStaff.getName());
attendanceDetail.setDateTime(date);
attendanceDetail.setDelFlag(Constants.DELETE_FLAG_0);
attendanceDetail.setStaffId(Long.valueOf(userId));
attendanceDetail.setEquipmentCode(sn);
attendanceDetail.setCreateTime(new Date());
int i = rzAttendanceDetailMapper.insertRzAttendanceDetail(attendanceDetail);
if(i < 1){
return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
}
//考勤加班统计
RzOverTime rzOverTime = null;
RzOverTimeDetail rzOverTimeDetail = null;
//打的是加班卡加班列表中填写数据
if("4".equals(button)){
//判断打卡月是否统计过加班
rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.valueOf(userId),date);
if(rzOverTime == null){
rzOverTime = new RzOverTime();
rzOverTime.setUserId(Long.valueOf(userId));
rzOverTime.setOverHours(new BigDecimal("0.0"));
rzOverTime.setDeptId(sysStaff.getDeptId());
rzOverTime.setName(sysStaff.getName());
rzOverTime.setOverTimeMonth(date);
rzOverTime.setDelFlag(Constants.DELETE_FLAG_0);
rzOverTime.setCreateBy("admin");
rzOverTime.setCreateTime(DateUtils.getNowDate());
i = rzOverTimeMapper.insertRzOverTime(rzOverTime);
if(i < 1){
return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
}
}
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());
i = rzOverTimeDetailMapper.insertRzOverTimeDetail(rzOverTimeDetail);
if(i < 1){
return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
}
return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
}
//员工考勤记录
RzAttendance attendance = rzAttendanceMapper.queryNowDayAttendanceByStatisticalIdAndDate(Long.valueOf(userId),date);
//判断是撤销卡
if("6".equals(button)){
attendance.setRules("");
i = rzAttendanceMapper.updateRzAttendance(attendance);
if(i < 1){
return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
}
return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
}
//判断是上班卡
if("1".equals(button) || "2".equals(button) || "3".equals(button)){
if(StringUtils.isNotNull(attendance.getWorkStartTime())){
attendance.setRules(rules);
}else{
attendance.setRules(rules);
attendance.setWorkStartTime(date);
}
try{
//判断三种上班卡
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");
if("上班卡(单班制)".equals(rules) && date.after(db_pre)
|| ("上班卡(双班制)".equals(rules) && ((date.after(db_pre) && date.getHours() < 12) || (date.after(sb_pre) && date.getHours() <21)))
|| ("上班卡(三班制)".equals(rules) && ((date.after(db_pre) && date.getHours() < 12) || (date.after(sbz_pre) && date.getHours() < 24)))){
attendance.setYcsFlag("1");
}
}catch (Exception e){
e.printStackTrace();
}
i = rzAttendanceMapper.updateRzAttendance(attendance);
if(i < 1){
return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
}
return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
}
// 查询员工的最后一次上班打卡信息
RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectRzAttendanceDetailByStaffId(Long.valueOf(userId));
//下班卡
//最后一次打卡为加班卡 跨月加班按上个月加班计算
if("加班卡".equals(rzAttendanceDetail.getButtonType())){
//修改加班打卡记录 根据员工ID和时间查找 统计数据
rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.valueOf(userId),rzAttendanceDetail.getDateTime());
//查找加班详情 加班统计ID和加班开始时间
rzOverTimeDetail = rzOverTimeDetailMapper.queryRzOverTimeDetailByDateAndOverId(rzOverTime.getId(),rzAttendanceDetail.getDateTime());
rzOverTimeDetail.setOverTimeEnd(date);
//计算加班时长 小时
double hours = (rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60/60;
if(hours > 4){
rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(4));
}else{
rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(hours));
}
i = rzOverTimeDetailMapper.updateRzOverTimeDetail(rzOverTimeDetail);
if(i < 1){
return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
}
//加班修改统计
rzOverTime.setOverHours(rzOverTime.getOverHours().add(rzOverTimeDetail.getOverTimeHours()));
i = rzOverTimeMapper.updateRzOverTime(rzOverTime);
if(i < 1){
return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
}
//反写考勤汇总
RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(Long.valueOf(userId),rzOverTime.getOverTimeMonth());
rzAttendanceStatistical.setWorkOvertimeNumber(rzOverTime.getOverHours());
i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical);
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\":\"打卡成功\"}";
/***
* PS: 注解为原代码逻辑
* //解析收到的数据
* JSONObject jsonObject = JSONObject.parseObject(json);
* String userId = jsonObject.getString("user_id");
* String sn = jsonObject.getString("sn");
* SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
* SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd");
* Date date = null; //打卡时间
* try{
* date = sdf.parse(jsonObject.getString("recog_time"));
* }catch (Exception e){
* e.printStackTrace();
* return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* String rules = ""; //打卡规则
* String button = jsonObject.getString("button");
* switch (button){
* case "1":
* rules = "上班卡(单班制)";
* break;
* case "2":
* rules = "上班卡(双班制)";
* break;
* case "3":
* rules = "上班卡(三班制)";
* break;
* case "4":
* rules = "加班卡";
* break;
* case "5":
* rules = "下班卡";
* break;
* default:
* rules = "撤销";
* break;
* }
*
* //判断是打特殊加班卡
* if(com.evo.equipment.constant.Constants.EQ_DEVICE_OVER_TIME_CODE.equals(sn)){
* RzSpecialAttendance rzSpecialAttendance = null;
* SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));
* 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\":\"打卡失败\"}";
* }
* }
* }
*
* //根据ID查询员工信息 ,判断员工是否存在不存在返回失败
* SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));//打卡记录信息
* if(sysStaff == null){
* return "{\"Result\":1,\"Msg\":\"验证失败,未设置考勤权限\"}";
* }
* //获取员工的工作时长
* EqImages eqImages = eqImagesMapper.selectEqImagesByStaffId(Long.valueOf(userId));
* //打卡明细
* RzAttendanceDetail attendanceDetail = new RzAttendanceDetail();
* //打卡明细表中插入数据
* attendanceDetail.setButtonType(rules);
* attendanceDetail.setName(sysStaff.getName());
* attendanceDetail.setDateTime(date);
* attendanceDetail.setDelFlag(Constants.DELETE_FLAG_0);
* attendanceDetail.setStaffId(Long.valueOf(userId));
* attendanceDetail.setEquipmentCode(sn);
* attendanceDetail.setCreateTime(new Date());
* int i = rzAttendanceDetailMapper.insertRzAttendanceDetail(attendanceDetail);
* if(i < 1){
* return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* //考勤加班统计
* RzOverTime rzOverTime = null;
* RzOverTimeDetail rzOverTimeDetail = null;
*
* //打的是加班卡加班列表中填写数据
* if("4".equals(button)){
* //判断打卡月是否统计过加班
* rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.valueOf(userId),date);
* if(rzOverTime == null){
* rzOverTime = new RzOverTime();
* rzOverTime.setUserId(Long.valueOf(userId));
* rzOverTime.setOverHours(new BigDecimal("0.0"));
* rzOverTime.setDeptId(sysStaff.getDeptId());
* rzOverTime.setName(sysStaff.getName());
* rzOverTime.setOverTimeMonth(date);
* rzOverTime.setDelFlag(Constants.DELETE_FLAG_0);
* rzOverTime.setCreateBy("admin");
* rzOverTime.setCreateTime(DateUtils.getNowDate());
* i = rzOverTimeMapper.insertRzOverTime(rzOverTime);
* if(i < 1){
* return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* }
* 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());
* i = rzOverTimeDetailMapper.insertRzOverTimeDetail(rzOverTimeDetail);
* if(i < 1){
* return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
* }
*
* //员工考勤记录
* RzAttendance attendance = rzAttendanceMapper.queryNowDayAttendanceByStatisticalIdAndDate(Long.valueOf(userId),date);
* //判断是撤销卡
* if("6".equals(button)){
* attendance.setRules("");
* i = rzAttendanceMapper.updateRzAttendance(attendance);
* if(i < 1){
* return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
* }
*
* //判断是上班卡
* if("1".equals(button) || "2".equals(button) || "3".equals(button)){
* if(StringUtils.isNotNull(attendance.getWorkStartTime())){
* attendance.setRules(rules);
* }else{
* attendance.setRules(rules);
* attendance.setWorkStartTime(date);
* }
* try{
* //判断三种上班卡
* 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");
* if("上班卡(单班制)".equals(rules) && date.after(db_pre)
* || ("上班卡(双班制)".equals(rules) && ((date.after(db_pre) && date.getHours() < 12) || (date.after(sb_pre) && date.getHours() <21)))
* || ("上班卡(三班制)".equals(rules) && ((date.after(db_pre) && date.getHours() < 12) || (date.after(sbz_pre) && date.getHours() < 24)))){
* attendance.setYcsFlag("1");
* }
* }catch (Exception e){
* e.printStackTrace();
* }
* i = rzAttendanceMapper.updateRzAttendance(attendance);
* if(i < 1){
* return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* return "{\"Result\":0,\"Msg\":\"打卡成功\"}";
* }
*
* // 查询员工的最后一次上班打卡信息
* RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectRzAttendanceDetailByStaffId(Long.valueOf(userId));
*
* //下班卡
* //最后一次打卡为加班卡 跨月加班按上个月加班计算
* if("加班卡".equals(rzAttendanceDetail.getButtonType())){
* //修改加班打卡记录 根据员工ID和时间查找 统计数据
* rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(Long.valueOf(userId),rzAttendanceDetail.getDateTime());
* //查找加班详情 加班统计ID和加班开始时间
* rzOverTimeDetail = rzOverTimeDetailMapper.queryRzOverTimeDetailByDateAndOverId(rzOverTime.getId(),rzAttendanceDetail.getDateTime());
* rzOverTimeDetail.setOverTimeEnd(date);
* //计算加班时长 小时
* double hours = (rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60/60;
* if(hours > 4){
* rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(4));
* }else{
* rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(hours));
* }
*
* i = rzOverTimeDetailMapper.updateRzOverTimeDetail(rzOverTimeDetail);
* if(i < 1){
* return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* //加班修改统计
* rzOverTime.setOverHours(rzOverTime.getOverHours().add(rzOverTimeDetail.getOverTimeHours()));
* i = rzOverTimeMapper.updateRzOverTime(rzOverTime);
* if(i < 1){
* return "{\"Result\":1,\"Msg\":\"打卡失败\"}";
* }
* //反写考勤汇总
* RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(Long.valueOf(userId),rzOverTime.getOverTimeMonth());
* rzAttendanceStatistical.setWorkOvertimeNumber(rzOverTime.getOverHours());
* i = rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical);
* 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.SecurityUtils;
import com.evo.common.utils.StringUtils;
import com.evo.personnelMatters.domain.RzLeaveDetail;
import com.evo.personnelMatters.mapper.RzLeaveDetailMapper;
import com.evo.utils.DateUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -44,7 +47,9 @@ public class RzAbnormalDetailServiceImpl implements IRzAbnormalDetailService
@Resource
private RzAbnormalMapper rzAbnormalMapper; //异常汇总
@Resource
private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //考勤统计
private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper; //考勤统计
@Resource
private RzLeaveDetailMapper rzLeaveDetailMapper;
/**
* 查询考勤异常详情
*
@ -68,30 +73,6 @@ public class RzAbnormalDetailServiceImpl implements IRzAbnormalDetailService
{
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 结果
@ -101,16 +82,27 @@ public class RzAbnormalDetailServiceImpl implements IRzAbnormalDetailService
//获取所有人的考勤信息
List<RzAttendance> res_list = rzAttendanceMapper.currentDateAllAttendance();
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) {
//判断是否为假期
if(isHoliday){
//如果是假期, 有打卡, 标识为加班, 没有打卡标识为公休
//判断未打卡, 做加班还是公休备注
rzAttendance.setRemarks((rzAttendance.getWorkStartTime() == null ? "公休": "加班"));
rzAttendanceMapper.updateRzAttendance(rzAttendance);
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)){
//判断员工当月是否存在异常情况

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

View File

@ -1,29 +1,37 @@
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.evo.attendance.domain.RzAttendance;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.mapper.RzAttendanceMapper;
import com.evo.attendance.mapper.RzAttendanceStatisticalMapper;
import com.evo.attendance.mapper.RzSpecialAttendanceMapper;
import com.evo.attendance.service.IRzAttendanceStatisticalService;
import com.evo.common.annotation.DataScope;
import com.evo.common.constant.Constants;
import com.evo.common.core.domain.AjaxResult;
import com.evo.common.core.domain.entity.SysDept;
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.RzOverTimeDetail;
import com.evo.personnelMatters.mapper.RzLeaveDetailMapper;
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 org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.beans.Transient;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
* 考勤统计Service业务层处理
@ -40,6 +48,13 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
private RzAttendanceMapper rzAttendanceMapper; //打卡记录
@Resource
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
@Transient
public RzAttendanceStatistical createRzAttendance(SysStaff sysStaff, List<String> dayList, Date date) {
if(date == null){
date = DateUtils.getNowDate();
@ -173,11 +189,8 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
rzAttendanceStatistical.setMonth(date);
rzAttendanceStatistical.setShouldAttendance(new BigDecimal(ParamUtils.getMonthWorkDayNum(getMonthWorkDayNum(date))).multiply(new BigDecimal("8.00")));
rzAttendanceStatistical.setDeptId(sysStaff.getDeptId());
rzAttendanceStatistical.setDelFlag(Constants.DELETE_FLAG_0);
rzAttendanceStatistical.setCreateBy(SecurityUtils.getUsername());
rzAttendanceStatistical.setCreateTime(date);
rzAttendanceStatistical.setAbsenteeism(new BigDecimal(0));
getBaseMapper().insertRzAttendanceStatistical(rzAttendanceStatistical);
getBaseMapper().insert(rzAttendanceStatistical);
//新增考勤详情
SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd");
RzAttendance rzAttendance = null;
@ -194,7 +207,7 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
}
rzAttendance.setDelFlag(Constants.DELETE_FLAG_0);
rzAttendance.setCreateTime(DateUtils.getNowDate());
rzAttendance.setCreateBy(SecurityUtils.getUsername());
rzAttendance.setCreateBy("admin");
pa_list.add(rzAttendance);
}
rzAttendanceMapper.insertBatchRzAttendance(pa_list);
@ -202,6 +215,65 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
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){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);

View File

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

View File

@ -223,6 +223,21 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
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){
Calendar currentDate = Calendar.getInstance();
@ -234,6 +249,15 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
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) {
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.system.service.ISysDictDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
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","需要自动计算请假时长的请假类型, 多个参数使用,隔开");
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.core.domain.BaseEntity;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -11,6 +12,7 @@ import org.apache.commons.lang3.builder.ToStringStyle;
* @author chenyj
* @date 2024-08-15
*/
@Data
public class EqButton extends BaseEntity
{
private static final long serialVersionUID = 1L;
@ -26,6 +28,11 @@ public class EqButton extends BaseEntity
@Excel(name = "按钮名称")
private String name;
/***
* 工作时长
*/
private Integer workHour;
/** 图标地址 */
@Excel(name = "图标地址")
private String image;
@ -37,61 +44,6 @@ public class EqButton extends BaseEntity
@Excel(name = "备注")
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
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -1,5 +1,6 @@
package com.evo.equipment.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.equipment.domain.EqButton;
import java.util.List;
@ -10,7 +11,7 @@ import java.util.List;
* @author chenyj
* @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));
String url = ParamUtils.getGlobalStaticUrl();
for(SysStaff user : userList){
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()));
try {
// 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;
}
@ -255,7 +260,7 @@ public class EqSnDetailServiceImpl extends ServiceImpl<EqSnDetailMapper, EqSnDet
public Boolean sendButtons(List<String> 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();
CwButtonData cbd = new CwButtonData();
cbv.setCmd("to_device");
@ -278,8 +283,7 @@ public class EqSnDetailServiceImpl extends ServiceImpl<EqSnDetailMapper, EqSnDet
}
@Override
public void checkDevice() {
List<String> sessionIds = WebSocketUsers.getUsers().keySet().stream().collect(Collectors.toList());
update(new UpdateWrapper<EqSnDetail>().set("type","连接已断开").notIn(Collections.isNotEmpty(sessionIds), "session_id", sessionIds));
public void checkDevice(String sessionId) {
update(new UpdateWrapper<EqSnDetail>().set("type","连接已断开").set("session_id","").eq( "session_id", sessionId));
}
}

View File

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

View File

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

View File

@ -1,5 +1,7 @@
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.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
@ -47,6 +49,7 @@ public class RzOverTime extends BaseEntity
private BigDecimal taskHours;
/** 删除标识 */
@TableField(fill = FieldFill.INSERT)
private String delFlag;

View File

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

View File

@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.personnelMatters.domain.RzLeaveDetail;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 请假管理详情Mapper接口
@ -63,4 +65,14 @@ public interface RzLeaveDetailMapper extends BaseMapper<RzLeaveDetail>
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;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.personnelMatters.domain.RzOverTimeDetail;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 加班详情Mapper接口
@ -11,7 +13,7 @@ import java.util.List;
* @author chenyj
* @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);
/**
* 根据加班统计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;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.common.constant.Constants;
import com.evo.common.core.domain.AjaxResult;
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.RzOverTimeMapper;
import com.evo.personnelMatters.service.IRzLeaveDetailService;
import com.evo.system.domain.SysStaff;
import com.evo.system.service.ISysDictDataService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -23,8 +26,12 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 请假管理详情Service业务层处理
@ -129,19 +136,7 @@ public class RzLeaveDetailServiceImpl extends ServiceImpl<RzLeaveDetailMapper, R
}
//不再反写考勤汇总, 由定时器, 每天执行查找
//这里需要做特殊处理, 如果时间范围跨月了, 需要每个月的考勤都要处理
// Integer betweenMonth = DateUtils.getBetweenMonth(rzLeaveDetail.getLeaveStartTime(), rzLeaveDetail.getLeaveEndTime());
// 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);
// }
buildExtension(rzLeaveDetail);
return AjaxResult.success();
}
@ -150,6 +145,59 @@ public class RzLeaveDetailServiceImpl extends ServiceImpl<RzLeaveDetailMapper, R
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;
//
//查询加班时长, 核实当前
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){
rzOverTime.setTaskHours(rzOverTime.getTaskHours().add(new BigDecimal(hours)));
return overTimeMapper.updateById(rzOverTime) > 0;
@ -207,7 +255,7 @@ public class RzLeaveDetailServiceImpl extends ServiceImpl<RzLeaveDetailMapper, R
//如果小于0 并且是调休, 需要反加加班
//验证调休
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.setTaskHours(rzOverTime.getTaskHours().subtract(new BigDecimal(Math.abs(newHolidayHour))));
overTimeMapper.updateById(rzOverTime);

View File

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

View File

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

View File

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

View File

@ -1,6 +1,9 @@
package com.evo.task;
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.restaurant.service.IRzRestaurantStatisticsService;
import com.evo.system.service.ISysStaffService;
@ -8,6 +11,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
@Component
public class TaskController {
@ -19,8 +23,7 @@ public class TaskController {
@Resource
private IRzAbnormalDetailService abnormalDetailService;
@Resource
private IEqSnDetailService eqSnDetailService; //异常卡
private IRzAttendanceStatisticalService rzAttendanceStatisticalService;
/**
* 每月1号 020 自动生成考勤数据
*/
@ -35,6 +38,16 @@ public class TaskController {
public void 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 计算转正,离职日期
*/
@ -44,7 +57,7 @@ public class TaskController {
};
/**
* 每天2300 计算当天的异常
* 每天2300 核验考勤情况, 异常
*/
//@Scheduled(cron = "0 0/30 * * * ?")
@Scheduled(cron = "0 0 23 * * ?")
@ -52,19 +65,20 @@ public class TaskController {
abnormalDetailService.insertRzAbnormalDetail();
}
/**
* 每月10号2点自动计算工龄
*/
@Scheduled(cron = "0 0 2 10 * ?")
public void calculationOfSeniority(){
sysStaffService.calculationOfSeniority();
}
// /**
// * 每月10号2点自动计算工龄
// */
// @Scheduled(cron = "0 0 2 10 * ?")
// public void 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' )
and staff_id in (select user_id from sys_staff where status != '-1')
</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>

View File

@ -95,9 +95,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where id = #{id}
</update>
<select id="selectRzSpecialAttendanceByuserIdAndDate" resultMap="RzSpecialAttendanceResult">
<select id="selectRzSpecialAttendanceByUserIdAndDate" resultMap="RzSpecialAttendanceResult">
<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 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>

View File

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

View File

@ -89,6 +89,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectRzOverTimeDetailVo"/>
where
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>
<!-- 根据加班统计ID查询加班情况 -->
<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}
</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>

View File

@ -52,7 +52,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<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>
<select id="selectSysStaffList" parameterType="com.evo.system.domain.SysStaff" resultMap="SysStaffResult">