From 4cc93a0f167ca8e212e1e28f57402cd56277fb79 Mon Sep 17 00:00:00 2001 From: andy <1042025947@qq.com> Date: Wed, 9 Jul 2025 17:30:59 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=80=83=E5=8B=A4=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3=20=E8=B0=83=E6=95=B4=E5=91=98?= =?UTF-8?q?=E5=B7=A5=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/evo/attendance/processor/KqUtils.java | 169 +++++++++++ .../impl/KQDeviceExchangeProcessor.java | 267 +++++++++--------- .../service/IRzAttendanceService.java | 3 +- .../service/RzAttendanceDetailService.java | 28 ++ .../impl/RzAttendanceDetailServiceImpl.java | 67 +++++ .../service/impl/RzAttendanceServiceImpl.java | 69 ++--- .../com/evo/common/constant/Constants.java | 1 + .../evo/common/controller/TestController.java | 156 +++++++++- .../main/java/com/evo/common/vo/OptionVo.java | 4 + .../controller/EqButtonController.java | 10 + .../equipment/service/IEqButtonService.java | 6 + .../service/impl/EqButtonServiceImpl.java | 10 +- .../controller/SpecialOverTimeController.java | 4 +- .../impl/RzOverTimeDetailServiceImpl.java | 10 +- .../impl/RzSubsidyInfoServiceImpl.java | 2 +- .../controller/SysStaffDetailController.java | 2 +- .../java/com/evo/system/domain/SysStaff.java | 17 +- .../com/evo/system/mapper/SysStaffMapper.java | 7 +- .../service/impl/SysStaffServiceImpl.java | 26 +- .../mapper/system/SysStaffMapper.xml | 5 +- 20 files changed, 651 insertions(+), 212 deletions(-) create mode 100644 evo-admin/src/main/java/com/evo/attendance/processor/KqUtils.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/RzAttendanceDetailService.java create mode 100644 evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceDetailServiceImpl.java diff --git a/evo-admin/src/main/java/com/evo/attendance/processor/KqUtils.java b/evo-admin/src/main/java/com/evo/attendance/processor/KqUtils.java new file mode 100644 index 0000000..307f799 --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/processor/KqUtils.java @@ -0,0 +1,169 @@ +package com.evo.attendance.processor; + +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.RzAttendanceMapper; +import com.evo.attendance.service.IRzSysParamService; +import com.evo.attendance.service.RzAttendanceDetailService; +import com.evo.common.utils.DataUtils; +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.RzOverTimeDetail; +import com.evo.personnelMatters.service.IRzHolidayService; +import com.evo.system.service.ISysDictDataService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 类 + * + * @ClassName:KqUtils + * @date: 2025年07月07日 14:09 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Service +@Slf4j +public class KqUtils { + + static EqButtonMapper eqButtonMapper; + + static RzAttendanceMapper rzAttendanceMapper; + + static RzAttendanceDetailService rzAttendanceDetailService; + + static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + static SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd"); + + + @Autowired + public KqUtils(EqButtonMapper eqButtonMapper, RzAttendanceMapper rzAttendanceMapper, RzAttendanceDetailService rzAttendanceDetailService) { + this.eqButtonMapper = eqButtonMapper; + this.rzAttendanceMapper = rzAttendanceMapper; + this.rzAttendanceDetailService = rzAttendanceDetailService; + } + /*** 上班卡的下班卡 + * @param date + * @param rules + * @return + */ + public static Boolean workOffDutyCard(Date date, String rules, RzAttendance attendance){ + + //计算工时 + Long hours = (date.getTime() - attendance.getWorkStartTime().getTime())/1000/60/60; + + EqButton eqButton = eqButtonMapper.selectOne(new LambdaQueryWrapper().eq(EqButton::getName, rules)); + + Integer maxWorkHour = ParamUtils.getTsWorkHour(attendance.getName()); + if(maxWorkHour == null){ + maxWorkHour = eqButton.getWorkHour(); + } + + //判断打卡时间, 添加夜班次数 打卡时间在晚上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(maxWorkHour)) >= 0){ + res = new BigDecimal(maxWorkHour); + } + //检查是否异常 + if(checkYc("下班", rules, sdf.format(date), sdfd.format(date))){ + attendance.setYcxFlag("1"); + } + + attendance.setWorkEndTime(date); + attendance.setWorkSum(res); + return (rzAttendanceMapper.updateRzAttendance(attendance) > 0); + } + + /*** 校验是否上班卡打卡异常 + * @param rules + * @param dateTime + * @param date + * @return + */ + public static 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) { + log.error("打卡交易是否异常出现错误{}", e.getMessage()); + } + //默认为没有异常 + return false; + } + + + public static void calculateOverTimeHours(RzOverTimeDetail rzOverTimeDetail, Long userId, String sn){ + //计算加班时长 分钟 + BigDecimal minutes = new BigDecimal((rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60); + //获取加班的最后一次的上班卡类型, 如果不是12小时制或者三班制, 直接扣减半小时 + RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailService.selectLastWorkCardByStaffId(userId); + /*** + * 上班卡不是12小时制, 并且不是三班制 (三班制为兼容旧数据) 直接扣减30分钟 + *需求来源 3.2.4 短休相关规定 + * 3.2 工作时间 + * 3.2.1 长白班: + * (1)实行每周一至周六,每天8小时的工作制度; + * (2)工作时间:08:30—12:00,13:00—17:30; + * (3)午休时间:12:00—13:00; + * (4)节假日(含周日)加班时,工作时间按第(2)条执行。 + * 3.2.2 八小时倒班: + * (1)白班工作时间:8:30—12:00, 12:30—17:00; 午餐短休:12:00—12:30。 + * (2)中班工作时间:17:00—18:30,19:00—01:30; 晚餐短休:18:30—19:00。 + * 3.2.3 十二小时倒班: + * (1)白班工作时间:8:30—12:00,12:30—18:30,19:00—20:30; + * 午餐短休:12:00—12:30,晚餐短休:18:30—19:00。 + * (2)夜班工作时间:20:30—23:30,00:00—03:30,04:00—08:30; + * 夜班短休:23:30—00:00,03:30—04:00。 + * 3.2.4 短休相关规定: + * (1)在规定的短休时间段内,需装拆加工零部件时,可暂停设备前往就餐或短休; + * (2)原则上十二小时倒班人员短休核算工时,八小时倒班及长白班人员短休不统计该时间段工时; + * (3)非就餐的短休,地点应在设备可视且可听范围之内,严禁在短休前提前强行停机,一经发现按以下条款考核激励: + * A) 岗位责任人激励-50元/项/次; + * B) 公司检查发现的按层级组织秩序,激励责任管理岗两级各-100元/项/次。 + */ + if(!rzAttendanceDetail.getButtonType().contains("12") && !rzAttendanceDetail.getButtonType().contains("三班")){ + minutes = minutes.subtract(new BigDecimal(ParamUtils.getShortBreakDeductionMinutes())); + } + //设置默认加班0小时 + double hours = 0; + //加班分钟>0分钟, 计算小时 + if(minutes.compareTo(DataUtils.DEFAULT_VALUE) >0){ + //计算小时, 保留2位小数 + hours = minutes.divide(new BigDecimal(60),2,BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + //获取规则 + JSONObject deviceRules = ParamUtils.getDeviceOverTimeRules(sn); + //获取最大加班时长 + Integer maxOverTimeHour = deviceRules.getInteger("maxHour"); + //记录加班时长 + rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(((hours > maxOverTimeHour) ? maxOverTimeHour : hours))); + + } + +} 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 c4e2efb..3a93b79 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 @@ -1,16 +1,18 @@ 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.KqUtils; import com.evo.attendance.processor.PunchTheClockStrategyExchangeProcessor; +import com.evo.attendance.service.RzAttendanceDetailService; 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.common.utils.Collections; +import com.evo.common.utils.DataUtils; +import com.evo.common.utils.DateUtils; +import com.evo.common.utils.StringUtils; import com.evo.equipment.mapper.EqButtonMapper; import com.evo.personnelMatters.domain.RzOverTime; import com.evo.personnelMatters.domain.RzOverTimeDetail; @@ -27,8 +29,6 @@ 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; @@ -47,7 +47,7 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP @Resource private SysStaffMapper sysStaffMapper; @Resource - private RzAttendanceDetailMapper rzAttendanceDetailMapper; + private RzAttendanceDetailService rzAttendanceDetailService; @Resource private RzOverTimeMapper rzOverTimeMapper; @Resource @@ -91,7 +91,7 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId()); //查询员工的最后一次打卡 按钮切换 - RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectLastRzAttendanceDetail(sysStaff.getUserId()); + RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailService.selectLastRzAttendanceDetail(sysStaff.getUserId()); //判断最后一次打卡为下班卡或没有打卡记录,则打卡为上班卡 if(showButton(sysStaffDetail) || StringUtils.isNull(rzAttendanceDetail) || "下班卡".equals(rzAttendanceDetail.getButtonType()) || "撤销".equals(rzAttendanceDetail.getButtonType())){ //如果最后一条数据的卡类型为下班卡,则返回上班卡和加班卡权限 or 检查当前人员是否存在特殊加班中 或者 检查当前人员部门是否开启加班 or 暂时取消这个判定 当天打过加班卡 ( || rzAttendanceDetailMapper.checkOverTimeCard(sysStaff.getUserId(), new Date()) > 0) @@ -141,18 +141,20 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP //获取最后一次的上班记录 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()); //获取员工的工作时长 - 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){ + RzAttendanceDetail attendanceDetail = rzAttendanceDetailService.addDetail(attendance, rules, sn, date, ""); + if(attendanceDetail.getId() == null){ return initMessage(1, "打卡失败"); } @@ -173,21 +175,22 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP } // 查询员工的最后一次上班打卡信息 - RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectRzAttendanceDetailByStaffId(Long.valueOf(userId)); + RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailService.selectRzAttendanceDetailByStaffId(Long.valueOf(userId)); //加班的下班卡 if(rzAttendanceDetail.getButtonType().contains("加班")){ return overTimeOffDutyCard(sysStaff, date, sn); } //上班的下班卡 if(rzAttendanceDetail.getButtonType().contains("上班")){ - return workOffDutyCard( date, rzAttendanceDetail.getButtonType(), attendance); + + return KqUtils.workOffDutyCard( date, rzAttendanceDetail.getButtonType(), attendance) ? initMessage(0, "打卡成功") : initMessage(1,"打卡失败"); } return initMessage(1, "打卡失败"); } public Boolean checkToDayCard(String userId, String rules){ - return ObjectUtils.isNotEmpty(rzAttendanceDetailMapper.selectOne(new LambdaQueryWrapper() + return ObjectUtils.isNotEmpty(rzAttendanceDetailService.getOne(new LambdaQueryWrapper() .like(RzAttendanceDetail::getButtonType,"%"+rules+"%") .eq(RzAttendanceDetail::getStaffId, Long.valueOf(userId)) .eq(RzAttendanceDetail::getDelFlag, Constants.DELETE_FLAG_0) @@ -207,7 +210,7 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP attendance.setRules(rules); attendance.setWorkStartTime(date); try{ - if(checkYc("上班", rules, sdf.format(date), sdfd.format(date))){ + if(KqUtils.checkYc("上班", rules, sdf.format(date), sdfd.format(date))){ attendance.setYcsFlag("1"); } }catch (Exception e){ @@ -216,71 +219,71 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP 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().eq(EqButton::getName, rules)); - - Integer maxWorkHour = ParamUtils.getTsWorkHour(attendance.getName()); - if(maxWorkHour == null){ - maxWorkHour = eqButton.getWorkHour(); - } - - //判断打卡时间, 添加夜班次数 打卡时间在晚上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(maxWorkHour)) >= 0){ - res = new BigDecimal(maxWorkHour); - } -// else if(hours.compareTo(Long.valueOf(eqButton.getWorkHour()/2)) > 0){ -// res = new BigDecimal(eqButton.getWorkHour()/2); +// /*** 上班卡的下班卡 +// * @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().eq(EqButton::getName, rules)); +// +// Integer maxWorkHour = ParamUtils.getTsWorkHour(attendance.getName()); +// if(maxWorkHour == null){ +// maxWorkHour = eqButton.getWorkHour(); // } - //检查是否异常 - 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,"打卡失败"); - } +// +// //判断打卡时间, 添加夜班次数 打卡时间在晚上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(maxWorkHour)) >= 0){ +// res = new BigDecimal(maxWorkHour); +// } +//// 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 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 @@ -308,12 +311,12 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP attendance.setRules(""); attendance.setYcsFlag(""); //如果是规则1 - return ((rzAttendanceMapper.updateById(attendance) > 0 && rzAttendanceDetailMapper.updateById(rzAttendanceDetail) > 0) ? initMessage(0, "打卡成功") : initMessage(1, "打卡失败")); + return ((rzAttendanceMapper.updateById(attendance) > 0 && rzAttendanceDetailService.updateById(rzAttendanceDetail)) ? 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, "打卡失败")); + return ((rzOverTimeDetailMapper.deleteById(overTimeDetail) > 0 && rzAttendanceDetailService.updateById(rzAttendanceDetail)) ? initMessage(0, "打卡成功") : initMessage(1, "打卡失败")); } //规则3 // if(rzAttendanceDetail.getButtonType().contains("下班")){ @@ -352,7 +355,7 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP public RzAttendanceDetail getLastDetailByUserIdAndDate(Long userId, Long... notId){ - return rzAttendanceDetailMapper.selectOne(new LambdaQueryWrapper().eq(RzAttendanceDetail::getStaffId,userId).notIn(Collections.isNotEmpty(notId), RzAttendanceDetail::getId, notId).orderByDesc(RzAttendanceDetail::getDateTime).last(" limit 1")); + return rzAttendanceDetailService.getOne(new LambdaQueryWrapper().eq(RzAttendanceDetail::getStaffId,userId).notIn(Collections.isNotEmpty(notId), RzAttendanceDetail::getId, notId).orderByDesc(RzAttendanceDetail::getDateTime).last(" limit 1")); } @@ -415,50 +418,52 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP } rzOverTimeDetail.setOverTimeEnd(date); //计算加班时长 分钟 - BigDecimal minutes = new BigDecimal((rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60); - //获取加班的最后一次的上班卡类型, 如果不是12小时制或者三班制, 直接扣减半小时 - RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailMapper.selectLastWorkCardByStaffId(sysStaff.getUserId()); - /*** - * 上班卡不是12小时制, 并且不是三班制 (三班制为兼容旧数据) 直接扣减30分钟 - *需求来源 3.2.4 短休相关规定 - * 3.2 工作时间 - * 3.2.1 长白班: - * (1)实行每周一至周六,每天8小时的工作制度; - * (2)工作时间:08:30—12:00,13:00—17:30; - * (3)午休时间:12:00—13:00; - * (4)节假日(含周日)加班时,工作时间按第(2)条执行。 - * 3.2.2 八小时倒班: - * (1)白班工作时间:8:30—12:00, 12:30—17:00; 午餐短休:12:00—12:30。 - * (2)中班工作时间:17:00—18:30,19:00—01:30; 晚餐短休:18:30—19:00。 - * 3.2.3 十二小时倒班: - * (1)白班工作时间:8:30—12:00,12:30—18:30,19:00—20:30; - * 午餐短休:12:00—12:30,晚餐短休:18:30—19:00。 - * (2)夜班工作时间:20:30—23:30,00:00—03:30,04:00—08:30; - * 夜班短休:23:30—00:00,03:30—04:00。 - * 3.2.4 短休相关规定: - * (1)在规定的短休时间段内,需装拆加工零部件时,可暂停设备前往就餐或短休; - * (2)原则上十二小时倒班人员短休核算工时,八小时倒班及长白班人员短休不统计该时间段工时; - * (3)非就餐的短休,地点应在设备可视且可听范围之内,严禁在短休前提前强行停机,一经发现按以下条款考核激励: - * A) 岗位责任人激励-50元/项/次; - * B) 公司检查发现的按层级组织秩序,激励责任管理岗两级各-100元/项/次。 - */ - if(!rzAttendanceDetail.getButtonType().contains("12") && !rzAttendanceDetail.getButtonType().contains("三班")){ - minutes = minutes.subtract(new BigDecimal(ParamUtils.getShortBreakDeductionMinutes())); - } - //设置默认加班0小时 - double hours = 0; - //加班分钟>0分钟, 计算小时 - if(minutes.compareTo(DataUtils.DEFAULT_VALUE) >0){ - //计算小时, 保留2位小数 - hours = minutes.divide(new BigDecimal(60),2,BigDecimal.ROUND_HALF_UP).doubleValue(); - } + KqUtils.calculateOverTimeHours(rzOverTimeDetail, sysStaff.getUserId(), sn); - //获取规则 - JSONObject deviceRules = ParamUtils.getDeviceOverTimeRules(sn); - //获取最大加班时长 - Integer maxOverTimeHour = deviceRules.getInteger("maxHour"); - //记录加班时长 - rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(((hours > maxOverTimeHour) ? maxOverTimeHour : hours))); +// BigDecimal minutes = new BigDecimal((rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60); +// //获取加班的最后一次的上班卡类型, 如果不是12小时制或者三班制, 直接扣减半小时 +// RzAttendanceDetail rzAttendanceDetail = rzAttendanceDetailService.selectLastWorkCardByStaffId(sysStaff.getUserId()); +// /*** +// * 上班卡不是12小时制, 并且不是三班制 (三班制为兼容旧数据) 直接扣减30分钟 +// *需求来源 3.2.4 短休相关规定 +// * 3.2 工作时间 +// * 3.2.1 长白班: +// * (1)实行每周一至周六,每天8小时的工作制度; +// * (2)工作时间:08:30—12:00,13:00—17:30; +// * (3)午休时间:12:00—13:00; +// * (4)节假日(含周日)加班时,工作时间按第(2)条执行。 +// * 3.2.2 八小时倒班: +// * (1)白班工作时间:8:30—12:00, 12:30—17:00; 午餐短休:12:00—12:30。 +// * (2)中班工作时间:17:00—18:30,19:00—01:30; 晚餐短休:18:30—19:00。 +// * 3.2.3 十二小时倒班: +// * (1)白班工作时间:8:30—12:00,12:30—18:30,19:00—20:30; +// * 午餐短休:12:00—12:30,晚餐短休:18:30—19:00。 +// * (2)夜班工作时间:20:30—23:30,00:00—03:30,04:00—08:30; +// * 夜班短休:23:30—00:00,03:30—04:00。 +// * 3.2.4 短休相关规定: +// * (1)在规定的短休时间段内,需装拆加工零部件时,可暂停设备前往就餐或短休; +// * (2)原则上十二小时倒班人员短休核算工时,八小时倒班及长白班人员短休不统计该时间段工时; +// * (3)非就餐的短休,地点应在设备可视且可听范围之内,严禁在短休前提前强行停机,一经发现按以下条款考核激励: +// * A) 岗位责任人激励-50元/项/次; +// * B) 公司检查发现的按层级组织秩序,激励责任管理岗两级各-100元/项/次。 +// */ +// if(!rzAttendanceDetail.getButtonType().contains("12") && !rzAttendanceDetail.getButtonType().contains("三班")){ +// minutes = minutes.subtract(new BigDecimal(ParamUtils.getShortBreakDeductionMinutes())); +// } +// //设置默认加班0小时 +// double hours = 0; +// //加班分钟>0分钟, 计算小时 +// if(minutes.compareTo(DataUtils.DEFAULT_VALUE) >0){ +// //计算小时, 保留2位小数 +// hours = minutes.divide(new BigDecimal(60),2,BigDecimal.ROUND_HALF_UP).doubleValue(); +// } +// +// //获取规则 +// 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, "打卡失败"); diff --git a/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java b/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java index 0e20711..d97d06a 100644 --- a/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java +++ b/evo-admin/src/main/java/com/evo/attendance/service/IRzAttendanceService.java @@ -1,5 +1,6 @@ package com.evo.attendance.service; +import com.baomidou.mybatisplus.extension.service.IService; import com.evo.attendance.domain.vo.RzAttendanceDetailVO; import com.evo.common.core.domain.AjaxResult; import com.evo.attendance.domain.RzAttendance; @@ -13,7 +14,7 @@ import java.util.List; * @author chenyj * @date 2024-09-05 */ -public interface IRzAttendanceService +public interface IRzAttendanceService extends IService { /** * 查询考勤记录 diff --git a/evo-admin/src/main/java/com/evo/attendance/service/RzAttendanceDetailService.java b/evo-admin/src/main/java/com/evo/attendance/service/RzAttendanceDetailService.java new file mode 100644 index 0000000..8b3d76d --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/RzAttendanceDetailService.java @@ -0,0 +1,28 @@ +package com.evo.attendance.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.evo.attendance.domain.RzAttendance; +import com.evo.attendance.domain.RzAttendanceDetail; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; + +/** + * 接口 + * + * @ClassName:RzAttendanceDetailService + * @date: 2025年07月07日 13:32 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +public interface RzAttendanceDetailService extends IService { + + public RzAttendanceDetail addDetail(RzAttendance attendance, String rules, String sn, Date date, String remark); + + public RzAttendanceDetail selectLastRzAttendanceDetail(Long staffId); + + public RzAttendanceDetail selectRzAttendanceDetailByStaffId(Long staffId); + + public RzAttendanceDetail selectLastWorkCardByStaffId(@Param("staffId") Long staffId); +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceDetailServiceImpl.java new file mode 100644 index 0000000..2fe3f9b --- /dev/null +++ b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceDetailServiceImpl.java @@ -0,0 +1,67 @@ +package com.evo.attendance.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.evo.attendance.domain.RzAttendance; +import com.evo.attendance.domain.RzAttendanceDetail; +import com.evo.attendance.mapper.RzAttendanceDetailMapper; +import com.evo.attendance.service.RzAttendanceDetailService; +import com.evo.common.constant.Constants; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.stereotype.Service; + +import java.util.Date; + +/** + * 类 + * + * @ClassName:RzAttendanceDetailServiceimpl + * @date: 2025年07月07日 13:33 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Service +public class RzAttendanceDetailServiceImpl extends ServiceImpl implements RzAttendanceDetailService { + + @Override + public RzAttendanceDetail addDetail(RzAttendance attendance, String rules, String sn, Date date, String remark) { + //获取员工的工作时长 + RzAttendanceDetail attendanceDetail = getOne(new LambdaQueryWrapper().eq(RzAttendanceDetail::getButtonType, rules).eq(RzAttendanceDetail::getDelFlag, Constants.DELETE_FLAG_0).eq(RzAttendanceDetail::getStaffId, attendance.getStaffId()).apply( " DATE_FORMAT(date_time,'%Y%m%d') = DATE_FORMAT({0},'%Y%m%d')", date)); + if(ObjectUtils.isEmpty(attendanceDetail)){ + attendanceDetail = new RzAttendanceDetail(); + attendanceDetail.setStaffId(attendance.getStaffId()); + attendanceDetail.setName(attendance.getName()); + attendanceDetail.setDelFlag(Constants.DELETE_FLAG_0); + } + + //打卡明细表中插入数据 + attendanceDetail.setButtonType(rules); + attendanceDetail.setAttendanceId(attendance.getId()); + attendanceDetail.setDateTime(date); + attendanceDetail.setEquipmentCode(sn); + attendanceDetail.setCreateTime(new Date()); + attendanceDetail.setRemark(remark); + if(attendanceDetail.getId() == null){ + save(attendanceDetail); + }else{ + updateById(attendanceDetail); + } + return attendanceDetail; + } + + @Override + public RzAttendanceDetail selectLastRzAttendanceDetail(Long staffId) { + return getBaseMapper().selectLastRzAttendanceDetail(staffId); + } + + @Override + public RzAttendanceDetail selectRzAttendanceDetailByStaffId(Long staffId) { + return getBaseMapper().selectRzAttendanceDetailByStaffId(staffId); + } + + @Override + public RzAttendanceDetail selectLastWorkCardByStaffId(Long staffId) { + return getBaseMapper().selectLastWorkCardByStaffId(staffId); + } +} diff --git a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java index 8cae880..ae2d682 100644 --- a/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java +++ b/evo-admin/src/main/java/com/evo/attendance/service/impl/RzAttendanceServiceImpl.java @@ -1,43 +1,33 @@ 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.RzAttendance; import com.evo.attendance.domain.RzAttendanceDetail; import com.evo.attendance.domain.vo.RzAttendanceDetailVO; -import com.evo.attendance.mapper.RzAttendanceDetailMapper; +import com.evo.attendance.mapper.RzAttendanceMapper; +import com.evo.attendance.processor.KqUtils; +import com.evo.attendance.service.IRzAttendanceService; +import com.evo.attendance.service.RzAttendanceDetailService; 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.DateUtils; import com.evo.common.utils.SecurityUtils; -import com.evo.attendance.domain.RzAttendance; -import com.evo.attendance.mapper.RzAttendanceMapper; -import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; -import com.evo.attendance.service.IRzAttendanceService; import com.evo.common.utils.StringUtils; -import com.evo.equipment.domain.EqImages; import com.evo.equipment.service.IEqImagesService; import com.evo.system.domain.SysStaff; import com.evo.system.mapper.SysDeptMapper; import com.evo.system.service.ISysStaffService; -import com.evo.utils.DateConvertor; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.text.SimpleDateFormat; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.ZoneId; import java.util.Date; import java.util.List; -import static com.evo.framework.datasource.DynamicDataSourceContextHolder.log; - /** * 考勤记录Service业务层处理 * @@ -49,13 +39,12 @@ public class RzAttendanceServiceImpl extends ServiceImpl= 8) { - rzAttendance.setWorkSum(Constants.DAY_WORK_HOUR); - } else if (sj >= 4) { - rzAttendance.setWorkSum(new BigDecimal(4)); + //如果下班卡为空, 则补上班卡 + SysStaff sysUser = sysStaffService.selectSysStaffByUserId(rzAttendance.getStaffId()); + if(rzAttendance.getWorkEndTime() == null){ + //跟新成功, 插入上班卡信息 + if(getBaseMapper().updateRzAttendance(rzAttendance) > 0){ + rzAttendanceDetailService.addDetail(rzAttendance, rzAttendance.getRules(), sysUser.getTimeClock(), rzAttendance.getWorkStartTime(),rzAttendance.getRemark()); + } + return 1; + }else if(rzAttendance.getWorkStartTime() != null && rzAttendance.getWorkEndTime() != null){ + if(KqUtils.workOffDutyCard(rzAttendance.getWorkEndTime(), rzAttendance.getRules(), rzAttendance)){ + //此处特殊, 使用rules 记录下班卡规则, 但是不持久化 + rzAttendanceDetailService.addDetail(rzAttendance, "下班卡", sysUser.getTimeClock(), rzAttendance.getWorkEndTime(),rzAttendance.getRemark()); + } + return 1; } - rzAttendance.setYcsFlag("0"); - rzAttendance.setYcxFlag("0"); - rzAttendance.setUpdateBy(SecurityUtils.getUsername()); - rzAttendance.setUpdateTime(DateUtils.getNowDate()); - return getBaseMapper().updateRzAttendance(rzAttendance); + return 0; } /** @@ -280,7 +273,7 @@ public class RzAttendanceServiceImpl extends ServiceImpl details = rzAttendanceDetailMapper.selectList(queryWrapper); + List details = rzAttendanceDetailService.list(queryWrapper); RzAttendanceDetail rzAttendanceDetail; if (!details.isEmpty()){ rzAttendanceDetail = details.get(0); @@ -315,7 +308,7 @@ public class RzAttendanceServiceImpl extends ServiceImpl() .eq(RzAttendance::getId, attendance.getId())); - rzAttendanceDetailMapper.update(rzAttendanceDetail, new LambdaUpdateWrapper() + rzAttendanceDetailService.update(rzAttendanceDetail, new LambdaUpdateWrapper() .eq(RzAttendanceDetail::getId, rzAttendanceDetail.getId())); //更新考勤记录详情 } else { @@ -362,7 +355,7 @@ public class RzAttendanceServiceImpl extends ServiceImpl details = rzAttendanceDetailMapper.selectList(queryWrapper); + List details = rzAttendanceDetailService.list(queryWrapper); RzAttendanceDetail rzAttendanceDetail = details.get(0); //更新考勤记录表 if (vo.getReissueType().equals("加班卡")) { @@ -391,7 +384,7 @@ public class RzAttendanceServiceImpl extends ServiceImpl() .eq(RzAttendance::getId, attendance.getId())); - rzAttendanceDetailMapper.update(rzAttendanceDetail, new LambdaUpdateWrapper() + rzAttendanceDetailService.update(rzAttendanceDetail, new LambdaUpdateWrapper() .eq(RzAttendanceDetail::getId, rzAttendanceDetail.getId())); } } catch (Exception e) { diff --git a/evo-admin/src/main/java/com/evo/common/constant/Constants.java b/evo-admin/src/main/java/com/evo/common/constant/Constants.java index b0924a7..2a395ac 100644 --- a/evo-admin/src/main/java/com/evo/common/constant/Constants.java +++ b/evo-admin/src/main/java/com/evo/common/constant/Constants.java @@ -113,6 +113,7 @@ public class Constants public static final String SEIZE_A_SEAT_0 = "0"; //占位符 public static final String SEIZE_A_SEAT_1 = "00"; //占位符 public static final String SEIZE_A_SEAT_2 = "000"; //占位符 + public static final String SEIZE_A_SEAT_3 = "0000"; //占位符 public static final String SYS_SENIORITY_SUBSIDIES = "50"; //工龄补助 public static final Integer SYS_CONTRACT_SUBSIDY = 50; //合同补助的基数 public static final String SYS_CONTRACT_0 = "50"; //一年期合同补助 diff --git a/evo-admin/src/main/java/com/evo/common/controller/TestController.java b/evo-admin/src/main/java/com/evo/common/controller/TestController.java index 19920a7..20d7035 100644 --- a/evo-admin/src/main/java/com/evo/common/controller/TestController.java +++ b/evo-admin/src/main/java/com/evo/common/controller/TestController.java @@ -1,32 +1,35 @@ package com.evo.common.controller; -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.service.IRzAttendanceService; import com.evo.attendance.service.IRzAttendanceStatisticalService; +import com.evo.attendance.service.RzAttendanceDetailService; +import com.evo.common.constant.Constants; import com.evo.common.core.domain.AjaxResult; -import com.evo.common.core.page.TableDataInfo; import com.evo.common.utils.Collections; -import com.evo.common.utils.ParamUtils; -import com.evo.finance.domain.RzSalaryDetail; -import com.evo.personnelMatters.domain.RzOverTimeDetail; +import com.evo.common.utils.StringUtils; import com.evo.personnelMatters.mapper.RzOverTimeDetailMapper; import com.evo.personnelMatters.mapper.RzOverTimeMapper; import com.evo.restaurant.service.IRzRestaurantStatisticsService; import com.evo.system.domain.SysStaff; import com.evo.system.service.ISysStaffService; -import com.evo.system.service.impl.SysStaffServiceImpl; -import org.springframework.security.access.prepost.PreAuthorize; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.time.DateUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; -import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; /** * 类 @@ -50,6 +53,11 @@ public class TestController { IRzAttendanceStatisticalService rzAttendanceStatisticalService; @Resource IRzRestaurantStatisticsService rzRestaurantStatisticsService; + + @Resource + private IRzAttendanceService rzAttendanceService; + @Resource + private RzAttendanceDetailService rzAttendanceDetailService; /** * 清洗加班 */ @@ -90,4 +98,136 @@ public class TestController { return AjaxResult.success(); } + + @PostMapping("/qxdk") + public AjaxResult qxdk() throws ParseException { + Map snMap = sysStaffService.list(new LambdaQueryWrapper().eq(SysStaff::getDelFlag, Constants.DELETE_FLAG_0)).stream().filter(data->{ return (data.getUserId() != null && StringUtils.isNotEmpty(data.getTimeClock())); + }).collect(Collectors.toMap(SysStaff::getUserId, SysStaff::getTimeClock)); + + + Date d = new SimpleDateFormat("yyyy-MM-dd").parse("2025-07-08"); + Map timeMap = Collections.asMap("上班卡(倒班12时制)",12,"上班卡(单班制)",9,"上班卡(倒班8时制)",9); + List list = rzAttendanceService.list(new LambdaQueryWrapper() + .eq(RzAttendance::getDelFlag, Constants.DELETE_FLAG_0) + .apply(" date_format(`attendance_date`,'%Y%m%d')=date_format({0},'%Y%m%d') ",d) + .apply(" work_start_time is not null ") + ).stream().map(data ->{ + data.setWorkEndTime(DateUtils.addHours(data.getWorkStartTime(), timeMap.get(data.getRules()))); + return data; + }).collect(Collectors.toList()); + + if(Collections.isNotEmpty(list)){ + //更新所有的卡时间 + rzAttendanceService.updateBatchById(list); + for (RzAttendance rzAttendance : list){ + List sbList = rzAttendanceDetailService.list(new LambdaQueryWrapper().eq(RzAttendanceDetail::getDelFlag, Constants.DELETE_FLAG_0).eq(RzAttendanceDetail::getAttendanceId, rzAttendance.getId()).like(RzAttendanceDetail::getButtonType,"%上班%")); + if(Collections.isEmpty(sbList)){ + rzAttendanceDetailService.addDetail(rzAttendance, rzAttendance.getRules(), snMap.get(rzAttendance.getStaffId()), rzAttendance.getWorkStartTime(), "系统清洗"); + }else if(sbList.size() > 1){ + sbList.remove(0); + rzAttendanceDetailService.removeByIds(sbList); + } + List xbList = rzAttendanceDetailService.list(new LambdaQueryWrapper().eq(RzAttendanceDetail::getDelFlag, Constants.DELETE_FLAG_0).eq(RzAttendanceDetail::getAttendanceId, rzAttendance.getId()).like(RzAttendanceDetail::getButtonType,"%下班%")); + if(ObjectUtils.isEmpty(xbList)){ + rzAttendanceDetailService.addDetail(rzAttendance, "下班卡", snMap.get(rzAttendance.getStaffId()), rzAttendance.getWorkEndTime(), "系统清洗"); + }else if(xbList.size() > 1){ + xbList.remove(0); + rzAttendanceDetailService.removeByIds(xbList); + } + } + } + + + + list = rzAttendanceService.list(new LambdaQueryWrapper() + .eq(RzAttendance::getDelFlag, Constants.DELETE_FLAG_0) + .apply(" date_format(`attendance_date`,'%Y%m%d')=date_format({0},'%Y%m%d') ",new SimpleDateFormat("yyyy-MM-dd").parse("2025-07-09")) + .apply(" work_start_time is not null ") + ); + + if(Collections.isNotEmpty(list)){ + //更新所有的卡时间 + for (RzAttendance rzAttendance : list){ + List sbList = rzAttendanceDetailService.list(new LambdaQueryWrapper().eq(RzAttendanceDetail::getDelFlag, Constants.DELETE_FLAG_0).eq(RzAttendanceDetail::getAttendanceId, rzAttendance.getId()).like(RzAttendanceDetail::getButtonType,"%上班%")); + if(Collections.isEmpty(sbList)){ + rzAttendanceDetailService.addDetail(rzAttendance, rzAttendance.getRules(), snMap.get(rzAttendance.getStaffId()), rzAttendance.getWorkStartTime(), "系统清洗"); + }else if(sbList.size() > 1){ + sbList.remove(0); + rzAttendanceDetailService.removeByIds(sbList); + } + } + } + return AjaxResult.success(); + } + + private String buildCode(Integer code){ + if(code < 10){ + return Constants.SEIZE_A_SEAT_3 + code; + }else if(code < 100){ + return Constants.SEIZE_A_SEAT_2 + code; + }else if(code < 1000){ + return Constants.SEIZE_A_SEAT_1 + code; + }else if(code < 10000){ + return Constants.SEIZE_A_SEAT_0 + code; + }else{ + return String.valueOf(code); + } + } + + @PostMapping("/qxCode") + public AjaxResult qxCode() throws ParseException { + AtomicReference code = new AtomicReference<>(6); + List list = sysStaffService.list(new LambdaQueryWrapper().notIn(SysStaff::getName, Collections.asList("胡景昌","张敏","胡毅鹏","李雾","尹国峰")).orderByAsc(SysStaff::getEmploymentDate)).stream().map(data ->{ + data.setCode(buildCode(code.get())); + code.set(code.get() +1); + return data; + }).collect(Collectors.toList()); + + sysStaffService.updateBatchById(list,list.size()); + + return AjaxResult.success(); + } + + + + public static void main(String[] args) { + String dids = "41676," + + "41677," + + "41715," + + "41824," + + "41747," + + "41748," + + "41703," + + "42086," + + "41801," + + "41817," + + "41674," + + "41680," + + "41772," + + "41774," + + "41820," + + "41822," + + "41711," + + "41830," + + "41684," + + "42023," + + "41821," + + "41840," + + "41754," + + "41962," + + "41688," + + "41951"; + StringBuilder d = new StringBuilder(""); + for (int i = 0; i < Collections.asList(dids.split(",")).size(); i++) { + if(i%2 > 0){ + d.append("'"+dids.split(",")[i]+"'").append(","); + } + } + System.out.println(d.toString()); + + } + + + + } diff --git a/evo-admin/src/main/java/com/evo/common/vo/OptionVo.java b/evo-admin/src/main/java/com/evo/common/vo/OptionVo.java index 7f6ac52..916078a 100644 --- a/evo-admin/src/main/java/com/evo/common/vo/OptionVo.java +++ b/evo-admin/src/main/java/com/evo/common/vo/OptionVo.java @@ -23,6 +23,10 @@ public class OptionVo { public OptionVo() { } + public OptionVo(String label) { + this.label = label; + } + public OptionVo(Long value, String label) { this.value = value; this.label = label; diff --git a/evo-admin/src/main/java/com/evo/equipment/controller/EqButtonController.java b/evo-admin/src/main/java/com/evo/equipment/controller/EqButtonController.java index 13c2998..cec61a6 100644 --- a/evo-admin/src/main/java/com/evo/equipment/controller/EqButtonController.java +++ b/evo-admin/src/main/java/com/evo/equipment/controller/EqButtonController.java @@ -140,4 +140,14 @@ public class EqButtonController extends BaseController { return eqButtonService.deleteEqButtonById(id,SecurityUtils.getUsername()); } + + + /** + * 补卡查询规则 + */ + @PostMapping("/getOption") + public AjaxResult getOption(String rules) + { + return AjaxResult.success(eqButtonService.getOption(rules)); + } } diff --git a/evo-admin/src/main/java/com/evo/equipment/service/IEqButtonService.java b/evo-admin/src/main/java/com/evo/equipment/service/IEqButtonService.java index 2bee38e..3fa897b 100644 --- a/evo-admin/src/main/java/com/evo/equipment/service/IEqButtonService.java +++ b/evo-admin/src/main/java/com/evo/equipment/service/IEqButtonService.java @@ -1,10 +1,14 @@ package com.evo.equipment.service; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.evo.common.core.domain.AjaxResult; +import com.evo.common.vo.OptionVo; import com.evo.equipment.domain.EqButton; import com.evo.equipment.domain.EqSnDetail; +import com.evo.personnelMatters.domain.RzSubsidyInfo; import java.util.List; +import java.util.stream.Collectors; /** * 按钮信息Service接口 @@ -62,4 +66,6 @@ public interface IEqButtonService */ public EqButton selectEqButtonByName(String name); + + public List getOption(String rules); } diff --git a/evo-admin/src/main/java/com/evo/equipment/service/impl/EqButtonServiceImpl.java b/evo-admin/src/main/java/com/evo/equipment/service/impl/EqButtonServiceImpl.java index d42e081..58372b1 100644 --- a/evo-admin/src/main/java/com/evo/equipment/service/impl/EqButtonServiceImpl.java +++ b/evo-admin/src/main/java/com/evo/equipment/service/impl/EqButtonServiceImpl.java @@ -1,14 +1,18 @@ package com.evo.equipment.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.evo.common.constant.Constants; import com.evo.common.core.domain.AjaxResult; import com.evo.common.utils.DateUtils; import com.evo.common.utils.SecurityUtils; +import com.evo.common.vo.OptionVo; import com.evo.equipment.domain.EqButton; import com.evo.equipment.domain.EqSnDetail; import com.evo.equipment.mapper.EqButtonMapper; import com.evo.equipment.service.IEqButtonService; import com.evo.equipment.service.IEqSnDetailService; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -22,7 +26,7 @@ import java.util.stream.Collectors; * @date 2024-11-15 */ @Service -public class EqButtonServiceImpl implements IEqButtonService +public class EqButtonServiceImpl extends ServiceImpl implements IEqButtonService { @Resource private EqButtonMapper eqButtonMapper; @@ -138,4 +142,8 @@ public class EqButtonServiceImpl implements IEqButtonService return eqButtonMapper.selectEqButtonByName(name); } + @Override + public List getOption(String rules) { + return list(new LambdaQueryWrapper().eq(EqButton::getDelFlag,0).like(StringUtils.isNotEmpty(rules), EqButton::getName, "%"+rules+"%").select(EqButton::getName)).stream().map(d ->new OptionVo(d.getName())).collect(Collectors.toList()); + } } diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/controller/SpecialOverTimeController.java b/evo-admin/src/main/java/com/evo/personnelMatters/controller/SpecialOverTimeController.java index b128483..df79bc5 100644 --- a/evo-admin/src/main/java/com/evo/personnelMatters/controller/SpecialOverTimeController.java +++ b/evo-admin/src/main/java/com/evo/personnelMatters/controller/SpecialOverTimeController.java @@ -38,9 +38,9 @@ public class SpecialOverTimeController extends BaseController { /** * 保存时间管理 */ - @PreAuthorize("@ss.hasPermi('personnelMatters:specialOverTime:add')") + @PreAuthorize("@ss.hasPermi('personnelMatters:specialOverTime:update')") @PostMapping - public AjaxResult addSpecialOverTime(@RequestBody SpecialOverTime specialOverTime) + public AjaxResult updateSpecialOverTime(@RequestBody SpecialOverTime specialOverTime) { return specialOverTimeService.addSpecialOverTime(specialOverTime); } diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeDetailServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeDetailServiceImpl.java index a30b387..06097cc 100644 --- a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeDetailServiceImpl.java +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzOverTimeDetailServiceImpl.java @@ -5,8 +5,10 @@ import com.evo.attendance.domain.RzAttendanceDetail; import com.evo.attendance.mapper.RzAttendanceDetailMapper; import com.evo.attendance.mapper.RzAttendanceMapper; import com.evo.attendance.mapper.RzAttendanceStatisticalMapper; +import com.evo.attendance.processor.KqUtils; import com.evo.common.constant.Constants; import com.evo.common.core.domain.AjaxResult; +import com.evo.common.core.domain.entity.SysUser; import com.evo.common.utils.DateUtils; import com.evo.common.utils.SecurityUtils; import com.evo.personnelMatters.domain.RzOverTime; @@ -168,18 +170,24 @@ public class RzOverTimeDetailServiceImpl implements IRzOverTimeDetailService @Transactional public AjaxResult updateRzOverTimeDetail(RzOverTimeDetail rzOverTimeDetail) { + + RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeById(rzOverTimeDetail.getOverTimeId()); + SysStaff sysStaff = sysStaffMapper.selectSysStaffByUserId(rzOverTime.getUserId()); //根据ID查询旧数据 RzOverTimeDetail older = rzOverTimeDetailMapper.selectRzOverTimeDetailById(rzOverTimeDetail.getId()); Long hours = (rzOverTimeDetail.getOverTimeEnd().getTime() - rzOverTimeDetail.getOverTimeStart().getTime())/1000/60/60; rzOverTimeDetail.setOverTimeHours(BigDecimal.valueOf(hours)); rzOverTimeDetail.setUpdateTime(DateUtils.getNowDate()); rzOverTimeDetail.setUpdateBy(SecurityUtils.getUsername()); + //计算加班时间 + KqUtils.calculateOverTimeHours(rzOverTimeDetail, sysStaff.getUserId(), sysStaff.getTimeClock()); + int i = rzOverTimeDetailMapper.updateRzOverTimeDetail(rzOverTimeDetail); if(i < 1){ return AjaxResult.error(); } //反写加班总时长 - RzOverTime rzOverTime = rzOverTimeMapper.selectRzOverTimeById(rzOverTimeDetail.getOverTimeId()); + rzOverTime.setOverHours(rzOverTime.getOverHours().add(BigDecimal.valueOf(hours)).subtract(older.getOverTimeHours())); i = rzOverTimeMapper.updateRzOverTime(rzOverTime); if(i < 1){ diff --git a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzSubsidyInfoServiceImpl.java b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzSubsidyInfoServiceImpl.java index e0f88f5..2833380 100644 --- a/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzSubsidyInfoServiceImpl.java +++ b/evo-admin/src/main/java/com/evo/personnelMatters/service/impl/RzSubsidyInfoServiceImpl.java @@ -56,7 +56,7 @@ public class RzSubsidyInfoServiceImpl extends ServiceImpl().eq(RzSubsidyInfo::getName, rzSubsidy.getName()).select(RzSubsidyInfo::getId)) > 0; + return getBaseMapper().selectCount(new LambdaQueryWrapper().eq(RzSubsidyInfo::getName, rzSubsidy.getName()).ne(rzSubsidy.getId() != null, RzSubsidyInfo::getId, rzSubsidy.getId()).select(RzSubsidyInfo::getId)) > 0; } @Override diff --git a/evo-admin/src/main/java/com/evo/system/controller/SysStaffDetailController.java b/evo-admin/src/main/java/com/evo/system/controller/SysStaffDetailController.java index 314b510..edd315e 100644 --- a/evo-admin/src/main/java/com/evo/system/controller/SysStaffDetailController.java +++ b/evo-admin/src/main/java/com/evo/system/controller/SysStaffDetailController.java @@ -52,7 +52,7 @@ public class SysStaffDetailController extends BaseController /** * 获取员工详情详细信息 */ - @PreAuthorize("@ss.hasPermi('system:staffDetail:query')") + @PreAuthorize("@ss.hasPermi('system:staff:detail')") @GetMapping(value = "/byUser/{id}") public AjaxResult getInfobyUser(@PathVariable("id") Long id) { diff --git a/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java b/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java index 9f246bb..7970078 100644 --- a/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java +++ b/evo-admin/src/main/java/com/evo/system/domain/SysStaff.java @@ -1,18 +1,18 @@ package com.evo.system.domain; -import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; - +import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.evo.common.annotation.Excel; +import com.evo.common.core.domain.BaseEntity; import com.evo.common.utils.Collections; import com.evo.common.utils.StringUtils; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import com.evo.common.annotation.Excel; -import com.evo.common.core.domain.BaseEntity; + +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; /** * 员工管理对象 sys_staff @@ -38,6 +38,7 @@ public class SysStaff extends BaseEntity private String companyName; /** 主键ID */ + @TableId(value = "user_id", type = IdType.AUTO) private Long userId; /** 部门ID */ diff --git a/evo-admin/src/main/java/com/evo/system/mapper/SysStaffMapper.java b/evo-admin/src/main/java/com/evo/system/mapper/SysStaffMapper.java index 553b0ac..0ccebb5 100644 --- a/evo-admin/src/main/java/com/evo/system/mapper/SysStaffMapper.java +++ b/evo-admin/src/main/java/com/evo/system/mapper/SysStaffMapper.java @@ -63,11 +63,10 @@ public interface SysStaffMapper extends BaseMapper */ public SysStaff queryysStaffByIdCardAndDeptId(@Param("idCard") String idCard,@Param("deptId") Long deptId); /** - * 根据公司查询编号 - * @param compayName - * @return + * 查询编号 +s * @return */ - public SysStaff querySysStaffOfMaxByCompany(String compayName); + public String queryMaxCode(); /** * 根据月份查询需要统计工资的人员信息 * @param emplDate 入职时间 diff --git a/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java b/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java index 790a89c..210c619 100644 --- a/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java +++ b/evo-admin/src/main/java/com/evo/system/service/impl/SysStaffServiceImpl.java @@ -128,7 +128,7 @@ public class SysStaffServiceImpl extends ServiceImpl i //性别 sysStaff.setSex((Integer.parseInt(sysStaff.getIdCard().substring(16,17)) % 2 == 0) ? "1" : "0"); //员工编码 - sysStaff.setCode(getCodeByCompanyName(sysStaff.getCompanyName())); + sysStaff.setCode(getCodeByCompanyName()); sysStaff.setSeniority(0l); sysStaff.setStatus(Constants.JOB_STATIS_0); sysStaff.setCreateTime(DateUtils.getNowDate()); @@ -239,7 +239,6 @@ public class SysStaffServiceImpl extends ServiceImpl i SysStaff old_staff = getBaseMapper().selectSysStaffByUserId(sysStaff.getUserId()); //判断员工更换公司 if(!old_staff.getCompanyName().equals(sysStaff.getCompanyName())) { - sysStaff.setCode(getCodeByCompanyName(sysStaff.getCompanyName())); SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId()); sysStaffDetail.setSpecialDeduction(DataUtils.DEFAULT_VALUE); sysStaffDetail.setTotalWages(DataUtils.DEFAULT_VALUE); @@ -511,7 +510,7 @@ public class SysStaffServiceImpl extends ServiceImpl i } // 判断员工编码是否存在,不存在,自动生成 if(StringUtils.isEmpty(sysStaff.getCode())){ - sysStaff.setCode(getCodeByCompanyName(sysStaff.getCompanyName())); + sysStaff.setCode(getCodeByCompanyName()); } for (SysDept sysDept : dept_list) { if(sysDept.getDeptName().equals(sysStaff.getDeptName())){ @@ -572,24 +571,25 @@ public class SysStaffServiceImpl extends ServiceImpl i } /** * 根据公司名称得到员工编号 - * @param companyName * @return */ - private String getCodeByCompanyName(String companyName){ + private String getCodeByCompanyName(){ //根据公司名称查询当前公司下的最大编号 - SysStaff macCode = getBaseMapper().querySysStaffOfMaxByCompany(companyName); - if(macCode == null){ - return companyName + "0001"; + String maxCode = getBaseMapper().queryMaxCode(); + if(maxCode == null){ + return "00001"; } - int code = Integer.parseInt(macCode.getCode().replace(companyName,"")) + 1; + int code = Integer.parseInt(maxCode) + 1; if(code < 10){ - return companyName + Constants.SEIZE_A_SEAT_2 + code; + return Constants.SEIZE_A_SEAT_3 + code; }else if(code < 100){ - return companyName + Constants.SEIZE_A_SEAT_1 + code; + return Constants.SEIZE_A_SEAT_2 + code; }else if(code < 1000){ - return companyName + Constants.SEIZE_A_SEAT_0 + code; + return Constants.SEIZE_A_SEAT_1 + code; + }else if(code < 10000){ + return Constants.SEIZE_A_SEAT_0 + code; }else{ - return companyName + code; + return String.valueOf(code); } } /** diff --git a/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml b/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml index 28df233..587a5c2 100644 --- a/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml +++ b/evo-admin/src/main/resources/mapper/system/SysStaffMapper.xml @@ -247,9 +247,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where id_card = #{idCard} and dept_id = #{deptId} and del_flag = '1' - + select max(code) from sys_staff