From c501dea1f4522d3956e0ca8b9648db91c3676206 Mon Sep 17 00:00:00 2001 From: aikai Date: Tue, 4 Jun 2024 14:02:03 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E6=89=93=E5=8D=A1=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/util/date/DateUtils.java | 23 +++- .../security/TenantSecurityWebFilter.java | 2 +- .../system/enums/ErrorCodeConstants.java | 6 + .../AttendanceEquipmentController.java | 57 ++++++++++ .../group/AttendanceGroupController.java | 8 ++ .../controller/admin/user/UserController.java | 9 ++ .../attendance/dto/AttendancePunchDTO.java | 9 +- .../dto/AttendancePunchPageDTO.java | 5 +- .../app/attendance/vo/AttendancePunchVO.java | 3 + .../AttendanceGroupShiftItemDO.java | 2 +- .../punchrecord/AttendancePunchRecordDO.java | 15 +-- .../AttendancePunchRecordMapper.java | 3 + .../dal/mysql/user/AdminUserMapper.java | 10 +- .../attendance/AttendanceMissingCardJob.java | 16 ++- .../attendance/AttendanceStatisticsJob.java | 5 +- .../attendance/AttendanceServiceImpl.java | 40 +++---- .../group/AttendanceGroupService.java | 8 ++ .../group/AttendanceGroupServiceImpl.java | 18 ++- .../AttendanceGroupShiftServiceImpl.java | 106 ++++++++++++++++-- .../punch/dto/AttendanceOnTheDayDTO.java | 3 + .../AttendanceSchedulingServiceImpl.java | 2 +- .../system/service/user/AdminUserService.java | 12 +- .../service/user/AdminUserServiceImpl.java | 22 ++-- .../resources/mapper/user/AdminUserMapper.xml | 15 +++ 24 files changed, 341 insertions(+), 58 deletions(-) create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/AttendanceEquipmentController.java diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java index 795fff10..4c0ccb37 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java @@ -11,6 +11,7 @@ import cn.hutool.json.JSONUtil; import java.text.SimpleDateFormat; import java.time.*; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -139,6 +140,27 @@ public class DateUtils { return calendar.getTime(); } + /** + * 创建指定时间 + * + * @param timeStr 时间字符串,格式为 HH:mm + * @return 指定时间 + */ + public static Date buildHHmmTime(String timeStr, LocalDateTime localDateTime) { + // 将LocalDateTime转换为Instant,因为Calendar不能直接从LocalDateTime构造 + Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant(); + // 使用Instant创建Calendar对象 + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(instant.toEpochMilli()); + // 输出转换后的Calendar对象 + String[] time = timeStr.split(":"); + calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0])); + calendar.set(Calendar.MINUTE, Integer.parseInt(time[1])); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTime(); + } + /** * 创建指定时间 * @@ -152,7 +174,6 @@ public class DateUtils { calendar.set(Calendar.MINUTE, Integer.parseInt(time[1])); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); - Date endTime = calendar.getTime(); return calendar.getTime(); } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java index 645699b9..17531b71 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java @@ -93,7 +93,7 @@ public class TenantSecurityWebFilter extends ApiRequestFilter { // StringBuffer url = request.getRequestURL(); // log.info("请求URL地址:" + url.toString()); // log.info("请求URI地址:" +request.getRequestURI()); - log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod()); + //log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod()); ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "租户的请求未传递,请进行排查")); return; diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index df45b348..c8074359 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -197,6 +197,12 @@ public interface ErrorCodeConstants { ErrorCode NO_PERMISSION_TO_VIEW_CURRENT_ATTENDANCE_GROUP_INFORMATION = new ErrorCode(1_003_012_000, "无权限查看当前考勤组信息!"); + ErrorCode THE_ATTENDANCE_INTERVAL_SHALL_NOT_EXCEED24_HOURS = new ErrorCode(1_003_013_000, "考勤区间不得超过24小时"); + + ErrorCode GROUP_SHIFT_IN_USE = new ErrorCode(1_003_014_000, "班次使用中不允许删除"); + + + ErrorCode LOG_FORM_NOT_USE = new ErrorCode(1_009_010_004, "你不用使用该日志模板"); ErrorCode LOG_USE_NOT_EXISTS = new ErrorCode(1_009_010_005, "模板不存在"); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/AttendanceEquipmentController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/AttendanceEquipmentController.java new file mode 100644 index 00000000..a3eb0507 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/AttendanceEquipmentController.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.system.controller; + +import cn.hutool.json.JSONObject; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +import cn.iocoder.yudao.module.system.controller.app.attendance.dto.AttendancePunchDTO; +import cn.iocoder.yudao.module.system.controller.app.attendance.vo.AttendancePunchVO; +import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO; +import cn.iocoder.yudao.module.system.service.attendance.AttendanceService; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.annotation.security.PermitAll; + +@Tag(name = "管理后台 - 资产") +@RestController +@RequestMapping("/api/v1") +@Validated +@Slf4j +public class AttendanceEquipmentController { + @Resource + private AttendanceService attendanceService; + + @PostMapping("/verify_user") + @PermitAll + public JSONObject verifyUser(@RequestBody JSONObject object) { + TenantContextHolder.setTenantId(1L); + // TODO: 2024/6/4 暂时写死 + JSONObject result = new JSONObject().set("Result", 0).set("Msg", "识别通过"); + JSONObject content = new JSONObject(); + content.set("voice_code", -2); + result.set("Content", content); + try { + String sn = object.getStr("sn"); + String userId = object.getStr("user_id"); + content.set("user_id", userId); + AttendancePunchVO punch = attendanceService.punch(new AttendancePunchDTO() + .setUserId(Long.valueOf(userId)) + .setPunchType(AttendanceGroupDO.PUNCH_TYPE_ATTENDANCE_MACHINE) + .setSn(sn)); + content.set("voice_text", punch.getStatus() == 0 ? "打卡成功" : (punch.getStatus() == 1 ? "迟到打卡成功" : "早退打卡成功")); + } catch (ServiceException e) { + content.set("voice_text", e.getMessage()); + } catch (Exception e) { + content.set("voice_text", "系统错误"); + } finally { + result.set("Content", content); + return result; + } + } +} \ 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/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 56b2cea7..2f2b407b 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 @@ -87,6 +87,14 @@ public class AttendanceGroupController { return success(BeanUtils.toBean(pageResult, AttendanceGroupRespVO.class)); } + + @GetMapping("/getAll") + @Operation(summary = "获得所有考勤组") + public CommonResult> getAll() { + List pageResult = groupService.getAll(); + 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/user/UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index 49741d3a..cdad946b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java @@ -165,6 +165,15 @@ public class UserController { return success(user); } + @PostMapping("/selectByDeptIdsFilterGroupUser") + @Operation(summary = "通过部门ids获取用户信息列表(过滤掉已在考勤组的用户)") + @PreAuthorize("@ss.hasPermission('system:user:query')") + public CommonResult> selectByDeptIdsFilterGroupUser(@RequestBody Collection deptIds) { + + List user = userService.selectByDeptIdsFilterGroupUser(deptIds); + return success(user); + } + @PostMapping("/getByDeptId") @Operation(summary = "根据部门编号获得用户详情") @Parameter(name = "deptId", description = "部门编号", required = true, example = "117") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchDTO.java index 8676cb79..1b692fc5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchDTO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchDTO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.system.controller.app.attendance.dto; -import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -33,6 +32,14 @@ public class AttendancePunchDTO { * 当前用户id */ private Long userId = getLoginUserId(); + /** + * 打卡类型 1考勤机 2小程序范围打卡(默认) + */ + private Integer punchType = AttendanceGroupDO.PUNCH_TYPE_MI_NI_APP; + /** + * 考勤机编号 + */ + private String sn; /** * 当前时间 */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchPageDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchPageDTO.java index 143fdeb6..4689581f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchPageDTO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/dto/AttendancePunchPageDTO.java @@ -23,7 +23,10 @@ public class AttendancePunchPageDTO { * 当前用户id */ private Long userId = getLoginUserId(); - + /** + * 打卡类型 1考勤机 2小程序范围打卡(默认) + */ + private Integer punchType = AttendanceGroupDO.PUNCH_TYPE_MI_NI_APP; /** * 是否返回考勤组考勤班次信息 */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/vo/AttendancePunchVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/vo/AttendancePunchVO.java index 2ed8da46..bbe14c49 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/vo/AttendancePunchVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/attendance/vo/AttendancePunchVO.java @@ -20,4 +20,7 @@ public class AttendancePunchVO { @Schema(description = "当天考勤列表") private List attendanceOnTheDayDTOS; + + @Schema(description = "打卡状态 0正常 1迟到 2早退", example = "1") + private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/attendance/groupshiftitem/AttendanceGroupShiftItemDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/attendance/groupshiftitem/AttendanceGroupShiftItemDO.java index 08a3ce15..9690acba 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/attendance/groupshiftitem/AttendanceGroupShiftItemDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/attendance/groupshiftitem/AttendanceGroupShiftItemDO.java @@ -53,7 +53,7 @@ public class AttendanceGroupShiftItemDO extends BaseDO { */ private Integer mustFlag; /** - * 是否次日(开始时间 大于 结束时间)跨天 0否 1是 + * 是否次日(开始时间 大于 结束时间)跨天 0否 1跨天 2结束时间跨天 */ private Integer nextDayFlag; /** diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/attendance/punchrecord/AttendancePunchRecordDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/attendance/punchrecord/AttendancePunchRecordDO.java index 71ada7b3..59ca236d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/attendance/punchrecord/AttendancePunchRecordDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/attendance/punchrecord/AttendancePunchRecordDO.java @@ -1,15 +1,12 @@ package cn.iocoder.yudao.module.system.dal.dataobject.attendance.punchrecord; -import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; -import java.util.*; import java.time.LocalDateTime; -import java.time.LocalDateTime; -import java.time.LocalDateTime; - -import com.baomidou.mybatisplus.annotation.*; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; /** * 用户打卡记录 DO @@ -100,6 +97,10 @@ public class AttendancePunchRecordDO extends BaseDO { * 应打卡时间 */ private LocalDateTime shouldPunchTime; + /** + * 最晚打卡时间(超过即为缺卡) + */ + private LocalDateTime latestPunchTime; /** * 打卡备注 */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/attendance/punchrecord/AttendancePunchRecordMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/attendance/punchrecord/AttendancePunchRecordMapper.java index 106b0fba..3fa74945 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/attendance/punchrecord/AttendancePunchRecordMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/attendance/punchrecord/AttendancePunchRecordMapper.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.attendance.punchrecord.AttendancePunchRecordDO; +import cn.iocoder.yudao.module.system.service.attendance.punch.dto.AttendanceOnTheDayDTO; import org.apache.ibatis.annotations.Mapper; /** @@ -23,6 +24,8 @@ public interface AttendancePunchRecordMapper extends BaseMapperX { return selectList(new LambdaQueryWrapperX() .eq(AdminUserDO::getDeptId, deptId) .ne(AdminUserDO::getId, userId) - .eq(AdminUserDO::getUserType , 1)); + .eq(AdminUserDO::getUserType, 1)); } void emptyOpenId(@Param("openId") String openId); List selectByDeptIds(Collection deptIds); + /** + * 根据部门ids查询出用户列表 过滤掉考勤组里有的 + * + * @param deptIds + * @return + */ + List selectByDeptIdsFilterGroupUser(Collection deptIds); + List selectUserByBoss(); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/attendance/AttendanceMissingCardJob.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/attendance/AttendanceMissingCardJob.java index e05dcce8..f9634618 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/attendance/AttendanceMissingCardJob.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/attendance/AttendanceMissingCardJob.java @@ -1,8 +1,10 @@ package cn.iocoder.yudao.module.system.job.attendance; +import cn.iocoder.yudao.framework.common.Constants; import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; +import cn.iocoder.yudao.module.system.dal.dataobject.attendance.punchrecord.AttendancePunchRecordDO; import cn.iocoder.yudao.module.system.dal.mysql.attendance.punchrecord.AttendancePunchRecordMapper; -import cn.iocoder.yudao.module.system.service.attendance.punchrecord.AttendancePunchRecordService; +import cn.iocoder.yudao.module.system.service.attendance.punch.dto.AttendanceOnTheDayDTO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.annotation.XxlJob; @@ -10,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.Resource; +import java.time.LocalDateTime; @Component @Slf4j @@ -24,7 +27,16 @@ public class AttendanceMissingCardJob { @TenantJob // --- ⚠️ 这个注解 会将租户列表拉出来 完了后逐个租户执行 定时任务需要注意 public ReturnT execute() throws Exception { log.info("开始 修改考勤缺卡"); - attendancePunchRecordMapper.selectList(new LambdaQueryWrapper<>()); + LocalDateTime now = LocalDateTime.now(); + String time = now.format(Constants.REPO_DATE_FORMAT); + LambdaQueryWrapper le = new LambdaQueryWrapper() + .eq(AttendancePunchRecordDO::getDayTime, time) + .eq(AttendancePunchRecordDO::getNextDayFlag, Constants.TRUE) + .eq(AttendancePunchRecordDO::getStatus, AttendanceOnTheDayDTO.PUNCH_STATUS_UN_PUNCH) + .le(AttendancePunchRecordDO::getLatestPunchTime, now); + AttendancePunchRecordDO attendancePunchRecordDO = new AttendancePunchRecordDO(); + attendancePunchRecordDO.setStatus(AttendanceOnTheDayDTO.PUNCH_STATUS_MISS); + attendancePunchRecordMapper.update(attendancePunchRecordDO, le); log.info("结束 修改考勤缺卡"); // 返回执行成功 return ReturnT.SUCCESS; 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 bc981280..b31a262f 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 @@ -80,6 +80,7 @@ public class AttendanceStatisticsJob { 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); @@ -117,8 +118,10 @@ public class AttendanceStatisticsJob { attendancePunchRecordDO.setFieldServiceFlag(Constants.FALSE); attendancePunchRecordDO.setNextDayFlag(Constants.TRUE); attendancePunchRecordDO.setDayTime(time); - LocalDateTime shouldPunchTime = LocalDateTime.ofInstant(DateUtils.buildHHmmTime(attendanceOnTheDayDTO.getTime()).toInstant(), ZoneId.systemDefault()); + 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); } } 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 fe290bd1..97924067 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 @@ -112,8 +112,9 @@ public class AttendanceServiceImpl implements AttendanceService { @Override @Transactional(rollbackFor = Exception.class) public AttendancePunchVO punch(AttendancePunchDTO dto) { - AttendancePunchPageVO pageVO = this.getPunchPage(new AttendancePunchPageDTO().setLongitude(dto.getLongitude()) - .setLatitude(dto.getLatitude()).setFlag(true).setLocalDateTime(dto.getLocalDateTime()).setUserId(dto.getUserId())); + AttendancePunchPageVO pageVO = this.getPunchPage(new AttendancePunchPageDTO().setPunchType(dto.getPunchType()) + .setLongitude(dto.getLongitude()).setLatitude(dto.getLatitude()) + .setFlag(true).setLocalDateTime(dto.getLocalDateTime()).setUserId(dto.getUserId())); // -- 获取当天的考勤记录 if (Constants.FALSE.equals(pageVO.getInGroup())) { throw exception(NOT_IN_THE_ATTENDANCE_GROUP); @@ -141,7 +142,7 @@ public class AttendanceServiceImpl implements AttendanceService { .setAttendanceGroupShiftId(pageVO.getAttendanceGroupShiftDO().getId()) .setAttendanceGroupShiftItemId(pageVO.getAttendanceGroupShiftItemId()) .setType(pageVO.getActivationGroup().getType()) - .setPunchType(AttendanceGroupDO.PUNCH_TYPE_MI_NI_APP) + .setPunchType(dto.getPunchType()) .setWorkType(pageVO.getType()) .setLevel(dayDTO.getLevel()) .setStatus(status) @@ -181,6 +182,7 @@ public class AttendanceServiceImpl implements AttendanceService { dayDTO.setPunchAddress(dto.getPunchAddress()); dayDTO.setRemark(dto.getRemark()); dayDTO.setImage(dto.getImage()); + // TODO: 2024/5/31 可能会有问题 dayDTO.setShouldPunchTime(pageVO.getShouldPunchTime()); dayDTO.setPunchLocalDateTime(dto.getLocalDateTime()); dayDTO.setLateTime(attendancePunchRecordSaveReqVO.getLateTime()); @@ -189,6 +191,7 @@ public class AttendanceServiceImpl implements AttendanceService { String mapKey = dto.getUserId().toString(); stringRedisTemplate.opsForHash().put(pageVO.getRedisKey(), mapKey, JSONUtil.toJsonStr(attendanceOnTheDayDTOS)); } + vo.setStatus(status); vo.setActivationGroup(pageVO.getActivationGroup()); vo.setAttendanceGroupShiftDO(pageVO.getAttendanceGroupShiftDO()); vo.setAttendanceOnTheDayDTOS(attendanceOnTheDayDTOS); @@ -222,9 +225,10 @@ public class AttendanceServiceImpl implements AttendanceService { LocalDateTime localDateTime = dto.getLocalDateTime(); AttendanceGroupDO activationGroup = dto.getActivationGroup(); vo.setFieldworkFlag(activationGroup.getFieldworkFlag()); - // - 根据经纬度判断是否在对应班组的打卡点上 - vo.setPunchPoint(GeoUtil.distance(Double.parseDouble(dto.getLatitude()), Double.parseDouble(dto.getLongitude()) - , Double.parseDouble(activationGroup.getLatitude()), Double.parseDouble(activationGroup.getLongitude()), activationGroup.getScope())); + // - 根据经纬度判断是否在对应班组的打卡点上 - 如果是考勤机的话默认就是在打卡点 + vo.setPunchPoint(AttendanceGroupDO.PUNCH_TYPE_ATTENDANCE_MACHINE.equals(dto.getPunchType()) ? Constants.TRUE : + GeoUtil.distance(Double.parseDouble(dto.getLatitude()), Double.parseDouble(dto.getLongitude()) + , Double.parseDouble(activationGroup.getLatitude()), Double.parseDouble(activationGroup.getLongitude()), activationGroup.getScope())); // -- 获取班次 AttendanceGroupShiftDO attendanceGroupShiftDO = attendanceGroupShiftService.getGroupShift(vo.getAttendanceGroupShiftId()); @@ -236,21 +240,17 @@ public class AttendanceServiceImpl implements AttendanceService { String yesterdayStr = LocalDateTimeUtil.offset(localDateTime, -1, ChronoUnit.DAYS).format(Constants.REPO_DATE_FORMAT); - String toDayStr = localDateTime.format(Constants.REPO_DATE_FORMAT); - String targetDayStr = null; - if (attendanceGroupShiftDO.getNextDayFlag() == null || Constants.FALSE.equals(attendanceGroupShiftDO.getNextDayFlag())) { - targetDayStr = toDayStr; - } else { - // 如果跨天的话 所以不能够直接通过判断是否跨天来取redis 数据 - 而是应该获取最晚打下班卡时间判断当前时间是否在最晚打卡下班时间之后 - 如果是的话 插入今天的数据 - targetDayStr = yesterdayStr; - // -- 获取最后一个元素 - AttendanceGroupShiftItemDO attendanceOnTheDayDTO = CollUtil.getLast(attendanceGroupShiftItemDOList); - // -- 获取最晚下班打卡时间 - LocalDateTime endTime = LocalDateTime.ofInstant(DateUtils.buildHHmmTime(attendanceOnTheDayDTO.getEndTime()).toInstant(), ZoneId.systemDefault()).plusMinutes(attendanceOnTheDayDTO.getAfterPunchTimeDownWork()); - if (localDateTime.isAfter(endTime)) { - targetDayStr = toDayStr; + String targetDayStr = localDateTime.format(Constants.REPO_DATE_FORMAT); + AttendanceGroupShiftItemDO last = CollUtil.getLast(attendanceGroupShiftItemDOList); + // -- 如果最后的时间是跨天 那么 需要判断当前时间是否在跨天时间段内 - 如果是的话取昨天的的yyyy-MM-dd + if (Arrays.asList(1, 2).contains(last.getNextDayFlag())) { + LocalDateTime endOfDay = LocalDateTime.ofInstant(DateUtils.buildHHmmTime(last.getEndTime()).toInstant(), ZoneId.systemDefault()).plusMinutes(last.getAfterPunchTimeDownWork()); + LocalDateTime beginOfDay = LocalDateTimeUtil.beginOfDay(endOfDay); + if (LocalDateTimeUtil.isIn(localDateTime, beginOfDay, endOfDay)) { + targetDayStr = yesterdayStr; } } + List attendanceOnTheDayDTOS = this.getAttendanceOnTheDay(key, mapKey, targetDayStr, attendanceGroupShiftItemDOList); // -- 这里没有的情况 只可能是redis 数据库崩了/或者班次子表没数据 - 暂时先返回不需要考勤 if (attendanceOnTheDayDTOS.isEmpty()) { @@ -376,6 +376,7 @@ public class AttendanceServiceImpl implements AttendanceService { dto.setAfterPunchTime(attendanceGroupShiftItemDO.getAfterPunchTimeUpWork()); dto.setPunchStatus(AttendanceOnTheDayDTO.PUNCH_STATUS_UN_PUNCH); dto.setFieldServiceFlag(Constants.FALSE); + dto.setNextDayFlag(attendanceGroupShiftItemDO.getNextDayFlag() == 0 || attendanceGroupShiftItemDO.getNextDayFlag() == 2 ? 0 : 1); attendanceOnTheDayDTOS.add(dto); dto = new AttendanceOnTheDayDTO(); @@ -390,6 +391,7 @@ public class AttendanceServiceImpl implements AttendanceService { dto.setAfterPunchTime(attendanceGroupShiftItemDO.getAfterPunchTimeDownWork()); dto.setPunchStatus(AttendanceOnTheDayDTO.PUNCH_STATUS_UN_PUNCH); dto.setFieldServiceFlag(Constants.FALSE); + dto.setNextDayFlag(attendanceGroupShiftItemDO.getNextDayFlag() == 0 ? 0 : 1); attendanceOnTheDayDTOS.add(dto); } return attendanceOnTheDayDTOS; 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 5e43fbb4..376bbcc0 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 @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.system.controller.admin.group.vo.AttendanceGroupS import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO; import javax.validation.Valid; +import java.util.List; /** * 考勤组 Service 接口 @@ -61,4 +62,11 @@ public interface AttendanceGroupService { AttendanceGroupDO getByUserId(Long userId); void test(); + + /** + * 获取所有 + * + * @return + */ + List getAll(); } \ 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 3391c888..6ed83338 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 @@ -129,6 +129,8 @@ public class AttendanceGroupServiceImpl implements AttendanceGroupService { 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); @@ -141,11 +143,11 @@ public class AttendanceGroupServiceImpl implements AttendanceGroupService { for (Map.Entry entry : map.entrySet()) { AttendanceGroupDO attendanceGroupDO = groupMap.get(entry.getKey()); List userIds = groupUserMap.get(entry.getKey()); - if (CollectionUtil.isEmpty(userIds)){ + if (CollectionUtil.isEmpty(userIds)) { continue; } List attendanceGroupShiftItemDOS = itemMaps.get(entry.getValue()); - if (CollectionUtil.isEmpty(attendanceGroupShiftItemDOS)){ + if (CollectionUtil.isEmpty(attendanceGroupShiftItemDOS)) { continue; } List attendanceOnTheDayDTOS = attendanceService.buildAttendanceOnTheDay(attendanceGroupShiftItemDOS); @@ -154,6 +156,7 @@ public class AttendanceGroupServiceImpl implements AttendanceGroupService { 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()); @@ -164,10 +167,12 @@ public class AttendanceGroupServiceImpl implements AttendanceGroupService { attendancePunchRecordDO.setStatus(AttendanceOnTheDayDTO.PUNCH_STATUS_UN_PUNCH); attendancePunchRecordDO.setFieldServiceFlag(Constants.FALSE); attendancePunchRecordDO.setDayTime(time); - LocalDateTime shouldPunchTime = LocalDateTime.ofInstant(DateUtils.buildHHmmTime(attendanceOnTheDayDTO.getTime()).toInstant(), ZoneId.systemDefault()); + 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); - // TODO: 2024/5/24 } } } @@ -176,6 +181,11 @@ public class AttendanceGroupServiceImpl implements AttendanceGroupService { } } + @Override + public List getAll() { + return attendanceGroupMapper.selectList(); + } + private Map getAttendanceGroupShiftIdGroupByGroup(List attendanceGroupDOS, LocalDateTime localDateTime) { Map map = new HashMap<>(); 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 b8e8797e..fd3790fd 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 @@ -1,28 +1,34 @@ package cn.iocoder.yudao.module.system.service.attendance.groupshift; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.LocalDateTimeUtil; 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.groupshift.vo.AttendanceGroupShiftPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.groupshift.vo.AttendanceGroupShiftSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.groupshift.vo.AttendanceGroupShiftVO; +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.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.scheduling.AttendanceSchedulingMapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.*; 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.GROUP_SHIFT_NOT_EXISTS; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; /** * 考勤组班次 Service 实现类 @@ -37,14 +43,23 @@ public class AttendanceGroupShiftServiceImpl implements AttendanceGroupShiftServ private AttendanceGroupShiftMapper groupShiftMapper; @Resource private AttendanceGroupShiftItemMapper groupShiftItemMapper; + @Resource + private AttendanceFixedMapper attendanceFixedMapper; + @Resource + private AttendanceSchedulingMapper attendanceSchedulingMapper; + @Override + @Transactional(rollbackFor = Exception.class) public Long createGroupShift(AttendanceGroupShiftSaveReqVO createReqVO) { // 插入 AttendanceGroupShiftDO groupShift = BeanUtils.toBean(createReqVO, AttendanceGroupShiftDO.class); - groupShiftMapper.insert(groupShift); // -- 插入子表 List items = BeanUtils.toBean(createReqVO.getItems(), AttendanceGroupShiftItemDO.class); + items = insertSpanDay(items); + long count = items.stream().filter(a -> a.getNextDayFlag() == 1).count(); + groupShift.setNextDayFlag(count > 0 ? 1 : 0); + groupShiftMapper.insert(groupShift); for (AttendanceGroupShiftItemDO item : items) { item.setKqAttendanceGroupShiftId(groupShift.getId()); } @@ -53,21 +68,92 @@ public class AttendanceGroupShiftServiceImpl implements AttendanceGroupShiftServ return groupShift.getId(); } + private static List insertSpanDay(List items) { + //先根据items中的level进行升序排序 + items = items.stream().sorted(Comparator.comparingInt(AttendanceGroupShiftItemDO::getLevel)).collect(Collectors.toList()); + AttendanceGroupShiftItemDO first = CollectionUtil.getFirst(items); + //获取明天时间 + LocalDateTime tomorrow = LocalDateTimeUtil.offset(LocalDateTime.now(), 1, ChronoUnit.DAYS); + LocalDateTime today = LocalDateTime.now(); + // -- 开始时间 - 这个肯定是当天的 + Date todayStartTime = DateUtils.buildHHmmTime(first.getBeginTime(), today); + int nextDay = 0; + for (AttendanceGroupShiftItemDO item : items) { + Date beginTime = DateUtils.buildHHmmTime(item.getBeginTime(), nextDay == 0 ? today : tomorrow); + Date endTime = DateUtils.buildHHmmTime(item.getEndTime(), nextDay == 0 ? today : tomorrow); + int nextDayFlag = nextDay; + if (nextDay == 0) { + if (beginTime.getTime() < todayStartTime.getTime()) { + nextDayFlag = 2; + nextDay = 1; + } + if (endTime.getTime() < todayStartTime.getTime()) { + nextDayFlag = nextDayFlag == 0 ? 2 : 1; + nextDay = 1; + } + } + item.setNextDayFlag(nextDayFlag); + } + if (nextDay == 1) { + AttendanceGroupShiftItemDO last = CollectionUtil.getLast(items); + Date endTime = DateUtils.buildHHmmTime(last.getEndTime(), tomorrow); + //区间大于1天 + Date deadlineTime = DateUtils.buildHHmmTime(first.getBeginTime(), tomorrow); + if (endTime.getTime() > deadlineTime.getTime()) { + throw exception(THE_ATTENDANCE_INTERVAL_SHALL_NOT_EXCEED24_HOURS); + } + } + return items; + } + @Override + @Transactional(rollbackFor = Exception.class) public void updateGroupShift(AttendanceGroupShiftSaveReqVO updateReqVO) { // 校验存在 validateGroupShiftExists(updateReqVO.getId()); // 更新 - AttendanceGroupShiftDO updateObj = BeanUtils.toBean(updateReqVO, AttendanceGroupShiftDO.class); + AttendanceGroupShiftDO attendanceGroupShiftDO = BeanUtils.toBean(updateReqVO, AttendanceGroupShiftDO.class); // -- 插入子表 List items = BeanUtils.toBean(updateReqVO.getItems(), AttendanceGroupShiftItemDO.class); - groupShiftItemMapper.updateBatch(items); - - groupShiftMapper.updateById(updateObj); + items = insertSpanDay(items); + List oldItems = groupShiftItemMapper.selectList(new LambdaQueryWrapper() + .eq(AttendanceGroupShiftItemDO::getKqAttendanceGroupShiftId, updateReqVO.getId())); + if (CollectionUtil.isEmpty(oldItems)) { + groupShiftItemMapper.insertBatch(items); + return; + } + //新增 + List saveList = items.stream().filter(a -> a.getId() == null).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(saveList)) { + for (AttendanceGroupShiftItemDO attendanceGroupShiftItemDO : saveList) { + attendanceGroupShiftItemDO.setKqAttendanceGroupShiftId(updateReqVO.getId()); + } + groupShiftItemMapper.insertBatch(saveList); + } + //修改 + List editList = items.stream().filter(a -> a.getId() != null).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(editList)) { + groupShiftItemMapper.updateBatch(editList); + } + //删除 + // -- 需要删除的 - + List oldIds = oldItems.stream().map(AttendanceGroupShiftItemDO::getId).collect(Collectors.toList()); + List newIds = editList.stream().map(AttendanceGroupShiftItemDO::getId).collect(Collectors.toList()); + List delIds = new ArrayList<>(CollectionUtil.subtract(oldIds, newIds)); + if (!delIds.isEmpty()) { + groupShiftItemMapper.deleteBatchIds(delIds); + } + groupShiftMapper.updateById(attendanceGroupShiftDO); } @Override public void deleteGroupShift(Long id) { + //查看当前考勤组班次是否在使用 如果是的话 则不允许删除 + Long fixedNum = attendanceFixedMapper.selectCount(new LambdaQueryWrapper().eq(AttendanceFixedDO::getAttendanceGroupShiftId, id)); + Long schedulingNum = attendanceSchedulingMapper.selectCount(new LambdaQueryWrapper().eq(AttendanceSchedulingDO::getAttendanceGroupShiftId, id)); + if (fixedNum + schedulingNum > 0) { + throw exception(GROUP_SHIFT_IN_USE); + } // 校验存在 validateGroupShiftExists(id); // 删除 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punch/dto/AttendanceOnTheDayDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punch/dto/AttendanceOnTheDayDTO.java index 9c433fac..a30b3c24 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punch/dto/AttendanceOnTheDayDTO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/punch/dto/AttendanceOnTheDayDTO.java @@ -50,6 +50,9 @@ public class AttendanceOnTheDayDTO { @Schema(description = "是否外勤 0否 1是", example = "1") private Integer fieldServiceFlag; + @Schema(description = "是否跨天 0否 1是", example = "1") + private Integer nextDayFlag; + @Schema(description = "用户打卡地点") private String punchAddress; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/scheduling/AttendanceSchedulingServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/scheduling/AttendanceSchedulingServiceImpl.java index 1cd6e83d..04be0b63 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/scheduling/AttendanceSchedulingServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/attendance/scheduling/AttendanceSchedulingServiceImpl.java @@ -116,7 +116,7 @@ public class AttendanceSchedulingServiceImpl implements AttendanceSchedulingServ @Override public AttendanceSchedulingDO getSchedulingByIndexDay(Long attendanceGroupId, Integer indexDay) { List list = schedulingMapper.selectList(new LambdaQueryWrapper() - .eq(AttendanceSchedulingDO::getAttendanceGroupShiftId, attendanceGroupId) + .eq(AttendanceSchedulingDO::getAttendanceGroupId, attendanceGroupId) .eq(AttendanceSchedulingDO::getIndexDay, indexDay)); if (!list.isEmpty()) { return list.get(0); 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 4b600660..a4aa6666 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 @@ -154,6 +154,14 @@ public interface AdminUserService { */ List getUserByDeptIds(Collection deptIds); + /** + * 获取部门下人员过滤掉考勤组内有的 + * + * @param deptIds + * @return + */ + List selectByDeptIdsFilterGroupUser(Collection deptIds); + /** * 获得指定部门的用户数组(除去当前登录者用户) * @@ -251,13 +259,15 @@ public interface AdminUserService { /** * 获取用户的签名图片地址 + * * @param userId * @return */ - String getSignImgPath(Long userId) ; + String getSignImgPath(Long userId); /** * 获取 岗位为总监或副总裁 以及部门层级为2级或3级的负责人的用户编号 + * * @return 用户编号 */ List getUserByBoss(); 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 31eef3e9..1436fd03 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 @@ -185,17 +185,17 @@ public class AdminUserServiceImpl implements AdminUserService { throw exception(USER_NOT_EXISTS); } - byte[] content = IoUtil.readBytes(avatarFile) ; - String avatar = "" ; - if(StringUtil.isEmpty(user.getAvatar())) { + byte[] content = IoUtil.readBytes(avatarFile); + String avatar = ""; + if (StringUtil.isEmpty(user.getAvatar())) { //没有头像 新增 // 存储文件 // BusinessFile file = new BusinessFile().setBusinessType(3L).setContent(content).setName(name); - avatar = fileApi.createBusinessFile(3L, name, content) ; - }else { + avatar = fileApi.createBusinessFile(3L, name, content); + } else { //有头像 修改 //变更infra_file_content的content字段内容 - avatar = fileApi.updateBusinessFileContent(user.getAvatar(), 3L, name, content) ; + avatar = fileApi.updateBusinessFileContent(user.getAvatar(), 3L, name, content); } user.setAvatar(avatar); userMapper.updateById(user); @@ -273,6 +273,14 @@ public class AdminUserServiceImpl implements AdminUserService { return userMapper.selectByDeptIds(deptIds); } + @Override + public List selectByDeptIdsFilterGroupUser(Collection deptIds) { + if (CollUtil.isEmpty(deptIds)) { + return Collections.emptyList(); + } + return userMapper.selectByDeptIdsFilterGroupUser(deptIds); + } + @Override public List getListUserByDeptId(Long deptId) { @@ -546,7 +554,7 @@ public class AdminUserServiceImpl implements AdminUserService { public String getSignImgPath(Long userId) { //2L 用户签名 String path = fileApi.getUserSignImgPath(userId).getData(); - return path ; + return path; } @Override 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 f6985cc7..5bdcc476 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 @@ -41,4 +41,19 @@ ) AND b.leader_user_id = a.id) + \ No newline at end of file