From e75014aaa739b0225df6311f7f38359c64e84c73 Mon Sep 17 00:00:00 2001 From: andy <1042025947@qq.com> Date: Tue, 1 Jul 2025 10:54:29 +0800 Subject: [PATCH] =?UTF-8?q?1.=E6=89=93=E5=8D=A1=E9=97=AD=E7=8E=AF=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E4=B8=80=E5=A4=A9=E5=8F=AF=E4=BB=A5=E6=89=93?= =?UTF-8?q?=E5=A4=9A=E6=AC=A1=E5=8D=A1=EF=BC=8C=E4=B8=80=E5=A4=A9=E5=8F=AA?= =?UTF-8?q?=E6=9C=89=E4=B8=80=E6=AC=A1=E6=89=93=E4=B8=8A=E4=B8=8B=E7=8F=AD?= =?UTF-8?q?=E5=8F=8A=E5=8A=A0=E7=8F=AD=E5=8D=A1=202.=E8=80=83=E5=8B=A4?= =?UTF-8?q?=E5=87=BA=E7=8E=B0=E6=BC=8F=E6=89=93=E5=8D=A1=EF=BC=8C=E6=AC=A1?= =?UTF-8?q?=E6=97=A5=E5=8F=AF=E4=BB=A5=E6=AD=A3=E5=B8=B8=E6=89=93=E5=8D=A1?= =?UTF-8?q?=EF=BC=888=E5=B0=8F=E6=97=B6=E5=88=B6=E5=91=98=E5=B7=A5?= =?UTF-8?q?=EF=BC=89=E3=80=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/KQDeviceExchangeProcessor.java | 61 ++++++++++++++++--- .../system/utils/SubsidyCalculationUtils.java | 9 ++- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/evo-admin/src/main/java/com/evo/attendance/processor/impl/KQDeviceExchangeProcessor.java b/evo-admin/src/main/java/com/evo/attendance/processor/impl/KQDeviceExchangeProcessor.java index f32ade7..c4e2efb 100644 --- a/evo-admin/src/main/java/com/evo/attendance/processor/impl/KQDeviceExchangeProcessor.java +++ b/evo-admin/src/main/java/com/evo/attendance/processor/impl/KQDeviceExchangeProcessor.java @@ -7,24 +7,23 @@ 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.annotation.Log; import com.evo.common.constant.Constants; import com.evo.common.core.domain.entity.SysDept; import com.evo.common.utils.*; 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.domain.SysStaffDetail; import com.evo.system.mapper.SysDeptMapper; +import com.evo.system.mapper.SysStaffDetailMapper; import com.evo.system.mapper.SysStaffMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -61,7 +60,8 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP private EqOverStaffMapper eqOverStaffMapper; @Resource private SysDeptMapper sysDeptMapper; - + @Resource + private SysStaffDetailMapper sysStaffDetailMapper; @Override public boolean accept(String sn) { @@ -87,12 +87,15 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP if(!sn.equals(com.evo.equipment.constant.Constants.EQ_DEVICE_PUBLIC_CODE) && !sn.equals(sysStaff.getTimeClock())){ return initMessage(1,"未设置当前考勤机打卡权限", "000000000"); } + //检查当前打卡人是不是月薪, 如果是月薪 并且当天没有打卡, 则显示上班卡, 否则显示下班卡 + SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId()); + //查询员工的最后一次打卡 按钮切换 RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectLastRzAttendanceDetail(sysStaff.getUserId()); //判断最后一次打卡为下班卡或没有打卡记录,则打卡为上班卡 - if(StringUtils.isNull(rzAttendanceDetail) || "下班卡".equals(rzAttendanceDetail.getButtonType()) || "撤销".equals(rzAttendanceDetail.getButtonType())){ - //如果最后一条数据的卡类型为下班卡,则返回上班卡和加班卡权限 or 检查当前人员是否存在特殊加班中 或者 检查当前人员部门是否开启加班 or 当天打过加班卡 - if(ObjectUtils.isNotEmpty(eqOverStaffMapper.selectEqOverStaffByUserId(sysStaff.getUserId())) || ObjectUtils.isEmpty(sysDeptMapper.selectOne(new LambdaQueryWrapper().eq(SysDept::getDeptId, sysStaff.getDeptId()).eq(SysDept::getIsOverTime,"1"))) || rzAttendanceDetailMapper.checkOverTimeCard(sysStaff.getUserId(), new Date()) > 0){ + if(showButton(sysStaffDetail) || StringUtils.isNull(rzAttendanceDetail) || "下班卡".equals(rzAttendanceDetail.getButtonType()) || "撤销".equals(rzAttendanceDetail.getButtonType())){ + //如果最后一条数据的卡类型为下班卡,则返回上班卡和加班卡权限 or 检查当前人员是否存在特殊加班中 或者 检查当前人员部门是否开启加班 or 暂时取消这个判定 当天打过加班卡 ( || rzAttendanceDetailMapper.checkOverTimeCard(sysStaff.getUserId(), new Date()) > 0) + if(ObjectUtils.isNotEmpty(eqOverStaffMapper.selectEqOverStaffByUserId(sysStaff.getUserId())) || ObjectUtils.isEmpty(sysDeptMapper.selectOne(new LambdaQueryWrapper().eq(SysDept::getDeptId, sysStaff.getDeptId()).eq(SysDept::getIsOverTime,"1")))){ //如果存在特殊加班, 或者当前部门没有开启加班 或者当天打过加班, 则无法打加班卡 return initMessage(0,"验证通过", "111000000"); } @@ -102,10 +105,12 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP } } + public Boolean showButton(SysStaffDetail detail){ + return (detail.getBasicSalary() != null && detail.getBasicSalary().compareTo(new BigDecimal(0)) > 0) && (detail.getJobsSalary() != null && detail.getJobsSalary().compareTo(new BigDecimal(0)) > 0) && (!checkToDayCard(String.valueOf(detail.getStaffId()), "上班") && !checkToDayCard(String.valueOf(detail.getStaffId()),"加班")); + } @Override public String exchangeFace(String userId, String sn, Date date, String button, String rules) { - //根据ID查询员工信息 ,判断员工是否存在,不存在返回失败 SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(Long.valueOf(userId));//打卡记录信息 log.info("日常-打卡信息如下: 员工姓名:{}, 打卡时间:{}. 打卡设备:{}, 打卡情况: {}",sysStaff.getName(), sdfd.format(date), sn, rules); @@ -114,6 +119,21 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP if(StringUtils.isNotEmpty(error)){ return initMessage(1, error); } + /*** + * 应人力要求, + * 1.打卡闭环,不能一天可以打多次卡,一天只有一次打上下班及加班卡 + * 2.考勤出现漏打卡,次日可以正常打卡(8小时制员工)】 其中8小时制员工 为单班制打卡 + */ + //上班卡 + if(rules.contains("上班") && checkToDayCard(userId, "上班")){ + return initMessage(1, "当天已经打过上班卡"); + } + //上班卡 + if(rules.contains("加班") && checkToDayCard(userId, "加班")){ + return initMessage(1, "当天已经打过加班卡"); + } + + //员工考勤记录 RzAttendance attendance = rzAttendanceMapper.queryNowDayAttendanceByStatisticalIdAndDate(Long.valueOf(userId),date); //如果当前打卡是下班卡, 并且当前员工考勤上班时间为空, 则判定为隔天打下班卡 @@ -166,6 +186,15 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP return initMessage(1, "打卡失败"); } + public Boolean checkToDayCard(String userId, String rules){ + return ObjectUtils.isNotEmpty(rzAttendanceDetailMapper.selectOne(new LambdaQueryWrapper() + .like(RzAttendanceDetail::getButtonType,"%"+rules+"%") + .eq(RzAttendanceDetail::getStaffId, Long.valueOf(userId)) + .eq(RzAttendanceDetail::getDelFlag, Constants.DELETE_FLAG_0) + .apply(" date_format(date_time,'%Y%m%d') = date_format({0},'%Y%m%d') ", new Date()))); + } + + /*** 上班卡 * @param userId * @param date @@ -366,8 +395,24 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP public String overTimeOffDutyCard(SysStaff sysStaff , Date date, String sn){ //修改加班打卡记录 根据员工ID和时间查找 统计数据 RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeByNameAndMonth(sysStaff.getUserId(),date); + //如果没有加班汇总, 生成一条新的 + if(ObjectUtils.isEmpty(rzOverTime)){ + rzOverTime = new RzOverTime(); + rzOverTime.setUserId(sysStaff.getUserId()); + rzOverTime.setDeptId(sysStaff.getDeptId()); + rzOverTime.setName(sysStaff.getName()); + rzOverTime.setOverTimeMonth(date); + rzOverTime.setOverHours(DataUtils.DEFAULT_VALUE); + rzOverTime.setDelFlag(Constants.DELETE_FLAG_0); + rzOverTime.setCreateBy("admin"); + rzOverTime.setCreateTime(new Date()); + rzOverTimeMapper.insert(rzOverTime); + } //查找加班详情 加班统计ID和加班开始时间 RzOverTimeDetail rzOverTimeDetail = rzOverTimeDetailMapper.queryRzOverTimeDetailByDateAndOverId(rzOverTime.getId(),date); + if(ObjectUtils.isEmpty(rzOverTimeDetail)){ + return initMessage(1, "未找到当天的加班信息, 请补卡"); + } rzOverTimeDetail.setOverTimeEnd(date); //计算加班时长 分钟 BigDecimal minutes = new BigDecimal((rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60); diff --git a/evo-admin/src/main/java/com/evo/system/utils/SubsidyCalculationUtils.java b/evo-admin/src/main/java/com/evo/system/utils/SubsidyCalculationUtils.java index 47f2e2a..d8775c9 100644 --- a/evo-admin/src/main/java/com/evo/system/utils/SubsidyCalculationUtils.java +++ b/evo-admin/src/main/java/com/evo/system/utils/SubsidyCalculationUtils.java @@ -41,6 +41,8 @@ public class SubsidyCalculationUtils { public static final String xnh = "13"; public static final String yc = "11"; + public static final List tsbz = Collections.asList(ht,gl,xnh,yc); + public static SysStaffDetail subsidyCalculation(SysStaff staff, SysStaffDetail staffDetail, List subsidyInfoList){ //正式员工并且有补助信息 if(Constants.JOB_STATIS_1.equals(staff.getStatus())){ @@ -51,24 +53,27 @@ public class SubsidyCalculationUtils { Map map = subsidyInfoList.stream().collect(Collectors.toMap(RzSubsidyInfo::getId, d->d, (k1, K2)->k1)); Boolean isAdd = true; for(String subsidyId : staff.getSubsidys().split(",")){ - isAdd = true; + isAdd = false; RzSubsidyInfo rzSubsidyInfo = map.get(Long.valueOf(subsidyId)); String key = rzSubsidyInfo.getName(); BigDecimal value = rzSubsidyInfo.getValue(); if(ht.equals(subsidyId) && staff.getContractStart() != null && staff.getContractEnd() != null){ Integer year= DateUtils.getBetweenYear(staff.getContractStart(), staff.getContractEnd(), 1); value = value.multiply(new BigDecimal(year)); + isAdd = true; }else if(gl.equals(subsidyId)){ Integer year= DateUtils.getBetweenYearByDays(staff.getEmploymentDate(), new Date()); //最多只允许10年的工龄补贴 if(year > 10) year=10; value = value.multiply(new BigDecimal(year)); + isAdd = true; }else if(xnh.equals(subsidyId)){ isAdd = "新农合".equals(staff.getSocialType()) && ("是".equals(staff.getSocialSubsidy()) || "享有".equals(staff.getSocialSubsidy())); }else if(yc.equals(subsidyId)){ isAdd = "否".equals(staff.getZsFlag()); } - if(isAdd) staffDetail.getExtendeds().put(key, value); + //当前补助不是特殊补助, 或者 特殊补助允许添加 + if(!tsbz.contains(subsidyId) || isAdd) staffDetail.getExtendeds().put(key, value); } } //计算学历补助