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 eff45e89..b6956d2d 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 @@ -72,14 +72,6 @@ public class AttendanceGroupController { } - @GetMapping("/test") - @PermitAll - public CommonResult test() { - groupService.test(); - return success("ok"); - } - - @GetMapping("/page") @Operation(summary = "获得考勤组分页") @PreAuthorize("@ss.hasPermission('attendance:group:query')") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/AttendanceGroupShiftController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/AttendanceGroupShiftController.java index fed11962..3eccd30b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/AttendanceGroupShiftController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupshift/AttendanceGroupShiftController.java @@ -50,7 +50,7 @@ public class AttendanceGroupShiftController { return success(groupShiftService.createGroupShift(createReqVO)); } - // TODO: 2024/6/5 如果返回的有值 (判断不是空数组) - 那么前端 跳出提示框 (该班次已有考勤组在使用请选择更新方式) 下面两个按钮 立即生效 和 (推荐)次日生效 + // 如果返回的有值 (判断不是空数组) - 那么前端 跳出提示框 (该班次已有考勤组在使用请选择更新方式) 下面两个按钮 立即生效 和 (推荐)次日生效 @PutMapping("/update") @Operation(summary = "更新考勤组班次") @PreAuthorize("@ss.hasPermission('attendance:group-shift:update')") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/AttendanceGroupUserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/AttendanceGroupUserController.java index 395f40c9..88ddb4b3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/AttendanceGroupUserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/AttendanceGroupUserController.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.AttendanceGroupUserCreateOrDelVO; import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.AttendanceGroupUserPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.AttendanceGroupUserRespVO; import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.AttendanceGroupUserSaveReqVO; @@ -39,10 +40,17 @@ public class AttendanceGroupUserController { @PostMapping("/createOrDel") @Operation(summary = "创建删除考勤组人员") @PreAuthorize("@ss.hasPermission('attendance:group-user:create')") - public CommonResult createOrDel(@RequestParam Long attendanceGroupId, - @Valid @RequestBody List userIds) { - groupUserService.createOrDel(attendanceGroupId, userIds); - return success("ok"); + public CommonResult createOrDel(@RequestParam Long attendanceGroupId, + @Valid @RequestBody List userIds) { + AttendanceGroupUserCreateOrDelVO vo = groupUserService.createOrDel(attendanceGroupId, userIds); + return success(vo); + } + + @PostMapping("/effectiveImmediately") + @Operation(summary = "立即生效") + public CommonResult effectiveImmediately(@RequestBody AttendanceGroupUserCreateOrDelVO vo) { + groupUserService.effectiveImmediately(vo); + return success(vo); } @PutMapping("/update") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserCreateOrDelVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserCreateOrDelVO.java new file mode 100644 index 00000000..a6ea598c --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/groupuser/vo/AttendanceGroupUserCreateOrDelVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.system.controller.admin.groupuser.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +public class AttendanceGroupUserCreateOrDelVO { + @Schema(description = "考勤组id") + private Long attendanceGroupId; + + @Schema(description = "删除的用户") + private List delUserIds; + + @Schema(description = "新增的用户") + private List saveUserIds; +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/attendance/AttendanceStatisticsJob.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/attendance/AttendanceStatisticsJob.java index 4c807ec4..7a2fea0e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/attendance/AttendanceStatisticsJob.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/attendance/AttendanceStatisticsJob.java @@ -1,41 +1,17 @@ package cn.iocoder.yudao.module.system.job.attendance; -import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.LocalDateTimeUtil; -import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.json.JSONUtil; -import cn.iocoder.yudao.framework.common.Constants; -import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; -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.mysql.attendance.group.AttendanceGroupMapper; -import cn.iocoder.yudao.module.system.dal.mysql.attendance.groupuser.AttendanceGroupUserMapper; -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.punchrecord.AttendancePunchRecordService; -import cn.iocoder.yudao.module.system.service.attendance.scheduling.AttendanceSchedulingService; import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; +import java.util.Collections; @Component @Slf4j @@ -55,110 +31,17 @@ public class AttendanceStatisticsJob { * / -- 5. 如果我凌晨1点 跑 明天的数据 会有什么问题吗? 好像没什么问题 - 嗯 */ @Resource - private AttendanceService attendanceService; - @Resource - private AttendanceGroupMapper attendanceGroupMapper; - @Resource - private AttendanceGroupUserMapper attendanceGroupUserMapper; - @Resource - private AttendanceFixedService attendanceFixedService; - - @Resource - private AttendanceSchedulingService attendanceSchedulingService; - @Resource - private AttendanceGroupShiftItemService attendanceGroupShiftItemService; - @Resource private AttendancePunchRecordService attendancePunchRecordService; - @Resource - private StringRedisTemplate stringRedisTemplate; @XxlJob("attendanceStatisticsJob") @TenantJob // --- ⚠️ 这个注解 会将租户列表拉出来 完了后逐个租户执行 定时任务需要注意 public ReturnT execute() throws Exception { log.info("开始 考勤预设"); - // 获取所有考勤组 - List attendanceGroupDOS = attendanceGroupMapper.selectList(); - // -- 根据考勤组ids 获取所有人员 - List attendanceGroupUserDOS = attendanceGroupUserMapper.selectList(); - //将attendanceGroupUserDOS对象中的type相同的userId合并成一个数组 type作为key 用户id列表List作为value - Map> groupUserMap = attendanceGroupUserDOS.stream().collect(Collectors.groupingBy(AttendanceGroupUserDO::getAttendanceGroupId, - Collectors.mapping(AttendanceGroupUserDO::getUserId, Collectors.toList()))); - // -- 获取考勤组下考勤规则 - 将将考勤组分组 - 按类型 LocalDateTime tomorrowLocalDateTime = LocalDateTimeUtil.offset(LocalDateTime.now(), 1, ChronoUnit.DAYS); - LocalDateTime theDayAfterTomorrowLocalDateTime = LocalDateTimeUtil.offset(tomorrowLocalDateTime, 1, ChronoUnit.DAYS); - String time = tomorrowLocalDateTime.format(Constants.REPO_DATE_FORMAT); - // 获取到考勤组 - 班次 key/value 格式 - Map map = this.getAttendanceGroupShiftIdGroupByGroup(attendanceGroupDOS, tomorrowLocalDateTime); - Map groupMap = attendanceGroupDOS.stream().collect(Collectors.toMap(AttendanceGroupDO::getId, v -> v)); - // -- 获取班次子表列表 - if (MapUtil.isNotEmpty(map)) { - List attendanceGroupShiftItemDOList = attendanceGroupShiftItemService.getGroupShiftItemListByShiftIds(new ArrayList<>(map.values())); - Map> itemMaps = attendanceGroupShiftItemDOList.stream().collect(Collectors.groupingBy(AttendanceGroupShiftItemDO::getKqAttendanceGroupShiftId)); - List attendancePunchRecordDOList = new ArrayList<>(); - for (Map.Entry entry : map.entrySet()) { - String key = Constants.ATTENDANCE + Constants.UNDERLINE + entry.getKey() + Constants.UNDERLINE; // + 时间 - AttendanceGroupDO attendanceGroupDO = groupMap.get(entry.getKey()); - List userIds = groupUserMap.get(entry.getKey()); - if (CollectionUtil.isEmpty(userIds)) { - continue; - } - List attendanceGroupShiftItemDOS = itemMaps.get(entry.getValue()); - if (CollectionUtil.isEmpty(attendanceGroupShiftItemDOS)) { - continue; - } - List attendanceOnTheDayDTOS = attendanceService.buildAttendanceOnTheDay(attendanceGroupShiftItemDOS); - for (Long userId : userIds) { - for (AttendanceOnTheDayDTO attendanceOnTheDayDTO : attendanceOnTheDayDTOS) { - AttendancePunchRecordDO attendancePunchRecordDO = new AttendancePunchRecordDO(); - attendancePunchRecordDO.setUserId(userId); - attendancePunchRecordDO.setAttendanceGroupId(entry.getKey()); - attendancePunchRecordDO.setAttendanceGroupName(attendanceGroupDO.getGroupName()); - attendancePunchRecordDO.setAttendanceGroupShiftId(attendanceOnTheDayDTO.getKqAttendanceGroupShiftId()); - attendancePunchRecordDO.setAttendanceGroupShiftName(attendanceOnTheDayDTO.getKqAttendanceGroupShiftName()); - attendancePunchRecordDO.setAttendanceGroupShiftItemId(attendanceOnTheDayDTO.getId()); - attendancePunchRecordDO.setType(attendanceGroupDO.getType()); - attendancePunchRecordDO.setPunchType(attendanceGroupDO.getPunchType()); - attendancePunchRecordDO.setWorkType(attendanceOnTheDayDTO.getType()); - attendancePunchRecordDO.setLevel(attendanceOnTheDayDTO.getLevel()); - attendancePunchRecordDO.setStatus(AttendanceOnTheDayDTO.PUNCH_STATUS_UN_PUNCH); - attendancePunchRecordDO.setFieldServiceFlag(Constants.FALSE); - attendancePunchRecordDO.setNextDayFlag(Constants.TRUE); - attendancePunchRecordDO.setDayTime(time); - LocalDateTime shouldPunchTime = LocalDateTime.ofInstant(DateUtils.buildHHmmTime(attendanceOnTheDayDTO.getTime(), - (attendanceOnTheDayDTO.getNextDayFlag() == 0 ? tomorrowLocalDateTime : theDayAfterTomorrowLocalDateTime)).toInstant(), ZoneId.systemDefault()); - attendancePunchRecordDO.setShouldPunchTime(shouldPunchTime); - attendancePunchRecordDO.setLatestPunchTime(shouldPunchTime.plusMinutes(attendanceOnTheDayDTO.getAfterPunchTime())); - attendancePunchRecordDOList.add(attendancePunchRecordDO); - } - stringRedisTemplate.opsForHash().put(key + time, userId, JSONUtil.toJsonStr(attendanceOnTheDayDTOS)); - } - //设置缓存 2天 - stringRedisTemplate.expire(key + time, 2, TimeUnit.DAYS); - } - // -- 批量 - attendancePunchRecordService.saveBatch(attendancePunchRecordDOList); - } + attendancePunchRecordService.defaultPersistence(Collections.emptyList(), tomorrowLocalDateTime); log.info("结束 考勤预设"); // 返回执行成功 return ReturnT.SUCCESS; } - private Map getAttendanceGroupShiftIdGroupByGroup(List attendanceGroupDOS, LocalDateTime localDateTime) { - Map map = new HashMap<>(); - List fixedList = attendanceGroupDOS.stream().filter(a -> a.getType().equals(1)).collect(Collectors.toList()); - List schedulingList = attendanceGroupDOS.stream().filter(a -> a.getType().equals(2)).collect(Collectors.toList()); - if (!fixedList.isEmpty()) { - Map attendanceFixedMap = attendanceFixedService.getGroupToShiftIdMap(fixedList, localDateTime); - if (ObjectUtil.isNotEmpty(attendanceFixedMap)) { - map.putAll(attendanceFixedMap); - } - } - if (!schedulingList.isEmpty()) { - Map attendanceSchedulingMap = attendanceSchedulingService.getGroupToShiftIdMap(schedulingList, localDateTime); - if (ObjectUtil.isNotEmpty(attendanceSchedulingMap)) { - map.putAll(attendanceSchedulingMap); - } - } - return map; - } } 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 365c24b4..6c59a105 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 @@ -61,8 +61,6 @@ public interface AttendanceGroupService { */ AttendanceGroupDO getByUserId(Long userId); - void test(); - /** * 获取所有 * 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 bfb3c7f4..d57f7477 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 @@ -126,70 +126,6 @@ public class AttendanceGroupServiceImpl implements AttendanceGroupService { return null; } - @Override - public void test() { - // 获取所有考勤组 - List attendanceGroupDOS = attendanceGroupMapper.selectList(); - // -- 根据考勤组ids 获取所有人员 - List attendanceGroupUserDOS = attendanceGroupUserMapper.selectList(); - //将attendanceGroupUserDOS对象中的type相同的userId合并成一个数组 type作为key 用户id列表List作为value - Map> groupUserMap = attendanceGroupUserDOS.stream().collect(Collectors.groupingBy(AttendanceGroupUserDO::getAttendanceGroupId, - Collectors.mapping(AttendanceGroupUserDO::getUserId, Collectors.toList()))); - // -- 获取考勤组下考勤规则 - 将将考勤组分组 - 按类型 - LocalDateTime tomorrowLocalDateTime = LocalDateTime.now(); - LocalDateTime theDayAfterTomorrowLocalDateTime = LocalDateTimeUtil.offset(tomorrowLocalDateTime, 1, ChronoUnit.DAYS); - - String time = tomorrowLocalDateTime.format(Constants.REPO_DATE_FORMAT); - // 获取到考勤组 - 班次 key/value 格式 - Map map = this.getAttendanceGroupShiftIdGroupByGroup(attendanceGroupDOS, tomorrowLocalDateTime); - Map groupMap = attendanceGroupDOS.stream().collect(Collectors.toMap(AttendanceGroupDO::getId, v -> v)); - // -- 获取班次子表列表 - if (MapUtil.isNotEmpty(map)) { - List attendanceGroupShiftItemDOList = attendanceGroupShiftItemService.getGroupShiftItemListByShiftIds(new ArrayList<>(map.values())); - Map> itemMaps = attendanceGroupShiftItemDOList.stream().collect(Collectors.groupingBy(AttendanceGroupShiftItemDO::getKqAttendanceGroupShiftId)); - List attendancePunchRecordDOList = new ArrayList<>(); - for (Map.Entry entry : map.entrySet()) { - AttendanceGroupDO attendanceGroupDO = groupMap.get(entry.getKey()); - List userIds = groupUserMap.get(entry.getKey()); - if (CollectionUtil.isEmpty(userIds)) { - continue; - } - List attendanceGroupShiftItemDOS = itemMaps.get(entry.getValue()); - if (CollectionUtil.isEmpty(attendanceGroupShiftItemDOS)) { - continue; - } - List attendanceOnTheDayDTOS = attendanceService.buildAttendanceOnTheDay(attendanceGroupShiftItemDOS); - for (Long userId : userIds) { - for (AttendanceOnTheDayDTO attendanceOnTheDayDTO : attendanceOnTheDayDTOS) { - AttendancePunchRecordDO attendancePunchRecordDO = new AttendancePunchRecordDO(); - attendancePunchRecordDO.setUserId(userId); - attendancePunchRecordDO.setAttendanceGroupId(entry.getKey()); - attendancePunchRecordDO.setAttendanceGroupName(attendanceGroupDO.getGroupName()); - attendancePunchRecordDO.setAttendanceGroupShiftId(attendanceOnTheDayDTO.getKqAttendanceGroupShiftId()); - attendancePunchRecordDO.setAttendanceGroupShiftName(attendanceOnTheDayDTO.getKqAttendanceGroupShiftName()); - attendancePunchRecordDO.setAttendanceGroupShiftItemId(attendanceOnTheDayDTO.getId()); - attendancePunchRecordDO.setType(attendanceGroupDO.getType()); - attendancePunchRecordDO.setPunchType(attendanceGroupDO.getPunchType()); - attendancePunchRecordDO.setWorkType(attendanceOnTheDayDTO.getType()); - attendancePunchRecordDO.setLevel(attendanceOnTheDayDTO.getLevel()); - attendancePunchRecordDO.setStatus(AttendanceOnTheDayDTO.PUNCH_STATUS_UN_PUNCH); - attendancePunchRecordDO.setFieldServiceFlag(Constants.FALSE); - attendancePunchRecordDO.setNextDayFlag(Constants.TRUE); - attendancePunchRecordDO.setDayTime(time); - LocalDateTime shouldPunchTime = LocalDateTime.ofInstant(DateUtils.buildHHmmTime(attendanceOnTheDayDTO.getTime(), - (attendanceOnTheDayDTO.getNextDayFlag() == 0 ? tomorrowLocalDateTime : theDayAfterTomorrowLocalDateTime)).toInstant(), ZoneId.systemDefault()); - attendancePunchRecordDO.setShouldPunchTime(shouldPunchTime); - attendancePunchRecordDO.setLatestPunchTime(shouldPunchTime.plusMinutes(attendanceOnTheDayDTO.getAfterPunchTime())); - - attendancePunchRecordDOList.add(attendancePunchRecordDO); - } - } - } - // -- 批量 - attendancePunchRecordService.saveBatch(attendancePunchRecordDOList); - } - } - @Override public List getAll() { return attendanceGroupMapper.selectList(); @@ -205,24 +141,4 @@ public class AttendanceGroupServiceImpl implements AttendanceGroupService { return ids; } - - private Map getAttendanceGroupShiftIdGroupByGroup(List attendanceGroupDOS, LocalDateTime localDateTime) { - Map map = new HashMap<>(); - List fixedList = attendanceGroupDOS.stream().filter(a -> a.getType().equals(1)).collect(Collectors.toList()); - List schedulingList = attendanceGroupDOS.stream().filter(a -> a.getType().equals(2)).collect(Collectors.toList()); - if (!fixedList.isEmpty()) { - Map attendanceFixedMap = attendanceFixedService.getGroupToShiftIdMap(fixedList, localDateTime); - if (ObjectUtil.isNotEmpty(attendanceFixedMap)) { - map.putAll(attendanceFixedMap); - } - } - if (!schedulingList.isEmpty()) { - Map attendanceSchedulingMap = attendanceSchedulingService.getGroupToShiftIdMap(schedulingList, localDateTime); - if (ObjectUtil.isNotEmpty(attendanceSchedulingMap)) { - map.putAll(attendanceSchedulingMap); - } - } - return map; - } - } \ 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/groupshift/AttendanceGroupShiftService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupshift/AttendanceGroupShiftService.java index b1aa3e0d..b3fb9762 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupshift/AttendanceGroupShiftService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupshift/AttendanceGroupShiftService.java @@ -69,6 +69,7 @@ public interface AttendanceGroupShiftService { List listByShiftIds(List listByShiftIds); /** + * 立即生效 * * @param groupIds */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupshift/AttendanceGroupShiftServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupshift/AttendanceGroupShiftServiceImpl.java index df715395..b1f6e1d7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupshift/AttendanceGroupShiftServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupshift/AttendanceGroupShiftServiceImpl.java @@ -13,12 +13,15 @@ import cn.iocoder.yudao.module.system.controller.admin.groupshift.vo.AttendanceG import cn.iocoder.yudao.module.system.dal.dataobject.attendance.fixed.AttendanceFixedDO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.groupshift.AttendanceGroupShiftDO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.groupshiftitem.AttendanceGroupShiftItemDO; +import cn.iocoder.yudao.module.system.dal.dataobject.attendance.punchrecord.AttendancePunchRecordDO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.scheduling.AttendanceSchedulingDO; import cn.iocoder.yudao.module.system.dal.mysql.attendance.fixed.AttendanceFixedMapper; import cn.iocoder.yudao.module.system.dal.mysql.attendance.groupshift.AttendanceGroupShiftMapper; import cn.iocoder.yudao.module.system.dal.mysql.attendance.groupshiftitem.AttendanceGroupShiftItemMapper; +import cn.iocoder.yudao.module.system.dal.mysql.attendance.punchrecord.AttendancePunchRecordMapper; import cn.iocoder.yudao.module.system.dal.mysql.attendance.scheduling.AttendanceSchedulingMapper; import cn.iocoder.yudao.module.system.service.attendance.group.AttendanceGroupService; +import cn.iocoder.yudao.module.system.service.attendance.punchrecord.AttendancePunchRecordService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.springframework.context.annotation.Lazy; import org.springframework.data.redis.core.StringRedisTemplate; @@ -57,7 +60,12 @@ public class AttendanceGroupShiftServiceImpl implements AttendanceGroupShiftServ private AttendanceGroupService attendanceGroupService; @Resource private StringRedisTemplate stringRedisTemplate; - + @Resource + @Lazy + private AttendancePunchRecordMapper attendancePunchRecordMapper; + @Resource + @Lazy + private AttendancePunchRecordService attendancePunchRecordService; @Override @Transactional(rollbackFor = Exception.class) @@ -131,8 +139,6 @@ public class AttendanceGroupShiftServiceImpl implements AttendanceGroupShiftServ // -- 查询下有没有考勤组在用这个班次 - 如果有的话就要考虑更新 是立即更新 还是 次日更新 List useGroupIds = attendanceGroupService.getUseGroupIds(updateReqVO.getId()); - // TODO: 2024/6/5 如果考勤组没有使用班次 则不需要更新 - boolean flag = false; if (CollectionUtil.isEmpty(oldItems)) { @@ -224,13 +230,27 @@ public class AttendanceGroupShiftServiceImpl implements AttendanceGroupShiftServ } @Override + @Transactional(rollbackFor = Exception.class) public void effectiveImmediately(List groupIds) { - String time = LocalDateTime.now().format(Constants.REPO_DATE_FORMAT); + LocalDateTime now = LocalDateTime.now(); + String time = now.format(Constants.REPO_DATE_FORMAT); + String yesterdayStr = LocalDateTimeUtil.offset(now, 1, ChronoUnit.DAYS).format(Constants.REPO_DATE_FORMAT); // TODO: 2024/6/5 删除当天redis中考勤记录 - 重新计算新的考勤记录到redis 和 数据库中 for (Long groupId : groupIds) { String key = Constants.ATTENDANCE + Constants.UNDERLINE + groupId + Constants.UNDERLINE; // + 时间 stringRedisTemplate.delete(key + time); + stringRedisTemplate.delete(key + yesterdayStr); + // -- 生成新的考勤记录到redis中 - 和数据库中(数据库中会有什么问题?) - 可能会导致两条数据一起更新 旧的数据和新的数据一起更新 + // -- 如果不生成会导致什么问题 - 可能导致考勤组人员缺卡 从而导致统计的时候缺卡统计不到 } + + // TODO: 2024/6/6 这里如果慢的话可以异步处理 + // -- 删除当前考勤组预留的考勤记录 + attendancePunchRecordMapper.delete(new LambdaQueryWrapper() + .in(AttendancePunchRecordDO::getAttendanceGroupId, groupIds) + .eq(AttendancePunchRecordDO::getNextDayFlag, Constants.TRUE)); + // -- 重新计算 - 插入到redis 和数据中 + attendancePunchRecordService.defaultPersistence(groupIds, LocalDateTime.now()); } private List buildShift(List dos) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupuser/AttendanceGroupUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupuser/AttendanceGroupUserService.java index 9b13f92f..c4b89a13 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupuser/AttendanceGroupUserService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupuser/AttendanceGroupUserService.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.system.service.attendance.groupuser; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.AttendanceGroupUserCreateOrDelVO; import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.AttendanceGroupUserPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.AttendanceGroupUserSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.groupuser.AttendanceGroupUserDO; @@ -21,7 +22,7 @@ public interface AttendanceGroupUserService { * @param attendanceGroupId * @param userIds */ - void createOrDel(Long attendanceGroupId, List userIds); + AttendanceGroupUserCreateOrDelVO createOrDel(Long attendanceGroupId, List userIds); /** * 更新考勤组人员 @@ -60,4 +61,11 @@ public interface AttendanceGroupUserService { * @return */ List getUserIdsByGroupId(Long id); + + /** + * 人员调整立即生效 + * + * @param vo + */ + void effectiveImmediately(AttendanceGroupUserCreateOrDelVO vo); } \ 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/groupuser/AttendanceGroupUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupuser/AttendanceGroupUserServiceImpl.java index 5cef78fb..c9dc3053 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupuser/AttendanceGroupUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/groupuser/AttendanceGroupUserServiceImpl.java @@ -1,18 +1,28 @@ package cn.iocoder.yudao.module.system.service.attendance.groupuser; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.iocoder.yudao.framework.common.Constants; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.AttendanceGroupUserCreateOrDelVO; import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.AttendanceGroupUserPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.groupuser.vo.AttendanceGroupUserSaveReqVO; 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.mysql.attendance.groupuser.AttendanceGroupUserMapper; +import cn.iocoder.yudao.module.system.dal.mysql.attendance.punchrecord.AttendancePunchRecordMapper; +import cn.iocoder.yudao.module.system.service.attendance.punchrecord.AttendancePunchRecordService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -30,39 +40,40 @@ public class AttendanceGroupUserServiceImpl implements AttendanceGroupUserServic @Resource private AttendanceGroupUserMapper groupUserMapper; + @Resource + private StringRedisTemplate stringRedisTemplate; + @Resource + private AttendancePunchRecordMapper attendancePunchRecordMapper; + @Resource + private AttendancePunchRecordService attendancePunchRecordService; @Override - public void createOrDel(Long attendanceGroupId, List userIds) { + public AttendanceGroupUserCreateOrDelVO createOrDel(Long attendanceGroupId, List userIds) { + AttendanceGroupUserCreateOrDelVO vo = new AttendanceGroupUserCreateOrDelVO(); + List groupUserList = groupUserMapper.selectList(AttendanceGroupUserDO::getAttendanceGroupId, attendanceGroupId); List list = new ArrayList<>(); - if (CollectionUtil.isEmpty(groupUserList)) { - if (CollectionUtil.isNotEmpty(userIds)) { - for (Long userId : userIds) { - list.add(new AttendanceGroupUserDO().setUserId(userId).setAttendanceGroupId(attendanceGroupId)); - } - groupUserMapper.insertBatch(list); - } - } else { - if (CollectionUtil.isNotEmpty(userIds)) { - List oldUserIds = groupUserList.stream().map(AttendanceGroupUserDO::getUserId).collect(Collectors.toList()); - List delIds = new ArrayList<>(CollectionUtil.subtract(oldUserIds, userIds)); - List saveIds = new ArrayList<>(CollectionUtil.subtract(userIds, oldUserIds)); - if (CollectionUtil.isNotEmpty(delIds)) { - groupUserMapper.delete(new LambdaQueryWrapper().eq(AttendanceGroupUserDO::getAttendanceGroupId, attendanceGroupId) - .in(AttendanceGroupUserDO::getUserId, delIds)); - } - if (CollectionUtil.isNotEmpty(saveIds)) { - for (Long userId : saveIds) { - list.add(new AttendanceGroupUserDO().setUserId(userId).setAttendanceGroupId(attendanceGroupId)); - } - groupUserMapper.insertBatch(list); - } - } else { - groupUserMapper.delete(AttendanceGroupUserDO::getAttendanceGroupId, attendanceGroupId); - } + + if (CollectionUtil.isEmpty(userIds)) { + userIds = Collections.emptyList(); } - - + List oldUserIds = groupUserList.stream().map(AttendanceGroupUserDO::getUserId).collect(Collectors.toList()); + List delIds = new ArrayList<>(CollectionUtil.subtract(oldUserIds, userIds)); + List saveIds = new ArrayList<>(CollectionUtil.subtract(userIds, oldUserIds)); + if (CollectionUtil.isNotEmpty(delIds)) { + groupUserMapper.delete(new LambdaQueryWrapper().eq(AttendanceGroupUserDO::getAttendanceGroupId, attendanceGroupId) + .in(AttendanceGroupUserDO::getUserId, delIds)); + } + if (CollectionUtil.isNotEmpty(saveIds)) { + for (Long userId : saveIds) { + list.add(new AttendanceGroupUserDO().setUserId(userId).setAttendanceGroupId(attendanceGroupId)); + } + groupUserMapper.insertBatch(list); + } + vo.setAttendanceGroupId(attendanceGroupId); + vo.setDelUserIds(delIds); + vo.setSaveUserIds(saveIds); + return vo; } @Override @@ -105,4 +116,25 @@ public class AttendanceGroupUserServiceImpl implements AttendanceGroupUserServic return list.stream().map(AttendanceGroupUserDO::getUserId).collect(Collectors.toList()); } + @Override + public void effectiveImmediately(AttendanceGroupUserCreateOrDelVO vo) { + LocalDateTime now = LocalDateTime.now(); + String time = now.format(Constants.REPO_DATE_FORMAT); + String yesterdayStr = LocalDateTimeUtil.offset(now, 1, ChronoUnit.DAYS).format(Constants.REPO_DATE_FORMAT); + // 删除掉redis 中的记录 - + if (CollectionUtil.isNotEmpty(vo.getDelUserIds())) { + String key = Constants.ATTENDANCE + Constants.UNDERLINE + vo.getAttendanceGroupId() + Constants.UNDERLINE; // + 时间 + stringRedisTemplate.opsForHash().delete(key + time, vo.getDelUserIds().stream().map(String::valueOf).toArray(String[]::new)); + stringRedisTemplate.opsForHash().delete(key + yesterdayStr, vo.getDelUserIds().stream().map(String::valueOf).toArray(String[]::new)); + //删除掉这些人员在这个考勤组里的记录 + attendancePunchRecordMapper.delete(new LambdaQueryWrapper() + .eq(AttendancePunchRecordDO::getAttendanceGroupId, vo.getAttendanceGroupId()) + .in(AttendancePunchRecordDO::getUserId, vo.getDelUserIds()) + .eq(AttendancePunchRecordDO::getNextDayFlag, Constants.TRUE)); + } + if (CollectionUtil.isNotEmpty(vo.getSaveUserIds())) { + attendancePunchRecordService.defaultPersistence(vo.getAttendanceGroupId(), vo.getSaveUserIds(), LocalDateTime.now()); + } + } + } \ 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/punchrecord/AttendancePunchRecordService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punchrecord/AttendancePunchRecordService.java index bb833156..44ef9169 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punchrecord/AttendancePunchRecordService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punchrecord/AttendancePunchRecordService.java @@ -3,10 +3,15 @@ package cn.iocoder.yudao.module.system.service.attendance.punchrecord; import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.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.punchrecord.AttendancePunchRecordDO; +import org.springframework.transaction.annotation.Transactional; import javax.validation.Valid; +import java.time.LocalDateTime; import java.util.List; +import java.util.Map; /** * 用户打卡记录 Service 接口 @@ -59,4 +64,34 @@ public interface AttendancePunchRecordService { * @param attendancePunchRecordDOList */ void saveBatch(List attendancePunchRecordDOList); + + + /** + * 预设考勤 + * @param groupId + * @param userIds + * @param localDateTime + */ + void defaultPersistence(Long groupId, List userIds, LocalDateTime localDateTime); + + /** + * 预设考勤 + * + * @param groupIds 考勤组ids + * @param localDateTime 时间 + */ + void defaultPersistence(List groupIds, LocalDateTime localDateTime); + + /** + * 预设持久化考勤 + * + * @param map 获取到考勤组 - 班次 key/value 格式 + * @param groupMap 考勤组id分map + * @param groupUserMap 考勤组id分组用户列表 + * @param itemMaps 考勤班次子表根据考勤班次分组 + * @param time 时间格式 yyyy-MM-dd + * @param localDateTime 需要预设的时间 + */ + void defaultPersistence(Map map, Map groupMap, Map> groupUserMap, + Map> itemMaps, String time, LocalDateTime localDateTime); } \ 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/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 1db24aad..3fc75bb7 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 @@ -1,17 +1,45 @@ package cn.iocoder.yudao.module.system.service.attendance.punchrecord; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.framework.common.Constants; 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.controller.admin.punchrecord.vo.AttendancePunchRecordPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordSaveReqVO; +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.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.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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.PUNCH_RECORD_NOT_EXISTS; @@ -27,6 +55,22 @@ public class AttendancePunchRecordServiceImpl implements AttendancePunchRecordSe @Resource private AttendancePunchRecordMapper punchRecordMapper; + @Resource + @Lazy // 避免依赖循环 + private AttendanceService attendanceService; + @Resource + private StringRedisTemplate stringRedisTemplate; + @Resource + private AttendanceFixedService attendanceFixedService; + @Resource + private AttendanceSchedulingService attendanceSchedulingService; + @Resource + private AttendanceGroupShiftItemService attendanceGroupShiftItemService; + @Resource + private AttendanceGroupUserMapper attendanceGroupUserMapper; + @Resource + private AttendanceGroupMapper attendanceGroupMapper; + @Override public Long createPunchRecord(AttendancePunchRecordSaveReqVO createReqVO) { @@ -76,4 +120,134 @@ public class AttendancePunchRecordServiceImpl implements AttendancePunchRecordSe punchRecordMapper.insertBatch(attendancePunchRecordDOList); } + + @Override + @Transactional(rollbackFor = Exception.class) + public void defaultPersistence(Long groupId, List userIds, LocalDateTime localDateTime) { + if (groupId == null || CollectionUtil.isEmpty(userIds)) { + return; + } + AttendanceGroupDO attendanceGroupDO = attendanceGroupMapper.selectById(groupId); + List attendanceGroupDOS = new ArrayList<>(); + attendanceGroupDOS.add(attendanceGroupDO); + + List attendanceGroupUserDOS = attendanceGroupUserMapper.selectList(new LambdaQueryWrapper() + .eq(AttendanceGroupUserDO::getAttendanceGroupId, groupId) + .in(AttendanceGroupUserDO::getUserId, userIds)); + this.defaultPersistence(attendanceGroupDOS, attendanceGroupUserDOS, localDateTime); + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void defaultPersistence(List groupIds, LocalDateTime localDateTime) { + List attendanceGroupDOS; + List attendanceGroupUserDOS; + if (CollectionUtil.isNotEmpty(groupIds)) { + attendanceGroupDOS = attendanceGroupMapper.selectBatchIds(groupIds); + attendanceGroupUserDOS = attendanceGroupUserMapper.selectList(new LambdaQueryWrapper() + .in(AttendanceGroupUserDO::getAttendanceGroupId, groupIds)); + } else { + attendanceGroupDOS = attendanceGroupMapper.selectList(); + attendanceGroupUserDOS = attendanceGroupUserMapper.selectList(); + } + this.defaultPersistence(attendanceGroupDOS, attendanceGroupUserDOS, localDateTime); + } + + public void defaultPersistence(List attendanceGroupDOS, List attendanceGroupUserDOS, LocalDateTime localDateTime) { + // 获取所有考勤组 + // -- 根据考勤组ids 获取所有人员 + //将attendanceGroupUserDOS对象中的type相同的userId合并成一个数组 type作为key 用户id列表List作为value + Map> groupUserMap = attendanceGroupUserDOS.stream().collect(Collectors.groupingBy(AttendanceGroupUserDO::getAttendanceGroupId, + Collectors.mapping(AttendanceGroupUserDO::getUserId, Collectors.toList()))); + // -- 获取考勤组下考勤规则 - 将将考勤组分组 - 按类型 + String time = localDateTime.format(Constants.REPO_DATE_FORMAT); + // 获取到考勤组 - 班次 key/value 格式 + Map map = this.getAttendanceGroupShiftIdGroupByGroup(attendanceGroupDOS, localDateTime); + Map groupMap = attendanceGroupDOS.stream().collect(Collectors.toMap(AttendanceGroupDO::getId, v -> v)); + // -- 获取班次子表列表 + if (MapUtil.isNotEmpty(map)) { + List attendanceGroupShiftItemDOList = attendanceGroupShiftItemService.getGroupShiftItemListByShiftIds(new ArrayList<>(map.values())); + Map> itemMaps = attendanceGroupShiftItemDOList.stream().collect(Collectors.groupingBy(AttendanceGroupShiftItemDO::getKqAttendanceGroupShiftId)); + this.defaultPersistence(map, groupMap, groupUserMap, itemMaps, time, localDateTime); + } + } + + + /** + * @param map 获取到考勤组 - 班次 key/value 格式 + * @param groupMap 考勤组id分map + * @param groupUserMap 考勤组id分组用户列表 + * @param itemMaps 考勤班次子表根据考勤班次分组 + * @param time 时间格式 yyyy-MM-dd + * @param localDateTime 需要预设的时间 + */ + @Override + public void defaultPersistence(Map map, Map groupMap, Map> groupUserMap, + Map> itemMaps, String time, LocalDateTime localDateTime) { + List attendancePunchRecordDOList = new ArrayList<>(); + LocalDateTime nextDayLocalDateTime = LocalDateTimeUtil.offset(localDateTime, 1, ChronoUnit.DAYS); + for (Map.Entry entry : map.entrySet()) { + String key = Constants.ATTENDANCE + Constants.UNDERLINE + entry.getKey() + Constants.UNDERLINE; // + 时间 + AttendanceGroupDO attendanceGroupDO = groupMap.get(entry.getKey()); + List userIds = groupUserMap.get(entry.getKey()); + if (CollectionUtil.isEmpty(userIds)) { + continue; + } + List attendanceGroupShiftItemDOS = itemMaps.get(entry.getValue()); + if (CollectionUtil.isEmpty(attendanceGroupShiftItemDOS)) { + continue; + } + List attendanceOnTheDayDTOS = attendanceService.buildAttendanceOnTheDay(attendanceGroupShiftItemDOS); + for (Long userId : userIds) { + for (AttendanceOnTheDayDTO attendanceOnTheDayDTO : attendanceOnTheDayDTOS) { + AttendancePunchRecordDO attendancePunchRecordDO = new AttendancePunchRecordDO(); + attendancePunchRecordDO.setUserId(userId); + attendancePunchRecordDO.setAttendanceGroupId(entry.getKey()); + attendancePunchRecordDO.setAttendanceGroupName(attendanceGroupDO.getGroupName()); + attendancePunchRecordDO.setAttendanceGroupShiftId(attendanceOnTheDayDTO.getKqAttendanceGroupShiftId()); + attendancePunchRecordDO.setAttendanceGroupShiftName(attendanceOnTheDayDTO.getKqAttendanceGroupShiftName()); + attendancePunchRecordDO.setAttendanceGroupShiftItemId(attendanceOnTheDayDTO.getId()); + attendancePunchRecordDO.setType(attendanceGroupDO.getType()); + attendancePunchRecordDO.setPunchType(attendanceGroupDO.getPunchType()); + attendancePunchRecordDO.setWorkType(attendanceOnTheDayDTO.getType()); + attendancePunchRecordDO.setLevel(attendanceOnTheDayDTO.getLevel()); + attendancePunchRecordDO.setStatus(AttendanceOnTheDayDTO.PUNCH_STATUS_UN_PUNCH); + attendancePunchRecordDO.setFieldServiceFlag(Constants.FALSE); + attendancePunchRecordDO.setNextDayFlag(Constants.TRUE); + attendancePunchRecordDO.setDayTime(time); + LocalDateTime shouldPunchTime = LocalDateTime.ofInstant(DateUtils.buildHHmmTime(attendanceOnTheDayDTO.getTime(), + (attendanceOnTheDayDTO.getNextDayFlag() == 0 ? localDateTime : nextDayLocalDateTime)).toInstant(), ZoneId.systemDefault()); + attendancePunchRecordDO.setShouldPunchTime(shouldPunchTime); + attendancePunchRecordDO.setLatestPunchTime(shouldPunchTime.plusMinutes(attendanceOnTheDayDTO.getAfterPunchTime())); + attendancePunchRecordDOList.add(attendancePunchRecordDO); + } + stringRedisTemplate.opsForHash().put(key + time, userId, JSONUtil.toJsonStr(attendanceOnTheDayDTOS)); + } + //设置缓存 2天 + stringRedisTemplate.expire(key + time, 2, TimeUnit.DAYS); + } + // -- 批量 + this.saveBatch(attendancePunchRecordDOList); + } + + private Map getAttendanceGroupShiftIdGroupByGroup(List attendanceGroupDOS, LocalDateTime localDateTime) { + Map map = new HashMap<>(); + List fixedList = attendanceGroupDOS.stream().filter(a -> a.getType().equals(1)).collect(Collectors.toList()); + List schedulingList = attendanceGroupDOS.stream().filter(a -> a.getType().equals(2)).collect(Collectors.toList()); + if (!fixedList.isEmpty()) { + Map attendanceFixedMap = attendanceFixedService.getGroupToShiftIdMap(fixedList, localDateTime); + if (ObjectUtil.isNotEmpty(attendanceFixedMap)) { + map.putAll(attendanceFixedMap); + } + } + if (!schedulingList.isEmpty()) { + Map attendanceSchedulingMap = attendanceSchedulingService.getGroupToShiftIdMap(schedulingList, localDateTime); + if (ObjectUtil.isNotEmpty(attendanceSchedulingMap)) { + map.putAll(attendanceSchedulingMap); + } + } + return map; + } + } \ No newline at end of file