diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/Constants.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/Constants.java index 3c629ea1..0ad1a257 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/Constants.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/Constants.java @@ -62,6 +62,10 @@ public class Constants { * yyyy-MM-dd格式 */ public static final DateTimeFormatter REPO_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + /** + * yyyy-MM + */ + public static final DateTimeFormatter YEAR_MONTH_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM"); /** * yyyy-MM-dd HH:mm:ss格式 */ diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java index 73692386..4edfece5 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java @@ -155,6 +155,7 @@ public class LocalDateTimeUtils { */ public static List getTheDayOfEachMonthSoFar(LocalDateTime beginTime, LocalDateTime endTime, int day) { List monthlyFirstDays = new ArrayList<>(); + beginTime = beginTime.withDayOfMonth(day); while (!beginTime.isAfter(endTime)) { // 获取当月的1号 LocalDateTime firstDayOfMonth = beginTime.withDayOfMonth(day); diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java index 4cdd6393..9212d6ea 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java @@ -29,6 +29,9 @@ public interface ErrorCodeConstants { ErrorCode NO_NEED_TO_APPLY_FOR_OVERTIME_IF_NOT_IN_THE_ATTENDANCE_GROUP = new ErrorCode(1_009_001_014, "不在考勤组内无需申请加班"); ErrorCode EXCEPTION_OCCURRED_WHILE_OBTAINING_OVERTIME_SETTINGS = new ErrorCode(1_009_001_015, "获取加班设置出现异常"); ErrorCode ABNORMAL_ACCESS_TO_ATTENDANCE_RECORDS = new ErrorCode(1_009_001_016, "获取考勤记录异常"); + ErrorCode OVERTIME_REQUESTS_ALREADY_EXIST_FOR_THE_SAME_TIME_PERIOD = new ErrorCode(1_009_001_018, "已存在相同时间段的加班申请"); + ErrorCode THE_CURRENT_USERS_ATTENDANCE_GROUP_HAS_NOT_SET_OVERTIME_RULES = new ErrorCode(1_009_001_019, "当前用户所在考勤组未设置加班规则"); + ErrorCode OA_REIMBURSEMENT_NOT_EXISTS = new ErrorCode(1_009_001_100, "报销申请不存在"); ErrorCode OA_EVECTION_NOT_EXISTS = new ErrorCode(1_009_001_101, "出差申请不存在"); ErrorCode OA_SEAL_NOT_EXISTS = new ErrorCode(1_009_001_102, "用章申请不存在"); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAOvertimeController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAOvertimeController.java index d9ea8e6c..73b1bca8 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAOvertimeController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAOvertimeController.java @@ -40,7 +40,7 @@ public class BpmOAOvertimeController { private BpmOAOvertimeItemService overtimeItemService; @PostMapping("/create") - @Operation(summary = "创建请求申请") + @Operation(summary = "创建加班申请") public CommonResult createOvertime(@Valid @RequestBody BpmOAOvertimeCreateReqVO createReqVO) { return success(overtimeService.createOvertime(getLoginUserId(), createReqVO)); @@ -54,7 +54,7 @@ public class BpmOAOvertimeController { List itemDOS = overtimeItemService.getByOvertimeId(id); List overtimeDateTimeVOS = BeanUtil.copyToList(itemDOS, BpmOAOvertimeItemVO.class); BpmOAOvertimeRespVO vo = BpmOAOvertimeConvert.INSTANCE.convert(overtime); - return success(vo.setOvertimeDateTimeVOS(overtimeDateTimeVOS)); + return success(vo.setTotalTimeLength(overtime.getTimeLength()).setOvertimeDateTimeVOS(overtimeDateTimeVOS)); } @GetMapping("/getByProcessInstanceId") @@ -65,6 +65,6 @@ public class BpmOAOvertimeController { List itemDOS = overtimeItemService.getByOvertimeId(overtime.getId()); List overtimeDateTimeVOS = BeanUtil.copyToList(itemDOS, BpmOAOvertimeItemVO.class); BpmOAOvertimeRespVO vo = BpmOAOvertimeConvert.INSTANCE.convert(overtime); - return success(vo.setOvertimeDateTimeVOS(overtimeDateTimeVOS)); + return success(vo.setTotalTimeLength(overtime.getTimeLength()).setOvertimeDateTimeVOS(overtimeDateTimeVOS)); } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/overtime/BpmOAOvertimeCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/overtime/BpmOAOvertimeCreateReqVO.java index fb629a5a..c0c3e561 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/overtime/BpmOAOvertimeCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/overtime/BpmOAOvertimeCreateReqVO.java @@ -1,11 +1,14 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.overtime; import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; +import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeDeserializer; +import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeSerializer; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; import javax.validation.constraints.NotNull; import java.math.BigDecimal; @@ -21,8 +24,6 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ */ @Schema(description = "管理后台 - 加班申请创建 Request VO") @Data -@EqualsAndHashCode() -@ToString(callSuper = true) public class BpmOAOvertimeCreateReqVO { @Schema(description = "加班原因", requiredMode = Schema.RequiredMode.REQUIRED) @@ -31,12 +32,10 @@ public class BpmOAOvertimeCreateReqVO { @Schema(description = "加班的开始时间", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "开始时间不能为空") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; @Schema(description = "加班的结束时间", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "结束时间不能为空") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; @Schema(description = "加班日期时间列表", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAEntryServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAEntryServiceImpl.java index 78d1ea01..17dc907d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAEntryServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAEntryServiceImpl.java @@ -147,6 +147,8 @@ public class BpmOAEntryServiceImpl implements BpmOAEntryService { .setUrls(convertList(uploadUserFiles, UploadUserFile::getUrl)) .setUserId(userId); fileApi.updateUserFileUserId(updateReqDTO); + // 更新用户入职时间到users表中 + userApi.updateUserEntryDate(new UserSaveRespDTO().setId(userId).setEntryDate(entry.getEntryDate().atStartOfDay())); } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java index c4e0ea93..11eb7d66 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java @@ -79,13 +79,6 @@ public class BpmOALeaveServiceImpl extends BpmOABaseService implements BpmOALeav @Override @Transactional(rollbackFor = Exception.class) public Long createLeave(Long userId, BpmOALeaveCreateReqVO createReqVO) { - List processingOrPassed = BpmProcessInstanceResultEnum.processingOrPassed(); - List bpmOALeaveDOS = leaveMapper.selectList(new LambdaQueryWrapper() - .eq(BpmOALeaveDO::getUserId, userId) - .le(BpmOALeaveDO::getStartTime, createReqVO.getEndTime()) - .gt(BpmOALeaveDO::getEndTime, createReqVO.getStartTime()) - .in(BpmOALeaveDO::getResult, processingOrPassed) - ); BpmOALeaveDO leave = BpmOALeaveConvert.INSTANCE.convert(createReqVO) .setUserId(userId) .setFileItems(createReqVO.getFileItems()) @@ -93,6 +86,13 @@ public class BpmOALeaveServiceImpl extends BpmOABaseService implements BpmOALeav // 构建请假开始 or 结束时间 LocalDateTime[] times = this.builderLeaveTime(leave); + List processingOrPassed = BpmProcessInstanceResultEnum.processingOrPassed(); + List bpmOALeaveDOS = leaveMapper.selectList(new LambdaQueryWrapper() + .eq(BpmOALeaveDO::getUserId, userId) + .le(BpmOALeaveDO::getStartTime, leave.getEndTime()) + .gt(BpmOALeaveDO::getEndTime, leave.getStartTime()) + .in(BpmOALeaveDO::getResult, processingOrPassed) + ); // -- 判断是否有重复时间 if (CollectionUtil.isNotEmpty(bpmOALeaveDOS)) { for (BpmOALeaveDO bpmOALeaveDO : bpmOALeaveDOS) { @@ -110,7 +110,7 @@ public class BpmOALeaveServiceImpl extends BpmOABaseService implements BpmOALeav // 发起 BPM 流程 Map processInstanceVariables = new HashMap<>(); - processInstanceVariables.put("duration", leave.getDuration()); +// processInstanceVariables.put("duration", leave.getDuration().toString()); String processInstanceId = processInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY) .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(leave.getId()))).getCheckedData(); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAOvertimeServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAOvertimeServiceImpl.java index 371f4b8b..124f16db 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAOvertimeServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAOvertimeServiceImpl.java @@ -2,11 +2,15 @@ package cn.iocoder.yudao.module.bpm.service.oa; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.BetweenFormatter; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.LocalDateTimeUtil; import cn.iocoder.yudao.framework.common.Constants; import cn.iocoder.yudao.framework.common.exception.ErrorCode; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.overtime.BpmOAOvertimeCreateReqVO; @@ -31,6 +35,7 @@ import cn.iocoder.yudao.module.system.api.holiday.dto.OvertimeIncreasesHolidayDT import cn.iocoder.yudao.module.system.api.workovertime.WorkOvertimeApi; import cn.iocoder.yudao.module.system.api.workovertime.vo.WorkOvertimeRuleApiVO; import cn.iocoder.yudao.module.system.api.workovertime.vo.WorkOvertimeRuleItemApiVO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -39,6 +44,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -86,39 +92,62 @@ public class BpmOAOvertimeServiceImpl extends BpmOABaseService implements BpmOAO @Override @Transactional(rollbackFor = Exception.class) public Long createOvertime(Long userId, BpmOAOvertimeCreateReqVO vo) { - // TODO: 2024/10/29 这里还需要判断是否已存在相同时间段的加班申请 + // 判断是否已存在相同时间段的加班申请 List dataTimes = DateUtils.betweenDayList(vo.getStartTime(), vo.getEndTime()); + List processingOrPassed = BpmProcessInstanceResultEnum.processingOrPassed(); + // -- 减去一分钟的时间 - 由于前端可能是一天中的最开始时间 - 这里要处理下 + LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(vo.getStartTime()); + LocalDateTime endTime = LocalDateTimeUtil.endOfDay(vo.getEndTime().plusMinutes(-1)); + List overtimeDOS = overtimeMapper.selectList(new LambdaQueryWrapper() + .eq(BpmOAOvertimeDO::getUserId, userId) + .le(BpmOAOvertimeDO::getStartTime, endTime) + .gt(BpmOAOvertimeDO::getEndTime, beginTime) + .in(BpmOAOvertimeDO::getResult, processingOrPassed) + ); + LocalDateTime[] times = new LocalDateTime[]{beginTime, endTime}; + if (CollectionUtil.isNotEmpty(overtimeDOS)) { + for (BpmOAOvertimeDO overtimeDO : overtimeDOS) { + LocalDateTime[] itemTimes = new LocalDateTime[]{overtimeDO.getStartTime(), overtimeDO.getEndTime()}; + boolean intersects = LocalDateTimeUtils.intersects(times[0], times[1], itemTimes[0], itemTimes[1]); + if (intersects) { + throw exception(OVERTIME_REQUESTS_ALREADY_EXIST_FOR_THE_SAME_TIME_PERIOD); + } + } + } CommonResult resultData = workOvertimeApi.getOvertimeRulesByUserId(userId); + // -- 获取用户考勤信息 if (!resultData.isSuccess()) { throw exception(EXCEPTION_OCCURRED_WHILE_OBTAINING_OVERTIME_SETTINGS); } + // -- 不在考勤组内不需要加班 WorkOvertimeRuleApiVO workOvertimeRuleApiVO = resultData.getCheckedData(); + if (Constants.ZERO.equals(workOvertimeRuleApiVO.getIsGroup())) { + throw exception(NO_NEED_TO_APPLY_FOR_OVERTIME_IF_NOT_IN_THE_ATTENDANCE_GROUP); + } + if (Constants.ZERO.equals(workOvertimeRuleApiVO.getIsOvertime())) { + throw exception(THE_CURRENT_USERS_ATTENDANCE_GROUP_HAS_NOT_SET_OVERTIME_RULES); + } List workOvertimeRuleItems = workOvertimeRuleApiVO.getWorkOvertimeRuleItems(); Map map = workOvertimeRuleItems.stream().collect(Collectors.toMap(WorkOvertimeRuleItemApiVO::getType, Function.identity())); // 根据时间计算是工作日还是节假日还是休息日 Map attendanceInfoByTimeRange = leaveService.getAttendanceInfoByTimeRange( new AttendanceTimeRangeInfoDTO().setUserId(userId).setStartTime(vo.getStartTime()).setEndTime(vo.getEndTime()) ); + for (String dataTime : dataTimes) { AttendanceTimeRangeInfoVO attendanceTimeRangeInfoVO = attendanceInfoByTimeRange.get(dataTime); WorkOvertimeRuleItemApiVO workOvertimeRuleItemApiVO = map.get(attendanceTimeRangeInfoVO.getDatType()); if (workOvertimeRuleItemApiVO.getStatus() == 0) { String msg = "%s不允许加班"; msg = String.format(msg, (dataTime + "号 " + (attendanceTimeRangeInfoVO.getDatType() == 1 ? "工作日" : attendanceTimeRangeInfoVO.getDatType() == 2 ? "休息日" : "节假日"))); - throw exception(new ErrorCode(1_009_001_016, msg)); + throw exception(new ErrorCode(1_009_001_017, msg)); } } - // 判断不在考勤组内 不需要加班 - AttendanceTimeRangeInfoVO attendanceTimeRangeInfoVO = attendanceInfoByTimeRange.get(dataTimes.get(0)); - if (attendanceTimeRangeInfoVO == null || Constants.FALSE.equals(attendanceTimeRangeInfoVO.getInGroup())) { - throw exception(NO_NEED_TO_APPLY_FOR_OVERTIME_IF_NOT_IN_THE_ATTENDANCE_GROUP); - } //插入OA 加班申请 BpmOAOvertimeDO overtime = BpmOAOvertimeConvert.INSTANCE.convert(vo).setUserId(userId) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); - overtimeMapper.insert(overtime); - + overtimeMapper.insert(overtime.setTimeLength(vo.getTotalTimeLength())); // -- 记录一个item表 List itemDOS = BeanUtil.copyToList(vo.getOvertimeDateTimeVOS(), BpmOAOvertimeItemDO.class); @@ -147,8 +176,6 @@ public class BpmOAOvertimeServiceImpl extends BpmOABaseService implements BpmOAO return overtime.getId(); } - // TODO: 2024/10/29 加班申请通过 并且加班时间已过的 - @Override @Transactional(rollbackFor = Exception.class) public void updateOvertimeResult(String processInstanceId, Long id, Integer result) { @@ -180,7 +207,14 @@ public class BpmOAOvertimeServiceImpl extends BpmOABaseService implements BpmOAO if (!resultData.isSuccess()) { throw exception(EXCEPTION_OCCURRED_WHILE_OBTAINING_OVERTIME_SETTINGS); } + // -- 不在考勤组内不需要加班 WorkOvertimeRuleApiVO workOvertimeRuleApiVO = resultData.getCheckedData(); + if (Constants.ZERO.equals(workOvertimeRuleApiVO.getIsGroup())) { + throw exception(NO_NEED_TO_APPLY_FOR_OVERTIME_IF_NOT_IN_THE_ATTENDANCE_GROUP); + } + if (Constants.ZERO.equals(workOvertimeRuleApiVO.getIsOvertime())) { + throw exception(THE_CURRENT_USERS_ATTENDANCE_GROUP_HAS_NOT_SET_OVERTIME_RULES); + } List workOvertimeRuleItems = workOvertimeRuleApiVO.getWorkOvertimeRuleItems(); Map map = workOvertimeRuleItems.stream().collect(Collectors.toMap(WorkOvertimeRuleItemApiVO::getType, Function.identity())); // --- 用户加班时间期间的打卡记录 @@ -199,12 +233,15 @@ public class BpmOAOvertimeServiceImpl extends BpmOABaseService implements BpmOAO WorkOvertimeRuleItemApiVO ruleItem = map.get(item.getDateType()); WorkOvertimeService resource = workOvertimeHandler.getResource(WorkOvertimeEnum.getEnumServerName(ruleItem.getType())); List recordList = recordMap.get(item.getDateTimeStr()); + if (recordList == null) { + recordList = new ArrayList<>(); + } recordList.sort(Comparator.comparing(AttendancePunchRecordVO::getShouldPunchTime)); // -- 计算加班时长 resource.getOvertimeHours(item, recordList, workOvertimeRuleApiVO, ruleItem); editItems.add(item); - - if (ruleItem.getTransformationType() == 1) { + // -- 如果是记为调休 - 并且假期id不为空 + if (ruleItem.getTransformationType() == 1 && ruleItem.getHolidayId() != null) { // -- 计算调休 if (item.getActualTimeLength().compareTo(BigDecimal.ZERO) > 0) { // -- 计算每个调休对象需要进行的调休时长 - 这里的单位是小时 - 还要获取假期的单位 来转换一下 diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/workovertime/WorkOvertimeRestDayServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/workovertime/WorkOvertimeRestDayServiceImpl.java index cb8364b1..7e9d8e15 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/workovertime/WorkOvertimeRestDayServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/workovertime/WorkOvertimeRestDayServiceImpl.java @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.LocalDateTimeUtil; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAOvertimeItemDO; import cn.iocoder.yudao.module.system.api.attendance.vo.AttendancePunchRecordVO; -import cn.iocoder.yudao.module.system.api.workovertime.vo.WorkOvertimeDeductRuleApiVO; import cn.iocoder.yudao.module.system.api.workovertime.vo.WorkOvertimeRuleApiVO; import cn.iocoder.yudao.module.system.api.workovertime.vo.WorkOvertimeRuleItemApiVO; import org.springframework.stereotype.Service; @@ -12,7 +11,6 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.math.BigDecimal; -import java.math.RoundingMode; import java.time.temporal.ChronoUnit; import java.util.List; @@ -37,10 +35,10 @@ public class WorkOvertimeRestDayServiceImpl implements WorkOvertimeRestDayServic } // --------------------- 在审批的时段内,按打卡时长计算 3无需审批,按打卡时长计算 --------------------- BigDecimal overtimeHours = BigDecimal.ZERO; - // -- 节假日 - 打了多久的卡就算多久 - 这里是计算加班时长 - + // -- 休息日 - 打了多久的卡就算多久 - 这里是计算加班时长 - AttendancePunchRecordVO first = CollUtil.getFirst(recordList); AttendancePunchRecordVO last = CollUtil.getLast(recordList); - if (first.getPunchTime() == null || last.getPunchTime() == null) { + if (first == null || first.getPunchTime() == null || last == null || last.getPunchTime() == null) { item.setActualTimeLength(overtimeHours); return; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/workovertime/WorkOvertimeWeekDayServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/workovertime/WorkOvertimeWeekDayServiceImpl.java index 0d9f8e40..579131e4 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/workovertime/WorkOvertimeWeekDayServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/workovertime/WorkOvertimeWeekDayServiceImpl.java @@ -15,9 +15,11 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * 加班 工作日 @@ -47,10 +49,11 @@ public class WorkOvertimeWeekDayServiceImpl implements WorkOvertimeWeekDayServic // 合并 AttendancePunchRecordVO列表中 UpWorkOvertimeTime 的和 Long upWorkOvertimeTime = recordList.stream().filter(a -> //获取正常打卡的上班卡 - a.getStatus().equals(0) && a.getWorkType().equals(1) + a.getStatus().equals(0) && a.getWorkType().equals(0) // 计算班前多少分钟 小于n分钟 则不考虑 && a.getUpWorkOvertimeTime() > 0 && TimeUnit.MILLISECONDS.toMinutes(a.getUpWorkOvertimeTime()) > ruleItem.getBeforeWorkOvertime()) .map(AttendancePunchRecordVO::getUpWorkOvertimeTime) + // TODO: 2024/11/9 这行计算有问题 .reduce(0L, Long::sum); // -- 转换为分钟 long millis = TimeUnit.MILLISECONDS.toMinutes(upWorkOvertimeTime); @@ -82,6 +85,15 @@ public class WorkOvertimeWeekDayServiceImpl implements WorkOvertimeWeekDayServic } public static void main(String[] args) { + // 合并 AttendancePunchRecordVO列表中 UpWorkOvertimeTime 的和 + List recordList = new ArrayList<>(); + List collect = recordList.stream().filter(a -> + //获取正常打卡的上班卡 + TimeUnit.MILLISECONDS.toMinutes(23114096L) > 30) + .map(AttendancePunchRecordVO::getUpWorkOvertimeTime).collect(Collectors.toList()); + System.out.println(collect ); + System.out.println(collect ); + LocalDateTime localDateTime = LocalDateTime.of(2024, 6, 25, 17, 30, 0); LocalDateTime plus = localDateTime.plus(1931472, ChronoUnit.MILLIS); long between = LocalDateTimeUtil.between(localDateTime, plus, ChronoUnit.MINUTES); diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/attendance/dto/AttendanceTimeRangeInfoDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/attendance/dto/AttendanceTimeRangeInfoDTO.java index 75e06f02..653b17fb 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/attendance/dto/AttendanceTimeRangeInfoDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/attendance/dto/AttendanceTimeRangeInfoDTO.java @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.system.api.attendance.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; import java.util.List; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + /** * @author 艾楷 */ @@ -20,11 +23,13 @@ public class AttendanceTimeRangeInfoDTO { * 开始时间 */ @Schema(description = "开始时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; /** * 结束时间 */ @Schema(description = "结束时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; /** diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/holiday/dto/OvertimeIncreasesHolidayDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/holiday/dto/OvertimeIncreasesHolidayDTO.java index 301c5630..0f8c538d 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/holiday/dto/OvertimeIncreasesHolidayDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/holiday/dto/OvertimeIncreasesHolidayDTO.java @@ -27,5 +27,5 @@ public class OvertimeIncreasesHolidayDTO { private Integer unit; @Schema(description = "日折算时长 n小时 = 一天 ") - private Integer conversion; + private BigDecimal conversion; } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java index d36ee377..5bc6925c 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java @@ -82,14 +82,14 @@ public interface AdminUserApi { @Parameter(name = "userId", description = "用户id", example = "1024", required = true) @Parameter(name = "fieldworkFlag", description = "是否可外勤打卡 | 0否 1是", example = "1", required = true) void updateFieldworkType(@RequestParam("userId") Long userId, - @RequestParam("fieldworkFlag") Integer fieldworkFlag); + @RequestParam("fieldworkFlag") Integer fieldworkFlag); @PostMapping(PREFIX + "/updateUserStaffing") @Operation(summary = "修改用户信息") @Parameter(name = "userId", description = "用户id", example = "1024", required = true) @Parameter(name = "userStaffing", description = "用户编制", example = "1", required = true) void updateUserStaffing(@RequestParam("userId") Long userId, - @RequestParam("userStaffing") Integer userStaffing); + @RequestParam("userStaffing") Integer userStaffing); @GetMapping(PREFIX + "/getUserIdsByUserNature") @Operation(summary = "获取所有用户性质为外勤的用户") @@ -101,4 +101,7 @@ public interface AdminUserApi { @Parameter(name = "factoryId", description = "工厂id", example = "1024", required = false) CommonResult> getFactoryUsers(@RequestParam(name = "factoryId", required = false) Long factoryId); + @PostMapping(PREFIX + "/updateUserEntryDate") + @Operation(summary = "更新用户入职信息") + CommonResult updateUserEntryDate(@RequestBody UserSaveRespDTO userSaveRespDTO); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/vo/WorkOvertimeMoreRuleApiVO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/vo/WorkOvertimeMoreRuleApiVO.java index 566433a2..f844a8f6 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/vo/WorkOvertimeMoreRuleApiVO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/vo/WorkOvertimeMoreRuleApiVO.java @@ -26,7 +26,7 @@ public class WorkOvertimeMoreRuleApiVO { private BigDecimal roundingIncrementalValue; @Schema(description = "日折算时长 n小时 = 一天 ") - private Integer conversion; + private BigDecimal conversion; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/vo/WorkOvertimeRuleApiVO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/vo/WorkOvertimeRuleApiVO.java index 68b7ad10..d5ad5ad8 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/vo/WorkOvertimeRuleApiVO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/vo/WorkOvertimeRuleApiVO.java @@ -30,4 +30,10 @@ public class WorkOvertimeRuleApiVO { @Schema(description = "更多规则") private WorkOvertimeMoreRuleApiVO moreRule; + @Schema(description = "是否在考勤组内 0否 1是") + private Integer isGroup = 1; + + @Schema(description = "是否有加班规则 0否 1是") + private Integer isOvertime = 1; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java index 5f090bfb..6d34f2d4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java @@ -115,4 +115,10 @@ public class AdminUserApiImpl implements AdminUserApi { return success(BeanUtils.toBean(factoryUsers, AdminUserRpcVO.class)); } + @Override + public CommonResult updateUserEntryDate(UserSaveRespDTO dto) { + userService.updateUserEntryDate(dto.getId(), dto.getEntryDate()); + return success(true); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/WorkOvertimeApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/WorkOvertimeApiImpl.java index 6bc68255..dcaaef4a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/WorkOvertimeApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/workovertime/WorkOvertimeApiImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.system.api.workovertime; import cn.hutool.core.bean.BeanUtil; +import cn.iocoder.yudao.framework.common.Constants; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.system.api.workovertime.vo.WorkOvertimeRuleApiVO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO; @@ -26,7 +27,13 @@ public class WorkOvertimeApiImpl implements WorkOvertimeApi { WorkOvertimeRuleApiVO vo = new WorkOvertimeRuleApiVO(); //先获取当前用户所在考勤组 - 再根据考勤组 查询对应的加班规则 AttendanceGroupDO attendanceGroupDO = attendanceGroupService.getByUserId(userId); + if (attendanceGroupDO == null) { + return CommonResult.success(vo.setIsGroup(Constants.ZERO)); + } WorkOvertimeRuleDO workOvertimeRuleDO = workOvertimeRuleAttendanceGroupService.getRuleByAttendanceGroupId(attendanceGroupDO.getId()); + if (workOvertimeRuleDO == null){ + return CommonResult.success(vo.setIsOvertime(Constants.ZERO)); + } BeanUtil.copyProperties(workOvertimeRuleDO, vo); return CommonResult.success(vo); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/attendance/vo/AttendancePunchPageVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/attendance/vo/AttendancePunchPageVO.java index a1667251..2e6113d8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/attendance/vo/AttendancePunchPageVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/attendance/vo/AttendancePunchPageVO.java @@ -9,6 +9,7 @@ import lombok.Data; import lombok.experimental.Accessors; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; @Data @@ -28,6 +29,8 @@ public class AttendancePunchPageVO { private Integer punchType = 4; @Schema(description = "当天考勤列表") private List attendanceOnTheDayDTOS; + @Schema(description = "是否加班 0否 1是") + private Integer workOvertimeFlag = 0; /** * redisKey @@ -71,4 +74,16 @@ public class AttendancePunchPageVO { * 当前用户 */ private AdminUserDO user; + + /** + * 处理加班打卡 不计算是否迟到早退 + * @param punchType + */ + public void setPunchType(Integer punchType) { + if (this.getFieldworkFlag() == 0) { + this.punchType = punchType; + } else { + this.punchType = Arrays.asList(0, 2).contains(punchType) ? 0 : 1; + } + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/AttendanceGroupController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/AttendanceGroupController.java index d3ef5404..f45ed53e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/AttendanceGroupController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/AttendanceGroupController.java @@ -93,6 +93,13 @@ public class AttendanceGroupController { return success(BeanUtils.toBean(pageResult, AttendanceGroupRespVO.class)); } + @GetMapping("/getAllFilterWorkOvertimeRule") + @Operation(summary = "获得所有考勤组过滤已绑定过加班规则的") + public CommonResult> getAllFilterWorkOvertimeRule(@RequestParam(required = false) Long workOvertimeRuleId) { + List pageResult = groupService.getAllFilterWorkOvertimeRule(workOvertimeRuleId); + return success(BeanUtils.toBean(pageResult, AttendanceGroupRespVO.class)); + } + @GetMapping("/export-excel") @Operation(summary = "导出考勤组 Excel") @PreAuthorize("@ss.hasPermission('attendance:group:export')") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupPageReqVO.java index 12895a1e..8847af45 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/group/vo/AttendanceGroupPageReqVO.java @@ -25,6 +25,9 @@ public class AttendanceGroupPageReqVO extends PageParam { @Schema(description = "群组名称", example = "李四") private String groupName; + @Schema(description = "考勤人员名称", example = "李四") + private String userNickname; + @Schema(description = "考勤类型 1固定班制 2排班制", example = "1") private Integer type; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java index 57c9e2a6..0da47962 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java @@ -8,6 +8,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Operation; +import javax.annotation.security.PermitAll; import javax.validation.*; import javax.servlet.http.*; import java.util.*; @@ -91,4 +92,4 @@ public class AttendancePunchRecordController { BeanUtils.toBean(list, AttendancePunchRecordRespVO.class)); } -} \ No newline at end of file +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordSaveReqVO.java index 11c3d530..a03b433e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/vo/AttendancePunchRecordSaveReqVO.java @@ -62,6 +62,9 @@ public class AttendancePunchRecordSaveReqVO { @Schema(description = "打卡时间") private LocalDateTime punchTime; + @Schema(description = "日期yyyy-MM-dd格式 (实际是哪一天)") + private String actualDayTime; + @Schema(description = "打卡备注", example = "你说的对") private String remark; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java index c9997e5f..fb3a273e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java @@ -42,4 +42,7 @@ public class UserPageReqVO extends PageParam { @Schema(description = "部门ids", example = "1024") private List deptIds; + @Schema(description = "考勤组ids", example = "1024") + private List groupIds; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRulePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRulePageReqVO.java index 35c087da..fae4e8ad 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRulePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRulePageReqVO.java @@ -29,7 +29,7 @@ public class WorkOvertimeMoreRulePageReqVO extends PageParam { private BigDecimal roundingIncrementalValue; @Schema(description = "日折算时长 n小时 = 一天 ") - private Integer conversion; + private BigDecimal conversion; @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRuleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRuleRespVO.java index 616e2555..fad6f9d1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRuleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRuleRespVO.java @@ -36,7 +36,7 @@ public class WorkOvertimeMoreRuleRespVO { @Schema(description = "日折算时长 n小时 = 一天 ") @ExcelProperty("日折算时长 n小时 = 一天 ") - private Integer conversion; + private BigDecimal conversion; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRuleSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRuleSaveReqVO.java index e2d93458..a121637a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRuleSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/workovertime/vo/WorkOvertimeMoreRuleSaveReqVO.java @@ -27,7 +27,7 @@ public class WorkOvertimeMoreRuleSaveReqVO { private BigDecimal roundingIncrementalValue; @Schema(description = "日折算时长 n小时 = 一天 ") - private Integer conversion; + private BigDecimal conversion; @Schema(description = "更多规则拓展列表") private List moreRuleExtList; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/worklog/HolidayRemindConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/worklog/HolidayRemindConvert.java index e96d5286..79c3cd7f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/worklog/HolidayRemindConvert.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/worklog/HolidayRemindConvert.java @@ -15,11 +15,10 @@ public interface HolidayRemindConvert { /** * @param openId 微信小程序唯一id - * @param nickname 发布人姓名 * @param miniProgramState 小程序的状态 * @return */ - default SubscribeMessageReqDTO convertHolidayRemind(String openId, String comment, String nickname, String miniProgramState) { + default SubscribeMessageReqDTO convertHolidayRemind(String openId, String comment, String miniProgramState) { SubscribeMessageReqDTO message = new SubscribeMessageReqDTO(); message.setToUser(openId); message.setTemplateId("fH29xjNb8pe-7onQ-wE3QrBAC-y8aaC_oosYZKNMtzM"); @@ -27,14 +26,14 @@ public interface HolidayRemindConvert { //消息类型 MsgData noticeType = new MsgData(); noticeType.setName("phrase8"); - noticeType.setValue("评论回复"); + noticeType.setValue("假期提醒"); message.addData(noticeType); //发送人 MsgData publishMan = new MsgData(); publishMan.setName("thing16"); - publishMan.setValue(nickname); + publishMan.setValue("系统提醒"); message.addData(publishMan); //发送时间 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/workovertime/WorkOvertimeMoreRuleDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/workovertime/WorkOvertimeMoreRuleDO.java index c8b02f47..c4f88112 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/workovertime/WorkOvertimeMoreRuleDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/workovertime/WorkOvertimeMoreRuleDO.java @@ -49,7 +49,7 @@ public class WorkOvertimeMoreRuleDO extends BaseDO { /** * 日折算时长 n小时 = 一天 */ - private Integer conversion; + private BigDecimal conversion; /** * 更多规则拓展列表 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/attendance/group/AttendanceGroupMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/attendance/group/AttendanceGroupMapper.java index 86303756..2b029869 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/attendance/group/AttendanceGroupMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/attendance/group/AttendanceGroupMapper.java @@ -49,4 +49,11 @@ public interface AttendanceGroupMapper extends BaseMapperX { * @return */ IPage selectPageList(@Param("vo") AttendanceGroupPageReqVO vo, @Param("page") Page page); + + /** + * 获取所有考勤组过滤绑定过加班规则的 + * + * @return + */ + List getAllFilterWorkOvertimeRule(@Param("workOvertimeRuleId") Long workOvertimeRuleId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/holiday/HolidayGrantJob.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/holiday/HolidayGrantJob.java index ceb47516..6a73a1f7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/holiday/HolidayGrantJob.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/holiday/HolidayGrantJob.java @@ -29,8 +29,6 @@ import java.util.stream.Collectors; @Slf4j public class HolidayGrantJob { - // TODO: 2024/4/22 - 每十分钟执行一次 将漏打卡的设为缺卡 这里的update要保证命中索引 保证是行锁 不然容易导致锁表 - @Resource private HolidayBalanceSettingService holidayBalanceSettingService; @Resource @@ -74,7 +72,7 @@ public class HolidayGrantJob { && holidayBalanceSettingDO.getIssueTime() != null && holidayBalanceSettingDO.getIssueTime().isBefore(now)).collect(Collectors.toList()); - if (CollectionUtil.isEmpty(fixedGrantList)) { + if (CollectionUtil.isNotEmpty(fixedGrantList)) { for (HolidayBalanceSettingDO holidayBalanceSettingDO : fixedGrantList) { // 计算下一次发放日期 LocalDateTime issueTime = holidaySettingService.calculateNextReleaseDate(now, holidayBalanceSettingDO); @@ -87,25 +85,6 @@ public class HolidayGrantJob { holidayBalanceSettingService.batchUpdate(editList); } - // TODO: 2024/10/23 这里要怎么去判断按照用户入职时间的话 是否发放过? - // -- 过滤出按照员工入职时间发放的 -// List employmentGrantList = list.stream().filter(holidayBalanceSettingDO -> -// holidayBalanceSettingDO.getType() == 2 && holidayBalanceSettingDO.getIssueTimeType() == 1) -// .collect(Collectors.toList()); -// // -- 获取到这些后 - 再获取到用户 -// if (CollectionUtil.isNotEmpty(employmentGrantList)) { -// for (HolidayBalanceSettingDO holidayBalanceSettingDO : employmentGrantList) { -// Long holidaySettingId = holidayBalanceSettingDO.getHolidaySettingId(); -// List rangeList = holidaySettingRangeMap.get(holidaySettingId); -// List usersByRange = holidaySettingRangeService.getUsersByRange(rangeList); -// // 搞个表记录下按照员工入职时间发放的 -// List users = usersByRange.stream().filter(a -> a.getEntryDate() != null && a.getEntryDate().isBefore(now)).collect(Collectors.toList()); -// if (CollectionUtil.isNotEmpty(users)) { -// holidayUserRecordService.grant(holidaySettingMap.get(holidaySettingId), holidaySettingRangeMap.get(holidaySettingId), holidayBalanceSettingDO, holidayWorkingAgeDOMap.get(holidaySettingId)); -// } -// } -// } - log.info("结束 发放假期"); // 返回执行成功 return ReturnT.SUCCESS; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/holiday/HolidayRemindJob.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/holiday/HolidayRemindJob.java index ae193aa4..84db7a63 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/holiday/HolidayRemindJob.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/holiday/HolidayRemindJob.java @@ -30,8 +30,6 @@ import java.util.stream.Collectors; @Slf4j public class HolidayRemindJob { - // TODO: 2024/4/22 - 每十分钟执行一次 将漏打卡的设为缺卡 这里的update要保证命中索引 保证是行锁 不然容易导致锁表 - @Resource private HolidayBalanceSettingService holidayBalanceSettingService; @Resource @@ -115,6 +113,9 @@ public class HolidayRemindJob { // 获取到主管 - 这里获取主管需要查询到对应用户所在的部门 - 完了后 在获取部门中的userIds AdminUserDO adminUserDO = leaderMap.get(user.getDeptId()); remindDTO.setUserId(adminUserDO.getId()); + if (leaderMap.get(adminUserDO.getId()) == null || leaderMap.get(adminUserDO.getId()).getOpenId() == null) { + continue; + } remindDTO.setOpenId(leaderMap.get(adminUserDO.getId()).getOpenId()); remindDTO.setMsg(user.getNickname() + "的" + name + "假期即将过期"); holidayRemindDTOS.add(remindDTO); @@ -127,9 +128,11 @@ public class HolidayRemindJob { // 获取到主管 - 这里获取主管需要查询到对应用户所在的部门 - 完了后 在获取部门中的userIds AdminUserDO adminUserDO = leaderMap.get(user.getDeptId()); remindDTO.setUserId(adminUserDO.getId()); - remindDTO.setOpenId(leaderMap.get(adminUserDO.getId()).getOpenId()); - remindDTO.setMsg(user.getNickname() + "的" + name + "假期即将过期"); - holidayRemindDTOS.add(remindDTO); + if (leaderMap.get(adminUserDO.getId()) != null && leaderMap.get(adminUserDO.getId()).getOpenId() == null) { + remindDTO.setOpenId(leaderMap.get(adminUserDO.getId()).getOpenId()); + remindDTO.setMsg(user.getNickname() + "的" + name + "假期即将过期"); + holidayRemindDTOS.add(remindDTO); + } } } } @@ -138,7 +141,7 @@ public class HolidayRemindJob { for (HolidayRemindDTO holidayRemindDTO : holidayRemindDTOS) { try { subscribeMessageSendApi.sendWorkLogComment(HolidayRemindConvert.INSTANCE.convertHolidayRemind( - holidayRemindDTO.getOpenId(), holidayRemindDTO.getMsg(), userMap.get(holidayRemindDTO.getUserId()).getNickname(), + holidayRemindDTO.getOpenId(), holidayRemindDTO.getMsg(), "formal")); } catch (Exception e) { log.error("发送假期过期提醒失败:{}", holidayRemindDTO); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceServiceImpl.java index 60c24253..10690746 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/AttendanceServiceImpl.java @@ -220,11 +220,12 @@ public class AttendanceServiceImpl implements AttendanceService { .setDayTime(pageVO.getTargetDayStr()) .setShouldPunchTime(pageVO.getShouldPunchTime()) .setPunchTime(dto.getLocalDateTime()) + .setActualDayTime(pageVO.getTargetDayStr()) //取绝对值 如果status是负数则变为正数 .setLateTime(Constants.ONE.equals(status) ? Math.abs(LocalDateTimeUtil.between(dto.getLocalDateTime(), pageVO.getShouldPunchTime(), ChronoUnit.MILLIS)) : 0L) .setLeaveEarlyTime(Constants.TWO.equals(status) ? Math.abs(LocalDateTimeUtil.between(dto.getLocalDateTime(), pageVO.getShouldPunchTime(), ChronoUnit.MILLIS)) : 0L) - .setDownWorkOvertimeTime(Constants.ZERO.equals(status) && Constants.ONE.equals(pageVO.getPunchType()) ? Math.abs(LocalDateTimeUtil.between(dto.getLocalDateTime(), pageVO.getShouldPunchTime(), ChronoUnit.MILLIS)) : 0L) - .setUpWorkOvertimeTime(Constants.ZERO.equals(status) && Constants.ZERO.equals(pageVO.getPunchType()) ? Math.abs(LocalDateTimeUtil.between(dto.getLocalDateTime(), pageVO.getShouldPunchTime(), ChronoUnit.MILLIS)) : 0L) + .setDownWorkOvertimeTime(Constants.ZERO.equals(status) && Constants.ONE.equals(pageVO.getPunchType()) && Constants.ZERO.equals(pageVO.getWorkOvertimeFlag()) ? Math.abs(LocalDateTimeUtil.between(dto.getLocalDateTime(), pageVO.getShouldPunchTime(), ChronoUnit.MILLIS)) : 0L) + .setUpWorkOvertimeTime(Constants.ZERO.equals(status) && Constants.ZERO.equals(pageVO.getPunchType()) && Constants.ZERO.equals(pageVO.getWorkOvertimeFlag()) ? Math.abs(LocalDateTimeUtil.between(dto.getLocalDateTime(), pageVO.getShouldPunchTime(), ChronoUnit.MILLIS)) : 0L) .setRemark(dto.getRemark()) .setImage(dto.getImage()) .setPunchAddress(dto.getPunchAddress()); @@ -363,7 +364,6 @@ public class AttendanceServiceImpl implements AttendanceService { break; } else { // 如果是未打卡 - 判断当前时间是否在打卡区间内 - 如果不在的话直接set缺卡 - // - 定时任务还没来得及刷新redis 数据 - 这里需要手动刷新 updateRedis = true; attendanceOnTheDayDTO.setPunchStatus(AttendanceOnTheDayDTO.PUNCH_STATUS_MISS); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/fixed/AttendanceFixedServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/fixed/AttendanceFixedServiceImpl.java index 0fbb09f6..dc25d2dd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/fixed/AttendanceFixedServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/fixed/AttendanceFixedServiceImpl.java @@ -232,16 +232,24 @@ public class AttendanceFixedServiceImpl implements AttendanceFixedService, Punch // -- 判断是否根据节假日自动排班 - 如果是的话 - 根据排班的来 Boolean isHolidayFlag = Constants.TRUE.equals(activationGroup.getAutoHolidaysFlag()) ? attendanceService.isHoliday(dto.getLocalDateTime()) : null; - // -- 当前是节假日 并且是放假 - if (isHolidayFlag != null && isHolidayFlag) { - return vo.setTodayNeedAttendance(Constants.FALSE); - } - //获取到当天是周几 - 如果是节假日补班的话 - 班次日期就是8 - int week = isHolidayFlag != null ? 8 : dto.getLocalDateTime().getDayOfWeek().getValue(); + // -- 先判断当前是否是节假日放假的日子 - 如果是的话 设为 -1 查询加班加班班次 如果不是的话 判断当前是否是补班 如果是的话设为8 为补班日 - 最后获取当前是周几(后续判断这个周几是否是有班次 - 没有的话再查询下 -1 是否有加班班次) + int week = isHolidayFlag != null && isHolidayFlag ? -1 : (isHolidayFlag != null ? 8 : dto.getLocalDateTime().getDayOfWeek().getValue()); AttendanceFixedDO attendanceFixedDO = this.getByGroupIdAndWeek(activationGroup.getId(), week); // -- 当前没有班次 - 不需要考勤 if (attendanceFixedDO == null || attendanceFixedDO.getAttendanceGroupShiftId() == null) { - return vo.setTodayNeedAttendance(Constants.FALSE); + // -- 再获取一次加班班次 - 判断下是否有加班日 没有的话直接返回 + if (week != -1) { + attendanceFixedDO = this.getByGroupIdAndWeek(activationGroup.getId(), -1); + if (attendanceFixedDO == null || attendanceFixedDO.getAttendanceGroupShiftId() == null) { + return vo.setTodayNeedAttendance(Constants.FALSE); + } else { + vo.setWorkOvertimeFlag(Constants.ONE); + } + } else { + return vo.setTodayNeedAttendance(Constants.FALSE); + } + } else if (week == -1) { + vo.setWorkOvertimeFlag(Constants.ONE); } vo.setAttendanceGroupShiftId(attendanceFixedDO.getAttendanceGroupShiftId()); attendanceService.calculatePunch(dto, vo); @@ -292,9 +300,9 @@ public class AttendanceFixedServiceImpl implements AttendanceFixedService, Punch LocalDateTime localDateTime = LocalDateTimeUtil.parseDate(time, Constants.REPO_DATE_FORMAT).atStartOfDay(); Boolean holiday = attendanceService.isHoliday(localDateTime); // -- 如果是节假日的话先插入下是节假日 - 不管上不上班 - attendanceTimeRangeInfoVO.setDatType(holiday ? Constants.THREE : Constants.ONE); Boolean isHolidayFlag = Constants.TRUE.equals(dto.getAutoHolidaysFlag()) ? holiday : null; + attendanceTimeRangeInfoVO.setDatType(isHolidayFlag != null && isHolidayFlag ? Constants.THREE : Constants.ONE); // -- 当前是节假日 并且是放假 if (isHolidayFlag != null && isHolidayFlag) { map.put(time, attendanceTimeRangeInfoVO); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/group/AttendanceGroupService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/group/AttendanceGroupService.java index 6c59a105..a0c0bc3d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/group/AttendanceGroupService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/group/AttendanceGroupService.java @@ -68,6 +68,11 @@ public interface AttendanceGroupService { */ List getAll(); + /** + * 获取所有考勤组过滤绑定过加班规则的 + * @return + */ + List getAllFilterWorkOvertimeRule(Long workOvertimeRuleId); /** * 获取使用班次id的考勤组ids * @@ -76,4 +81,4 @@ public interface AttendanceGroupService { */ List getUseGroupIds(Long shiftId); -} \ No newline at end of file +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/group/AttendanceGroupServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/group/AttendanceGroupServiceImpl.java index 165e6ac8..9843de0d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/group/AttendanceGroupServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/group/AttendanceGroupServiceImpl.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.system.controller.admin.group.vo.AttendanceGroupPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.group.vo.AttendanceGroupSaveReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.assets.AssetsDO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.groupuser.AttendanceGroupUserDO; import cn.iocoder.yudao.module.system.dal.mysql.attendance.group.AttendanceGroupMapper; @@ -116,6 +115,11 @@ public class AttendanceGroupServiceImpl implements AttendanceGroupService { return attendanceGroupMapper.selectList(); } + @Override + public List getAllFilterWorkOvertimeRule(Long workOvertimeRuleId) { + return attendanceGroupMapper.getAllFilterWorkOvertimeRule(workOvertimeRuleId); + } + @Override public List getUseGroupIds(Long shiftId) { List fixedGroupIds = attendanceFixedService.getUseGroupIds(shiftId); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punchrecord/AttendancePunchRecordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punchrecord/AttendancePunchRecordServiceImpl.java index 875cc7c1..2d93cf03 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punchrecord/AttendancePunchRecordServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punchrecord/AttendancePunchRecordServiceImpl.java @@ -11,25 +11,40 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.system.api.attendance.dto.AttendancePunchRecordDTO; +import cn.iocoder.yudao.module.system.api.subscribe.SubscribeMessageSendApi; import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordSaveReqVO; +import cn.iocoder.yudao.module.system.controller.admin.user.dto.UserDTO; +import cn.iocoder.yudao.module.system.convert.worklog.HolidayRemindConvert; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.groupshiftitem.AttendanceGroupShiftItemDO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.groupuser.AttendanceGroupUserDO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.punchrecord.AttendancePunchRecordDO; +import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; +import cn.iocoder.yudao.module.system.dal.dataobject.holiday.holidaybalancesetting.HolidayBalanceSettingDO; +import cn.iocoder.yudao.module.system.dal.dataobject.holiday.holidaysetting.HolidaySettingDO; +import cn.iocoder.yudao.module.system.dal.dataobject.holiday.holidayuserrecord.HolidayUserRecordDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.mysql.attendance.group.AttendanceGroupMapper; import cn.iocoder.yudao.module.system.dal.mysql.attendance.groupuser.AttendanceGroupUserMapper; import cn.iocoder.yudao.module.system.dal.mysql.attendance.punchrecord.AttendancePunchRecordMapper; +import cn.iocoder.yudao.module.system.job.holiday.dto.HolidayRemindDTO; import cn.iocoder.yudao.module.system.service.attendance.AttendanceService; import cn.iocoder.yudao.module.system.service.attendance.fixed.AttendanceFixedService; import cn.iocoder.yudao.module.system.service.attendance.groupshiftitem.AttendanceGroupShiftItemService; import cn.iocoder.yudao.module.system.service.attendance.punch.dto.AttendanceOnTheDayDTO; import cn.iocoder.yudao.module.system.service.attendance.scheduling.AttendanceSchedulingService; +import cn.iocoder.yudao.module.system.service.dept.DeptService; +import cn.iocoder.yudao.module.system.service.holiday.holidaybalancesetting.HolidayBalanceSettingService; +import cn.iocoder.yudao.module.system.service.holiday.holidaysetting.HolidaySettingService; +import cn.iocoder.yudao.module.system.service.holiday.holidaysettingrange.HolidaySettingRangeService; +import cn.iocoder.yudao.module.system.service.holiday.holidayuserrecord.HolidayUserRecordService; +import cn.iocoder.yudao.module.system.service.holiday.holidayworkingage.HolidayWorkingAgeService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.StringRedisTemplate; @@ -54,6 +69,7 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.PUNCH_RECO * @author 艾楷 */ @Service +@Slf4j @Validated public class AttendancePunchRecordServiceImpl extends ServiceImpl implements AttendancePunchRecordService { @@ -77,8 +93,6 @@ public class AttendancePunchRecordServiceImpl extends ServiceImpl holidaySettingRanges, List holidayWorkingAges) { // ------- 插入假期设置 holidaySettingMapper.insert(holidaySetting); @@ -182,7 +183,7 @@ public class HolidaySettingServiceImpl implements HolidaySettingService { } // -- 计算假期 if (holidayBalanceSetting.getStatus() == 1) { - holidayUserRecordService.grant(holidaySetting, holidaySettingRanges, holidayBalanceSetting, holidayWorkingAges); + holidayUserRecordService.init(holidaySetting, holidaySettingRanges, holidayBalanceSetting, holidayWorkingAges); } } @@ -198,11 +199,22 @@ public class HolidaySettingServiceImpl implements HolidaySettingService { LocalDateTime issueTime = null; if (holidayBalanceSetting.getType() == 1) { //获取下个月几号 - issueTime = now.withDayOfMonth(holidayBalanceSetting.getIssueTimeType()).plusMonths(1); + //判断是否大于当前时间 - 如果是的话则已经有发放 + LocalDateTime localDateTime = now.withDayOfMonth(holidayBalanceSetting.getIssueTimeType()); + if (now.isBefore(localDateTime)) { + issueTime = localDateTime; + } else { + issueTime = localDateTime.plusMonths(1); + } } else if (holidayBalanceSetting.getType() == 2) { if (holidayBalanceSetting.getIssueTimeType() == 2) { //获取明年1月1号 - issueTime = now.plusYears(1).withMonth(Month.JANUARY.getValue()).withDayOfMonth(1); + LocalDateTime localDateTime = now.withMonth(Month.JANUARY.getValue()).withDayOfMonth(1); + if (now.isBefore(localDateTime)) { + issueTime = localDateTime; + } else { + issueTime = localDateTime.plusYears(1); + } } } // -- 取一天的开始时间 @@ -247,7 +259,7 @@ public class HolidaySettingServiceImpl implements HolidaySettingService { @Override public List listByIds(List holidaySettingIds) { - if (CollectionUtil.isEmpty(holidaySettingIds)){ + if (CollectionUtil.isEmpty(holidaySettingIds)) { return Collections.emptyList(); } return holidaySettingMapper.selectBatchIds(holidaySettingIds); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/holiday/holidayuserrecord/HolidayUserRecordService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/holiday/holidayuserrecord/HolidayUserRecordService.java index ded0884a..fdfc1220 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/holiday/holidayuserrecord/HolidayUserRecordService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/holiday/holidayuserrecord/HolidayUserRecordService.java @@ -42,7 +42,7 @@ public interface HolidayUserRecordService { void createUserHoliday(CreateUserHolidayDTO dto); /** - * 创建用户请假(用于用户主动请假) + * 假期逾期 * * @param holidayUserRecords */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/holiday/holidayuserrecord/HolidayUserRecordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/holiday/holidayuserrecord/HolidayUserRecordServiceImpl.java index 11a9a19b..877faaa0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/holiday/holidayuserrecord/HolidayUserRecordServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/holiday/holidayuserrecord/HolidayUserRecordServiceImpl.java @@ -236,7 +236,7 @@ public class HolidayUserRecordServiceImpl implements HolidayUserRecordService { return holidayUserRecordMapper.selectList(new LambdaQueryWrapper() .eq(HolidayUserRecordDO::getUserId, userId) .eq(HolidayUserRecordDO::getHolidaySettingId, holidaySettingId) - .orderByDesc(HolidayUserRecordDO::getReleaseTime)); + .orderByDesc(HolidayUserRecordDO::getCreateTime)); } @Override @@ -330,7 +330,8 @@ public class HolidayUserRecordServiceImpl implements HolidayUserRecordService { holidayUserRecordDO.setRemark(remark + localDateTimeBigDecimalEntry.getValue() + (holidaySetting.getMinUnit() == 3 ? "小时" : "天") + holidaySetting.getName()); holidayUserRecordDO.setReason(reason); // -- 如果是0的话就不记录了 - if (BigDecimal.ZERO.compareTo(holidayUserRecordDO.getHolidayBalance()) == 0) { + if (BigDecimal.ZERO.compareTo(holidayUserRecordDO.getHolidayBalance()) == 0 + || (expiredTime != null && expiredTime.isBefore(now))) { continue; } newHolidayUserRecordDOList.add(holidayUserRecordDO); @@ -360,7 +361,7 @@ public class HolidayUserRecordServiceImpl implements HolidayUserRecordService { List newHolidayUserDOList, LocalDateTime now, String remark, Integer direction, String reason) { BigDecimal quota = userQuotaMap.get(userId); // -- 如果是0的话就不记录了 - if (BigDecimal.ZERO.compareTo(quota) == 0) { + if (quota == null || BigDecimal.ZERO.compareTo(quota) == 0) { return; } HolidayUserDO holidayUserDO = holidayUserDOMap.get(userId); @@ -385,7 +386,8 @@ public class HolidayUserRecordServiceImpl implements HolidayUserRecordService { holidayUserRecordDO.setExpirationReminderFlag(1); holidayUserRecordDO.setExpiredDeductionFlag(1); } - holidayUserRecordDO.setRemark(remark + quota + (holidaySetting.getMinUnit() == 3 ? "小时" : "天") + holidaySetting.getName()); + //quota保留两位小数 + holidayUserRecordDO.setRemark(remark + quota.setScale(2, RoundingMode.HALF_UP) + (holidaySetting.getMinUnit() == 3 ? "小时" : "天") + holidaySetting.getName()); holidayUserRecordDO.setReason(reason); newHolidayUserRecordDOList.add(holidayUserRecordDO); BigDecimal holidayBalance = holidayUserDO.getHolidayBalance().add(direction == 0 ? quota : quota.negate()); @@ -619,6 +621,7 @@ public class HolidayUserRecordServiceImpl implements HolidayUserRecordService { continue; } if (holidayBalanceSettingDO.getQuotaRule() == 1) { + // TODO: 2024/11/6 // -- actualWorkFlag 没有判断这个 - 暂时去掉 quotaMap.put(user.getId(), new BigDecimal(holidayBalanceSettingDO.getQuota().toString())); } else { Map holidayWorkingAgeMap = holidayWorkingAgeDOS.stream().collect(Collectors.toMap(HolidayWorkingAgeDO::getYears, HolidayWorkingAgeDO::getNum)); @@ -674,7 +677,7 @@ public class HolidayUserRecordServiceImpl implements HolidayUserRecordService { List holidayUserDOS = holidayUserMapper.selectList(new LambdaQueryWrapper().eq(HolidayUserDO::getUserId, userId) .eq(HolidayUserDO::getHolidaySettingId, dto.getHolidaySettingId())); // 过滤掉不适用的 - if (CollectionUtils.isEmpty(holidayUserDOS)){ + if (CollectionUtils.isEmpty(holidayUserDOS)) { return; } LocalDateTime now = LocalDateTime.now(); @@ -714,12 +717,12 @@ public class HolidayUserRecordServiceImpl implements HolidayUserRecordService { if (dto.getUnit() == 1) { if (minUnit == 1 || minUnit == 2) { // 转换为天 - - holidayBalance = dto.getHolidayBalance().divide(BigDecimal.valueOf(dto.getConversion()), 2, RoundingMode.HALF_UP); + holidayBalance = dto.getHolidayBalance().divide(dto.getConversion(), 2, RoundingMode.HALF_UP); } } else { // -- 转换为小时 if (minUnit == 3) { - holidayBalance = dto.getHolidayBalance().multiply(BigDecimal.valueOf(dto.getConversion())); + holidayBalance = dto.getHolidayBalance().multiply(dto.getConversion()); } } return holidayBalance; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java index b4000468..f4585e65 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java @@ -14,6 +14,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import javax.validation.Valid; import java.io.InputStream; +import java.time.LocalDateTime; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -106,8 +107,8 @@ public interface AdminUserService { /** * 修改用户编制 * - * @param id 用户编号 - * @param userStaffing 编制 + * @param id 用户编号 + * @param userStaffing 编制 */ void updateUserStaffing(Long id, Integer userStaffing); @@ -161,6 +162,7 @@ public interface AdminUserService { /** * 获取用户分页 - 带部门名称 - + * * @param reqVO * @return */ @@ -398,8 +400,17 @@ public interface AdminUserService { /** * 获得指定身份证号码的用户列表 + * * @param idcards 身份证号码列表 * @return 用户列表 */ List getUserListByIdCard(List idcards); + + /** + * 更新用户入职时间 + * + * @param id + * @param entryDate + */ + void updateUserEntryDate(Long id, LocalDateTime entryDate); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index 0f51062d..01296c77 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -795,4 +795,9 @@ public class AdminUserServiceImpl implements AdminUserService { return userMapper.selectList(new LambdaQueryWrapperX() .inIfPresent(AdminUserDO::getIdcard, idCards)); } + + @Override + public void updateUserEntryDate(Long id, LocalDateTime entryDate) { + userMapper.updateById(new AdminUserDO().setId(id).setEntryDate(entryDate)); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/workovertime/WorkOvertimeRuleServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/workovertime/WorkOvertimeRuleServiceImpl.java index da5a9b91..14e24f52 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/workovertime/WorkOvertimeRuleServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/workovertime/WorkOvertimeRuleServiceImpl.java @@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.system.controller.admin.workovertime.vo.*; import cn.iocoder.yudao.module.system.dal.dataobject.workovertime.*; import cn.iocoder.yudao.module.system.dal.mysql.workovertime.*; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import org.springframework.stereotype.Service; @@ -210,6 +211,9 @@ public class WorkOvertimeRuleServiceImpl implements WorkOvertimeRuleService { public void deleteWorkOvertimeRule(Long id) { // 删除 workOvertimeRuleMapper.deleteById(id); + // 同步删除考勤组加班规则关联数据 + workOvertimeRuleAttendanceGroupMapper.delete(new LambdaQueryWrapper() + .eq(WorkOvertimeRuleAttendanceGroupDO::getRuleId, id)); } @Override diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/group/AttendanceGroupMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/group/AttendanceGroupMapper.xml index e457fe37..f198d11b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/group/AttendanceGroupMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/group/AttendanceGroupMapper.xml @@ -34,6 +34,10 @@ WHERE a.deleted = 0 ) as b on a.id = b.attendance_group_id + + LEFT JOIN kq_attendance_group_user as c on a.id = c.attendance_group_id and c.deleted = 0 + LEFT JOIN system_users as d on c.user_id = d.id and d.deleted = 0 + a.deleted = 0 @@ -59,7 +63,23 @@ #{userId} + + and d.nickname like CONCAT( '%', #{vo.userNickname}, '%' ) + GROUP BY a.id + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/scheduling/AttendanceSchedulingMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/scheduling/AttendanceSchedulingMapper.xml index 9db8bf78..b305e53e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/scheduling/AttendanceSchedulingMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/scheduling/AttendanceSchedulingMapper.xml @@ -16,6 +16,7 @@ from kq_attendance_scheduling where deleted = 0 + and index_day > 0 group by attendance_group_id - \ No newline at end of file + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/AdminUserMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/AdminUserMapper.xml index 52be5161..a74c677a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/AdminUserMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/AdminUserMapper.xml @@ -124,6 +124,9 @@ select a.*,b.name as deptName from system_users as a left join system_dept as b on a.dept_id = b.id + + left join kq_attendance_group_user c on a.id = c.user_id + a.deleted = 0 and a.user_type = 1 @@ -153,6 +156,12 @@ #{deptId} + + and c.attendance_group_id in + + #{groupId} + +