请假考勤调整
This commit is contained in:
parent
24d3508ea8
commit
2ae403942e
@ -0,0 +1,27 @@
|
|||||||
|
package cn.iocoder.yudao.framework.common.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class BpmOALeaveDTO {
|
||||||
|
/**
|
||||||
|
* 请假表单主键
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 申请人的用户编号
|
||||||
|
*
|
||||||
|
* 关联 AdminUserDO 的 id 属性
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
}
|
@ -8,6 +8,7 @@ import cn.hutool.http.HttpUtil;
|
|||||||
import cn.hutool.json.JSONArray;
|
import cn.hutool.json.JSONArray;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.Constants;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.*;
|
import java.time.*;
|
||||||
@ -257,6 +258,25 @@ public class DateUtils {
|
|||||||
return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now());
|
return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个时间区间 - 获取两个时间区间的所有日期
|
||||||
|
*
|
||||||
|
* @param beginTime
|
||||||
|
* @param endTime
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<String> betweenDayList(LocalDateTime beginTime, LocalDateTime endTime) {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
long num = LocalDateTimeUtil.between(beginTime, endTime, ChronoUnit.DAYS);
|
||||||
|
|
||||||
|
for (int i = 0; i <= num; i++) {
|
||||||
|
LocalDateTime dateTime = LocalDateTimeUtil.offset(beginTime, i, ChronoUnit.DAYS);
|
||||||
|
list.add(dateTime.format(Constants.REPO_DATE_FORMAT));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取两个时间区间 - 获取两个时间区间的所有日期
|
* 获取两个时间区间 - 获取两个时间区间的所有日期
|
||||||
*
|
*
|
||||||
@ -357,6 +377,7 @@ public class DateUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 将1-7的数字转换为对应的中文星期表示
|
* 将1-7的数字转换为对应的中文星期表示
|
||||||
|
*
|
||||||
* @param dayOfWeek 数字形式的星期几,1-7分别代表星期一到星期日
|
* @param dayOfWeek 数字形式的星期几,1-7分别代表星期一到星期日
|
||||||
* @return 中文表示的星期几
|
* @return 中文表示的星期几
|
||||||
*/
|
*/
|
||||||
|
@ -20,6 +20,7 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode OA_DEPART_BM_POST_NOT_EXISTS = new ErrorCode(1_009_001_005, "部门的部门经理不存在");
|
ErrorCode OA_DEPART_BM_POST_NOT_EXISTS = new ErrorCode(1_009_001_005, "部门的部门经理不存在");
|
||||||
ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1_009_001_006, "HR岗位未设置");
|
ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1_009_001_006, "HR岗位未设置");
|
||||||
ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1_009_001_007, "请假天数必须>=1");
|
ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1_009_001_007, "请假天数必须>=1");
|
||||||
|
ErrorCode FAILED_TO_APPLY_FOR_LEAVE = new ErrorCode(1_009_001_008, "请假失败");
|
||||||
|
|
||||||
ErrorCode OA_REIMBURSEMENT_NOT_EXISTS = new ErrorCode(1_009_001_100, "报销申请不存在");
|
ErrorCode OA_REIMBURSEMENT_NOT_EXISTS = new ErrorCode(1_009_001_100, "报销申请不存在");
|
||||||
ErrorCode OA_EVECTION_NOT_EXISTS = new ErrorCode(1_009_001_101, "出差申请不存在");
|
ErrorCode OA_EVECTION_NOT_EXISTS = new ErrorCode(1_009_001_101, "出差申请不存在");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.rpc.config;
|
package cn.iocoder.yudao.module.bpm.framework.rpc.config;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.attendance.AttendanceApi;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
||||||
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
|
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
|
||||||
@ -15,8 +16,8 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@EnableFeignClients(clients = {FileApi.class,RoleApi.class, DeptApi.class, PostApi.class, AdminUserApi.class, SmsSendApi.class, DictDataApi.class, NotifyMessageSendApi.class,
|
@EnableFeignClients(clients = {FileApi.class, RoleApi.class, DeptApi.class, PostApi.class, AdminUserApi.class, SmsSendApi.class, DictDataApi.class, NotifyMessageSendApi.class,
|
||||||
SubscribeMessageSendApi.class, SocialClientApi.class, UsersExtApi.class
|
SubscribeMessageSendApi.class, SocialClientApi.class, UsersExtApi.class, AttendanceApi.class
|
||||||
})
|
})
|
||||||
public class RpcConfiguration {
|
public class RpcConfiguration {
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.service.oa;
|
package cn.iocoder.yudao.module.bpm.service.oa;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.BpmOALeaveDTO;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOALeaveRpcVO;
|
import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOALeaveRpcVO;
|
||||||
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
|
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
|
||||||
@ -12,17 +16,21 @@ import cn.iocoder.yudao.module.bpm.convert.oa.BpmOALeaveConvert;
|
|||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOALeaveMapper;
|
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOALeaveMapper;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||||
|
import cn.iocoder.yudao.module.system.api.attendance.AttendanceApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.attendance.dto.AttendancePunchRecordDTO;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.FAILED_TO_APPLY_FOR_LEAVE;
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_LEAVE_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_LEAVE_NOT_EXISTS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,6 +54,8 @@ public class BpmOALeaveServiceImpl extends BpmOABaseService implements BpmOALeav
|
|||||||
private BpmProcessInstanceApi processInstanceApi;
|
private BpmProcessInstanceApi processInstanceApi;
|
||||||
@Resource
|
@Resource
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
@Resource
|
||||||
|
private AttendanceApi attendanceApi;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@ -77,6 +87,7 @@ public class BpmOALeaveServiceImpl extends BpmOABaseService implements BpmOALeav
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateLeaveResult(Long id, Integer result) {
|
public void updateLeaveResult(Long id, Integer result) {
|
||||||
BpmOALeaveDO bpmOALeaveDO = validateLeaveExists(id);
|
BpmOALeaveDO bpmOALeaveDO = validateLeaveExists(id);
|
||||||
leaveMapper.updateById(new BpmOALeaveDO().setId(id).setResult(result));
|
leaveMapper.updateById(new BpmOALeaveDO().setId(id).setResult(result));
|
||||||
@ -84,17 +95,28 @@ public class BpmOALeaveServiceImpl extends BpmOABaseService implements BpmOALeav
|
|||||||
// -- 如果是的话 先插入到redis中 - (事前请假)
|
// -- 如果是的话 先插入到redis中 - (事前请假)
|
||||||
// -- 如果不是 则查询相应的考勤 修改考勤状态 (事后请假 - 还需要判断结束时间是否)
|
// -- 如果不是 则查询相应的考勤 修改考勤状态 (事后请假 - 还需要判断结束时间是否)
|
||||||
//
|
//
|
||||||
// if (result.equals(BpmProcessInstanceResultEnum.APPROVE.getResult())) {
|
LocalDateTime now = LocalDateTimeUtil.now();
|
||||||
// if (LocalDateTimeUtil.between(bpmOALeaveDO.getStartTime(), LocalDateTimeUtil.now()).toDays() > 0) {
|
if (result.equals(BpmProcessInstanceResultEnum.APPROVE.getResult())) {
|
||||||
// // -- 插入到redis中
|
// 事后请假修改考勤 = 考勤的预设已经生成过了 - 并且已经在表里面存在了 - 所以要找到表中的数据 - 修改考勤状态
|
||||||
// LeaveVO leaveVO = new LeaveVO();
|
CommonResult commonResult = attendanceApi.askingForLeaveAfterwardsToModifyAttendance(new AttendancePunchRecordDTO()
|
||||||
// BeanUtil.copyProperties(bpmOALeaveDO, leaveVO);
|
.setUserId(bpmOALeaveDO.getUserId())
|
||||||
// stringRedisTemplate.opsForHash().put("leave", bpmOALeaveDO.getUserId().toString(), JSONUtil.toJsonStr(leaveVO));
|
.setStartTime(bpmOALeaveDO.getStartTime())
|
||||||
// } else {
|
.setEndTime(bpmOALeaveDO.getEndTime())
|
||||||
// // -- 查询相应的考勤 修改考勤状态
|
.setLeaveId(id)
|
||||||
//
|
);
|
||||||
// }
|
if (!commonResult.isSuccess()) {
|
||||||
// }
|
throw exception(FAILED_TO_APPLY_FOR_LEAVE);
|
||||||
|
}
|
||||||
|
if (now.isBefore(bpmOALeaveDO.getEndTime())) {
|
||||||
|
// 事前请假 = 考勤预设可能还没有生成 - 因为可能请假好几天 - 所以这里处理就比较麻烦点 - 先看下考勤表里面有没有在这个区间的考勤 - 如果有的话先修改考勤状态 -
|
||||||
|
// 然后将数据先存入redis - 在设置考勤预设的时候 就去redis 中查询是否有请假 - 有的话预设的时候就预设进去
|
||||||
|
BpmOALeaveDTO dto = new BpmOALeaveDTO();
|
||||||
|
BeanUtil.copyProperties(bpmOALeaveDO, dto);
|
||||||
|
String key = "leave" + "_" + bpmOALeaveDO.getUserId().toString();
|
||||||
|
stringRedisTemplate.opsForHash().put(key, id.toString(), JSONUtil.toJsonStr(dto));
|
||||||
|
// -- 将请假put到redis的map中 -
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BpmOALeaveDO validateLeaveExists(Long id) {
|
private BpmOALeaveDO validateLeaveExists(Long id) {
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.api.attendance;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.module.system.api.attendance.dto.AttendancePunchRecordDTO;
|
||||||
|
import cn.iocoder.yudao.module.system.api.attendance.vo.AttendancePunchRecordVO;
|
||||||
|
import cn.iocoder.yudao.module.system.enums.ApiConstants;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||||
|
@Tag(name = "RPC 服务 - 考勤")
|
||||||
|
public interface AttendanceApi {
|
||||||
|
|
||||||
|
String PREFIX = ApiConstants.PREFIX + "/attendance";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping(PREFIX + "/askingForLeaveAfterwardsToModifyAttendance")
|
||||||
|
@Operation(summary = "获取考勤记录")
|
||||||
|
CommonResult askingForLeaveAfterwardsToModifyAttendance(@RequestBody AttendancePunchRecordDTO attendancePunchRecordDTO);
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.api.attendance.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户打卡记录 DTO
|
||||||
|
*
|
||||||
|
* @author 艾楷
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class AttendancePunchRecordDTO {
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
/**
|
||||||
|
* 请假id 对应bpm_oa_leave表id
|
||||||
|
*/
|
||||||
|
private Long leaveId;
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.api.attendance.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户打卡记录 DO
|
||||||
|
*
|
||||||
|
* @author 艾楷
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AttendancePunchRecordVO {
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 考勤组管理员id
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 部门id
|
||||||
|
*/
|
||||||
|
private Long deptId;
|
||||||
|
/**
|
||||||
|
* 考勤组id
|
||||||
|
*/
|
||||||
|
private Long attendanceGroupId;
|
||||||
|
/**
|
||||||
|
* 考勤组名称
|
||||||
|
*/
|
||||||
|
private String attendanceGroupName;
|
||||||
|
/**
|
||||||
|
* 班次id
|
||||||
|
*/
|
||||||
|
private Long attendanceGroupShiftId;
|
||||||
|
/**
|
||||||
|
* 班次名称
|
||||||
|
*/
|
||||||
|
private String attendanceGroupShiftName;
|
||||||
|
/**
|
||||||
|
* 班次子表id
|
||||||
|
*/
|
||||||
|
private Long attendanceGroupShiftItemId;
|
||||||
|
/**
|
||||||
|
* 考勤类型 1固定班制 2排班制
|
||||||
|
*/
|
||||||
|
private Integer type;
|
||||||
|
/**
|
||||||
|
* 打卡类型 1考勤机 2小程序范围打卡
|
||||||
|
*/
|
||||||
|
private Integer punchType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上下班类型 0上班 1下班
|
||||||
|
*/
|
||||||
|
private Integer workType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 级别 1到~
|
||||||
|
*/
|
||||||
|
private Integer level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡状态 0正常 1迟到 2早退 3缺卡 4未打卡(还没到打卡时间) 5补卡 6请假
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 明天的打卡 0否 1是 (业务需要 先把明天的打卡统计出来)
|
||||||
|
*/
|
||||||
|
private Integer nextDayFlag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否外勤 0否 1是
|
||||||
|
*/
|
||||||
|
private Integer fieldServiceFlag;
|
||||||
|
/**
|
||||||
|
* 日期yyyy-MM-dd格式 (归属于哪一天)
|
||||||
|
*/
|
||||||
|
private String dayTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期yyyy-MM-dd格式 (实际是哪一天)
|
||||||
|
*/
|
||||||
|
private String actualDayTime;
|
||||||
|
/**
|
||||||
|
* 打卡时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime punchTime;
|
||||||
|
/**
|
||||||
|
* 应打卡时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime shouldPunchTime;
|
||||||
|
/**
|
||||||
|
* 最晚打卡时间(超过即为缺卡)
|
||||||
|
*/
|
||||||
|
private LocalDateTime latestPunchTime;
|
||||||
|
/**
|
||||||
|
* 打卡备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
/**
|
||||||
|
* 图片
|
||||||
|
*/
|
||||||
|
private String image;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户打卡地点
|
||||||
|
*/
|
||||||
|
private String punchAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迟到时长时间戳
|
||||||
|
*/
|
||||||
|
private Long lateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 早退时长时间戳
|
||||||
|
*/
|
||||||
|
private Long leaveEarlyTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加班时长时间戳
|
||||||
|
*/
|
||||||
|
private Long workOvertimeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已提醒 0否 1是
|
||||||
|
*/
|
||||||
|
private Integer remindFlag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假json对象
|
||||||
|
*/
|
||||||
|
private String leaveJson;
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.api.attendance;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.module.system.api.attendance.dto.AttendancePunchRecordDTO;
|
||||||
|
import cn.iocoder.yudao.module.system.service.attendance.punchrecord.AttendancePunchRecordService;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||||
|
@Validated
|
||||||
|
public class AttendanceApiImpl implements AttendanceApi {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AttendancePunchRecordService attendancePunchRecordService;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult askingForLeaveAfterwardsToModifyAttendance(AttendancePunchRecordDTO attendancePunchRecordDTO) {
|
||||||
|
attendancePunchRecordService.askingForLeaveAfterwardsToModifyAttendance(attendancePunchRecordDTO);
|
||||||
|
return CommonResult.success("ok");
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,8 @@ public class AttendanceStatisticsVO {
|
|||||||
private List<AttendancePunchStatisticsVO> fieldServiceNumber;
|
private List<AttendancePunchStatisticsVO> fieldServiceNumber;
|
||||||
@Schema(description = "休息日")
|
@Schema(description = "休息日")
|
||||||
private List<AttendancePunchStatisticsVO> restDays;
|
private List<AttendancePunchStatisticsVO> restDays;
|
||||||
|
@Schema(description = "请假次数")
|
||||||
|
private List<AttendancePunchStatisticsVO> leaveNumber;
|
||||||
@Schema(description = "头部次数")
|
@Schema(description = "头部次数")
|
||||||
private CalculateNum calculateNum;
|
private CalculateNum calculateNum;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class AttendanceStatusByDayVO {
|
public class AttendanceStatusByDayVO {
|
||||||
@Schema(description = "状态 0正常 1异常(迟到/早退/缺卡)")
|
@Schema(description = "状态 0正常 1异常(迟到/早退/缺卡/请假/补卡)")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
@Schema(description = "是否有提交过 请假/加班/出差/外出/补卡 申请 0否 1是")
|
@Schema(description = "是否有提交过 请假/加班/出差/外出/补卡 申请 0否 1是")
|
||||||
private Integer submitStatus = 0;
|
private Integer submitStatus = 0;
|
||||||
|
@ -27,6 +27,8 @@ public class CalculateNum {
|
|||||||
String totalEarlyDeparturesTimeStr;
|
String totalEarlyDeparturesTimeStr;
|
||||||
@Schema(description = "缺卡总次数")
|
@Schema(description = "缺卡总次数")
|
||||||
int totalMissingCardsNumber = 0;
|
int totalMissingCardsNumber = 0;
|
||||||
|
@Schema(description = "请假总次数")
|
||||||
|
int totalLeaveNumber = 0;
|
||||||
@Schema(description = "上班缺卡总次数")
|
@Schema(description = "上班缺卡总次数")
|
||||||
int totalUpMissingCardsNumber = 0;
|
int totalUpMissingCardsNumber = 0;
|
||||||
@Schema(description = "下班缺卡总次数")
|
@Schema(description = "下班缺卡总次数")
|
||||||
|
@ -30,6 +30,9 @@ public class TeamAttendanceStatisticsByCycleVO {
|
|||||||
@Schema(description = "外勤")
|
@Schema(description = "外勤")
|
||||||
private List<TeamAttendancePunchStatisticsVO> fieldServiceList;
|
private List<TeamAttendancePunchStatisticsVO> fieldServiceList;
|
||||||
|
|
||||||
|
@Schema(description = "请假")
|
||||||
|
private List<TeamAttendancePunchStatisticsVO> leaveList;
|
||||||
|
|
||||||
@Schema(description = "顶部")
|
@Schema(description = "顶部")
|
||||||
private TeamAttendanceStatisticsNumVO teamAttendanceStatisticsNumVO;
|
private TeamAttendanceStatisticsNumVO teamAttendanceStatisticsNumVO;
|
||||||
|
|
||||||
@ -52,6 +55,9 @@ public class TeamAttendanceStatisticsByCycleVO {
|
|||||||
@Schema(description = "缺卡次数")
|
@Schema(description = "缺卡次数")
|
||||||
private Integer missingCardNum;
|
private Integer missingCardNum;
|
||||||
|
|
||||||
|
@Schema(description = "请假次数")
|
||||||
|
private Integer leaveNum;
|
||||||
|
|
||||||
@Schema(description = "旷工次数")
|
@Schema(description = "旷工次数")
|
||||||
private Integer absenteeismNum;
|
private Integer absenteeismNum;
|
||||||
|
|
||||||
|
@ -19,4 +19,6 @@ public class TeamAttendanceStatisticsByDayVO {
|
|||||||
private Integer leaveEarlyNum;
|
private Integer leaveEarlyNum;
|
||||||
@Schema(description = "外勤数量")
|
@Schema(description = "外勤数量")
|
||||||
private Integer fieldworkNum;
|
private Integer fieldworkNum;
|
||||||
|
@Schema(description = "请假数量")
|
||||||
|
private Integer leaveNum;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public class AttendancePunchRecordDO extends BaseDO {
|
|||||||
private Integer level;
|
private Integer level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打卡状态 0正常 1迟到 2早退 3缺卡 4未打卡(还没到打卡时间) 5补卡
|
* 打卡状态 0正常 1迟到 2早退 3缺卡 4未打卡(还没到打卡时间) 5补卡 6请假
|
||||||
*/
|
*/
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
@ -91,9 +91,14 @@ public class AttendancePunchRecordDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private Integer fieldServiceFlag;
|
private Integer fieldServiceFlag;
|
||||||
/**
|
/**
|
||||||
* 日期yyyy-MM-dd格式
|
* 日期yyyy-MM-dd格式 (归属于哪一天)
|
||||||
*/
|
*/
|
||||||
private String dayTime;
|
private String dayTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期yyyy-MM-dd格式 (实际是哪一天)
|
||||||
|
*/
|
||||||
|
private String actualDayTime;
|
||||||
/**
|
/**
|
||||||
* 打卡时间
|
* 打卡时间
|
||||||
*/
|
*/
|
||||||
@ -140,6 +145,11 @@ public class AttendancePunchRecordDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private Integer remindFlag;
|
private Integer remindFlag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假单id
|
||||||
|
*/
|
||||||
|
private Long leaveId;
|
||||||
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private String deptName;
|
private String deptName;
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,10 @@ package cn.iocoder.yudao.module.system.dal.mysql.attendance.punchrecord;
|
|||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.system.api.attendance.dto.AttendancePunchRecordDTO;
|
||||||
|
import cn.iocoder.yudao.module.system.api.attendance.vo.AttendancePunchRecordVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordPageReqVO;
|
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.dal.dataobject.attendance.punchrecord.AttendancePunchRecordDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
|
||||||
import cn.iocoder.yudao.module.system.service.attendance.punch.dto.AttendanceOnTheDayDTO;
|
import cn.iocoder.yudao.module.system.service.attendance.punch.dto.AttendanceOnTheDayDTO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
@ -47,4 +48,4 @@ public interface AttendancePunchRecordMapper extends BaseMapperX<AttendancePunch
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<AttendancePunchRecordDO> statistics(@Param("userList") List<Long> userList, @Param("dateList") List<String> dateList);
|
List<AttendancePunchRecordDO> statistics(@Param("userList") List<Long> userList, @Param("dateList") List<String> dateList);
|
||||||
}
|
}
|
||||||
|
@ -446,7 +446,12 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
|
|
||||||
Map<String, List<AttendancePunchRecordDO>> collect = list.stream().collect(Collectors.groupingBy(AttendancePunchRecordDO::getDayTime));
|
Map<String, List<AttendancePunchRecordDO>> collect = list.stream().collect(Collectors.groupingBy(AttendancePunchRecordDO::getDayTime));
|
||||||
|
|
||||||
List<Integer> statusList = Arrays.asList(AttendanceOnTheDayDTO.PUNCH_STATUS_LATE, AttendanceOnTheDayDTO.PUNCH_STATUS_LEAVE_EARLY, AttendanceOnTheDayDTO.PUNCH_STATUS_MISS);
|
List<Integer> statusList = Arrays.asList(AttendanceOnTheDayDTO.PUNCH_STATUS_LATE,
|
||||||
|
AttendanceOnTheDayDTO.PUNCH_STATUS_LEAVE_EARLY,
|
||||||
|
AttendanceOnTheDayDTO.PUNCH_STATUS_MISS,
|
||||||
|
AttendanceOnTheDayDTO.REPLACEMENT_CARD,
|
||||||
|
AttendanceOnTheDayDTO.ASK_FOR_LEAVE
|
||||||
|
);
|
||||||
for (Map.Entry<String, List<AttendancePunchRecordDO>> entry : collect.entrySet()) {
|
for (Map.Entry<String, List<AttendancePunchRecordDO>> entry : collect.entrySet()) {
|
||||||
AttendanceStatusByDayVO attendanceStatusByDayVO = new AttendanceStatusByDayVO();
|
AttendanceStatusByDayVO attendanceStatusByDayVO = new AttendanceStatusByDayVO();
|
||||||
int status = 0;
|
int status = 0;
|
||||||
@ -504,6 +509,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
List<AttendancePunchStatisticsVO> beLateNumber = new ArrayList<>();
|
List<AttendancePunchStatisticsVO> beLateNumber = new ArrayList<>();
|
||||||
List<AttendancePunchStatisticsVO> earlyDeparturesNumber = new ArrayList<>();
|
List<AttendancePunchStatisticsVO> earlyDeparturesNumber = new ArrayList<>();
|
||||||
List<AttendancePunchStatisticsVO> missingCardsNumber = new ArrayList<>();
|
List<AttendancePunchStatisticsVO> missingCardsNumber = new ArrayList<>();
|
||||||
|
List<AttendancePunchStatisticsVO> leaveNumber = new ArrayList<>();
|
||||||
List<AttendancePunchStatisticsVO> minerDays = new ArrayList<>();
|
List<AttendancePunchStatisticsVO> minerDays = new ArrayList<>();
|
||||||
List<AttendancePunchStatisticsVO> fieldServiceNumber = new ArrayList<>();
|
List<AttendancePunchStatisticsVO> fieldServiceNumber = new ArrayList<>();
|
||||||
CalculateNum calculateNum = new CalculateNum();
|
CalculateNum calculateNum = new CalculateNum();
|
||||||
@ -533,6 +539,10 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
List<AttendancePunchStatisticsVO> missingCardsList = this.calculateMissingCardsList(day, weekChinese, workMap, calculateNum);
|
List<AttendancePunchStatisticsVO> missingCardsList = this.calculateMissingCardsList(day, weekChinese, workMap, calculateNum);
|
||||||
missingCardsNumber.addAll(missingCardsList);
|
missingCardsNumber.addAll(missingCardsList);
|
||||||
|
|
||||||
|
// -- 请假计算
|
||||||
|
List<AttendancePunchStatisticsVO> leaveList = this.calculateLeaveList(day, weekChinese, workMap, calculateNum);
|
||||||
|
leaveNumber.addAll(leaveList);
|
||||||
|
|
||||||
// -- 旷工计算
|
// -- 旷工计算
|
||||||
AttendancePunchStatisticsVO miner = this.calculateMiner(day, weekChinese, entry.getValue(), calculateNum);
|
AttendancePunchStatisticsVO miner = this.calculateMiner(day, weekChinese, entry.getValue(), calculateNum);
|
||||||
if (miner != null) {
|
if (miner != null) {
|
||||||
@ -553,6 +563,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
vo.setBeLateNumber(beLateNumber);
|
vo.setBeLateNumber(beLateNumber);
|
||||||
vo.setEarlyDeparturesNumber(earlyDeparturesNumber);
|
vo.setEarlyDeparturesNumber(earlyDeparturesNumber);
|
||||||
vo.setMissingCardsNumber(missingCardsNumber);
|
vo.setMissingCardsNumber(missingCardsNumber);
|
||||||
|
vo.setLeaveNumber(leaveNumber);
|
||||||
vo.setMinerDays(minerDays);
|
vo.setMinerDays(minerDays);
|
||||||
vo.setFieldServiceNumber(fieldServiceNumber);
|
vo.setFieldServiceNumber(fieldServiceNumber);
|
||||||
vo.setRestDays(restDays);
|
vo.setRestDays(restDays);
|
||||||
@ -560,6 +571,80 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假计算
|
||||||
|
*
|
||||||
|
* @param workMap
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String calculateLeaveList(Map<Long, List<AttendancePunchRecordDO>> workMap) {
|
||||||
|
int todayLeaveNumber = 0;
|
||||||
|
for (Map.Entry<Long, List<AttendancePunchRecordDO>> workEntry : workMap.entrySet()) {
|
||||||
|
if (CollectionUtil.isNotEmpty(workEntry.getValue())) {
|
||||||
|
// -- 请假计算
|
||||||
|
List<AttendancePunchRecordDO> leaveList = workEntry.getValue().stream().filter(a -> AttendanceOnTheDayDTO.ASK_FOR_LEAVE.equals(a.getStatus())).collect(Collectors.toList());
|
||||||
|
if (CollectionUtil.isNotEmpty(leaveList)) {
|
||||||
|
todayLeaveNumber += leaveList.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return String.valueOf(todayLeaveNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假计算
|
||||||
|
*
|
||||||
|
* @param workMap
|
||||||
|
* @param calculateNum
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private void calculateLeaveList(Map<Long, List<AttendancePunchRecordDO>> workMap, CalculateNum calculateNum) {
|
||||||
|
int todayLeaveNumber = 0;
|
||||||
|
for (Map.Entry<Long, List<AttendancePunchRecordDO>> workEntry : workMap.entrySet()) {
|
||||||
|
if (CollectionUtil.isNotEmpty(workEntry.getValue())) {
|
||||||
|
// -- 请假计算
|
||||||
|
List<AttendancePunchRecordDO> leaveList = workEntry.getValue().stream().filter(a -> AttendanceOnTheDayDTO.ASK_FOR_LEAVE.equals(a.getStatus())).collect(Collectors.toList());
|
||||||
|
if (CollectionUtil.isNotEmpty(leaveList)) {
|
||||||
|
todayLeaveNumber += leaveList.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
calculateNum.setTotalLeaveNumber(calculateNum.getTotalLeaveNumber() + todayLeaveNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假计算
|
||||||
|
*
|
||||||
|
* @param day
|
||||||
|
* @param weekChinese
|
||||||
|
* @param workMap
|
||||||
|
* @param calculateNum
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<AttendancePunchStatisticsVO> calculateLeaveList(String day, String weekChinese, Map<Long, List<AttendancePunchRecordDO>> workMap, CalculateNum calculateNum) {
|
||||||
|
List<AttendancePunchStatisticsVO> list = new ArrayList<>();
|
||||||
|
int totalLeaveNumber = 0;
|
||||||
|
for (Map.Entry<Long, List<AttendancePunchRecordDO>> workEntry : workMap.entrySet()) {
|
||||||
|
if (CollectionUtil.isNotEmpty(workEntry.getValue())) {
|
||||||
|
// -- 缺卡计算
|
||||||
|
List<AttendancePunchRecordDO> missingCardsList = workEntry.getValue().stream().filter(a -> AttendanceOnTheDayDTO.ASK_FOR_LEAVE.equals(a.getStatus())).collect(Collectors.toList());
|
||||||
|
if (CollectionUtil.isNotEmpty(missingCardsList)) {
|
||||||
|
totalLeaveNumber += missingCardsList.size();
|
||||||
|
for (AttendancePunchRecordDO attendancePunchRecordDO : missingCardsList) {
|
||||||
|
AttendancePunchStatisticsVO earlyDepartures = new AttendancePunchStatisticsVO();
|
||||||
|
earlyDepartures.setDay(day);
|
||||||
|
earlyDepartures.setWeek(weekChinese);
|
||||||
|
earlyDepartures.setShouldPunchTime(attendancePunchRecordDO.getShouldPunchTime().format(DateTimeFormatter.ofPattern("HH:mm")));
|
||||||
|
list.add(earlyDepartures);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
calculateNum.setTotalLeaveNumber(calculateNum.getTotalLeaveNumber() + totalLeaveNumber);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, TeamAttendanceStatisticsByDayVO> teamStatisticsByDay(TeamAttendanceStatisticsByDayDTO dto) {
|
public Map<String, TeamAttendanceStatisticsByDayVO> teamStatisticsByDay(TeamAttendanceStatisticsByDayDTO dto) {
|
||||||
Map<String, TeamAttendanceStatisticsByDayVO> map = new HashMap<>();
|
Map<String, TeamAttendanceStatisticsByDayVO> map = new HashMap<>();
|
||||||
@ -587,6 +672,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
int lateNum = 0;
|
int lateNum = 0;
|
||||||
int leaveEarlyNum = 0;
|
int leaveEarlyNum = 0;
|
||||||
int fieldworkNum = 0;
|
int fieldworkNum = 0;
|
||||||
|
int leaveNum = 0;
|
||||||
for (AttendancePunchRecordDO attendancePunchRecordDO : entry.getValue()) {
|
for (AttendancePunchRecordDO attendancePunchRecordDO : entry.getValue()) {
|
||||||
if (AttendanceOnTheDayDTO.PUNCH_STATUS_MISS.equals(attendancePunchRecordDO.getStatus())) {
|
if (AttendanceOnTheDayDTO.PUNCH_STATUS_MISS.equals(attendancePunchRecordDO.getStatus())) {
|
||||||
punchStatusMissNum++;
|
punchStatusMissNum++;
|
||||||
@ -600,6 +686,9 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
if (Constants.TRUE.equals(attendancePunchRecordDO.getFieldServiceFlag())) {
|
if (Constants.TRUE.equals(attendancePunchRecordDO.getFieldServiceFlag())) {
|
||||||
fieldworkNum++;
|
fieldworkNum++;
|
||||||
}
|
}
|
||||||
|
if (AttendanceOnTheDayDTO.ASK_FOR_LEAVE.equals(attendancePunchRecordDO.getStatus())) {
|
||||||
|
leaveNum++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TeamAttendanceStatisticsByDayVO vo = new TeamAttendanceStatisticsByDayVO();
|
TeamAttendanceStatisticsByDayVO vo = new TeamAttendanceStatisticsByDayVO();
|
||||||
vo.setAnswerNum(userMap.keySet().size());
|
vo.setAnswerNum(userMap.keySet().size());
|
||||||
@ -608,6 +697,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
vo.setLateNum(lateNum);
|
vo.setLateNum(lateNum);
|
||||||
vo.setLeaveEarlyNum(leaveEarlyNum);
|
vo.setLeaveEarlyNum(leaveEarlyNum);
|
||||||
vo.setFieldworkNum(fieldworkNum);
|
vo.setFieldworkNum(fieldworkNum);
|
||||||
|
vo.setLeaveNum(leaveNum);
|
||||||
map.put(entry.getKey(), vo);
|
map.put(entry.getKey(), vo);
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
@ -661,6 +751,8 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
List<TeamAttendancePunchStatisticsVO> absenteeismList = new ArrayList<>();
|
List<TeamAttendancePunchStatisticsVO> absenteeismList = new ArrayList<>();
|
||||||
//外勤
|
//外勤
|
||||||
List<TeamAttendancePunchStatisticsVO> fieldServiceList = new ArrayList<>();
|
List<TeamAttendancePunchStatisticsVO> fieldServiceList = new ArrayList<>();
|
||||||
|
//请假
|
||||||
|
List<TeamAttendancePunchStatisticsVO> leaveList = new ArrayList<>();
|
||||||
|
|
||||||
Map<Long, List<AttendancePunchRecordDO>> userPunchMap = list.stream().collect(Collectors.groupingBy(AttendancePunchRecordDO::getUserId));
|
Map<Long, List<AttendancePunchRecordDO>> userPunchMap = list.stream().collect(Collectors.groupingBy(AttendancePunchRecordDO::getUserId));
|
||||||
// -- 根据用户分组
|
// -- 根据用户分组
|
||||||
@ -690,6 +782,8 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
this.calculateEarlyDepartures(workMap, calculateNum);
|
this.calculateEarlyDepartures(workMap, calculateNum);
|
||||||
// -- 缺卡
|
// -- 缺卡
|
||||||
this.calculateMissingCardsList(workMap, calculateNum);
|
this.calculateMissingCardsList(workMap, calculateNum);
|
||||||
|
// -- 请假
|
||||||
|
this.calculateLeaveList(workMap, calculateNum);
|
||||||
// -- 旷工
|
// -- 旷工
|
||||||
this.calculateMiner(dayEntry.getValue(), calculateNum);
|
this.calculateMiner(dayEntry.getValue(), calculateNum);
|
||||||
// -- 外勤
|
// -- 外勤
|
||||||
@ -733,6 +827,14 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
BeanUtil.copyProperties(averageWorkingHourVO, item);
|
BeanUtil.copyProperties(averageWorkingHourVO, item);
|
||||||
fieldServiceList.add(item.setTop(calculateNum.getTotalFieldServiceNumber() + "次").setDown(""));
|
fieldServiceList.add(item.setTop(calculateNum.getTotalFieldServiceNumber() + "次").setDown(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- 请假漏卡
|
||||||
|
if (calculateNum.getTotalLeaveNumber() > 0) {
|
||||||
|
TeamAttendancePunchStatisticsVO item = new TeamAttendancePunchStatisticsVO();
|
||||||
|
BeanUtil.copyProperties(averageWorkingHourVO, item);
|
||||||
|
leaveList.add(item.setTop(calculateNum.getTotalLeaveNumber() + "次请假漏卡").setDown(""));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vo.setAverageWorkingHoursList(averageWorkingHours);
|
vo.setAverageWorkingHoursList(averageWorkingHours);
|
||||||
@ -741,6 +843,8 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
vo.setMissingCardList(missingCardList);
|
vo.setMissingCardList(missingCardList);
|
||||||
vo.setAbsenteeismList(absenteeismList);
|
vo.setAbsenteeismList(absenteeismList);
|
||||||
vo.setFieldServiceList(fieldServiceList);
|
vo.setFieldServiceList(fieldServiceList);
|
||||||
|
vo.setLeaveList(leaveList);
|
||||||
|
|
||||||
int sum = averageWorkingHours.stream().mapToInt(a -> a.getCalculateNum().getTotalAttendanceDays()).sum();
|
int sum = averageWorkingHours.stream().mapToInt(a -> a.getCalculateNum().getTotalAttendanceDays()).sum();
|
||||||
TeamAttendanceStatisticsByCycleVO.TeamAttendanceStatisticsNumVO teamAttendanceStatisticsByCycleVO = new TeamAttendanceStatisticsByCycleVO.TeamAttendanceStatisticsNumVO();
|
TeamAttendanceStatisticsByCycleVO.TeamAttendanceStatisticsNumVO teamAttendanceStatisticsByCycleVO = new TeamAttendanceStatisticsByCycleVO.TeamAttendanceStatisticsNumVO();
|
||||||
teamAttendanceStatisticsByCycleVO.setAverageWorkingHours(
|
teamAttendanceStatisticsByCycleVO.setAverageWorkingHours(
|
||||||
@ -750,6 +854,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
.setBeLateNum(beLateList.stream().mapToInt(a -> a.getCalculateNum().getTotalLateArrivalsNumber()).sum())
|
.setBeLateNum(beLateList.stream().mapToInt(a -> a.getCalculateNum().getTotalLateArrivalsNumber()).sum())
|
||||||
.setLeaveEarlyNum(leaveEarlyList.stream().mapToInt(a -> a.getCalculateNum().getTotalEarlyDeparturesNumber()).sum())
|
.setLeaveEarlyNum(leaveEarlyList.stream().mapToInt(a -> a.getCalculateNum().getTotalEarlyDeparturesNumber()).sum())
|
||||||
.setMissingCardNum(missingCardList.stream().mapToInt(a -> a.getCalculateNum().getTotalMissingCardsNumber()).sum())
|
.setMissingCardNum(missingCardList.stream().mapToInt(a -> a.getCalculateNum().getTotalMissingCardsNumber()).sum())
|
||||||
|
.setLeaveNum(leaveList.stream().mapToInt(a -> a.getCalculateNum().getTotalLeaveNumber()).sum())
|
||||||
.setAbsenteeismNum(absenteeismList.stream().mapToInt(a -> a.getCalculateNum().getTotalMinerDays()).sum())
|
.setAbsenteeismNum(absenteeismList.stream().mapToInt(a -> a.getCalculateNum().getTotalMinerDays()).sum())
|
||||||
.setFieldServiceNum(fieldServiceList.stream().mapToInt(a -> a.getCalculateNum().getTotalFieldServiceNumber()).sum())
|
.setFieldServiceNum(fieldServiceList.stream().mapToInt(a -> a.getCalculateNum().getTotalFieldServiceNumber()).sum())
|
||||||
);
|
);
|
||||||
@ -913,6 +1018,10 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
//早退时长
|
//早退时长
|
||||||
String leaveEarly = this.calculateEarlyDepartures(workMap);
|
String leaveEarly = this.calculateEarlyDepartures(workMap);
|
||||||
row.add(leaveEarly);
|
row.add(leaveEarly);
|
||||||
|
//请假漏卡次数
|
||||||
|
String leaveList = this.calculateLeaveList(workMap);
|
||||||
|
row.add(leaveList);
|
||||||
|
|
||||||
Map<Integer, Integer> missingCardsMap = this.calculateCommuteMissingCardsList(workMap);
|
Map<Integer, Integer> missingCardsMap = this.calculateCommuteMissingCardsList(workMap);
|
||||||
row.add(missingCardsMap.get(Constants.ZERO).toString());
|
row.add(missingCardsMap.get(Constants.ZERO).toString());
|
||||||
row.add(missingCardsMap.get(Constants.ONE).toString());
|
row.add(missingCardsMap.get(Constants.ONE).toString());
|
||||||
@ -926,7 +1035,8 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
|
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
|
||||||
|
|
||||||
try {
|
try {
|
||||||
EasyExcel.write(response.getOutputStream())
|
// EasyExcel.write(response.getOutputStream())
|
||||||
|
EasyExcel.write("/Users/aikai/Downloads/" + System.currentTimeMillis() + "考勤统计按日导出.xls")
|
||||||
.head(generateDailyHead(headTitle, detailedHead, maxSize))
|
.head(generateDailyHead(headTitle, detailedHead, maxSize))
|
||||||
.autoCloseStream(false)
|
.autoCloseStream(false)
|
||||||
.excelType(ExcelTypeEnum.XLS)
|
.excelType(ExcelTypeEnum.XLS)
|
||||||
@ -934,7 +1044,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
.sheet("考勤统计按日导出")
|
.sheet("考勤统计按日导出")
|
||||||
.doWrite(data);
|
.doWrite(data);
|
||||||
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("考勤统计", StandardCharsets.UTF_8.name()));
|
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("考勤统计", StandardCharsets.UTF_8.name()));
|
||||||
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
// response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@ -980,6 +1090,8 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
return "未打卡";
|
return "未打卡";
|
||||||
} else if (status == 5) {
|
} else if (status == 5) {
|
||||||
return "补卡";
|
return "补卡";
|
||||||
|
} else if (status == 6) {
|
||||||
|
return "请假";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -1035,6 +1147,8 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
this.calculateCommuteMissingCardsList(workMap, calculateNum);
|
this.calculateCommuteMissingCardsList(workMap, calculateNum);
|
||||||
// -- 旷工
|
// -- 旷工
|
||||||
this.calculateMiner(dayEntry.getValue(), calculateNum);
|
this.calculateMiner(dayEntry.getValue(), calculateNum);
|
||||||
|
// -- 请假
|
||||||
|
this.calculateLeaveList(workMap, calculateNum);
|
||||||
}
|
}
|
||||||
//休息天数
|
//休息天数
|
||||||
this.calculateRestDay(dateList, dayMap.keySet().stream().distinct().collect(Collectors.toList()), calculateNum);
|
this.calculateRestDay(dateList, dayMap.keySet().stream().distinct().collect(Collectors.toList()), calculateNum);
|
||||||
@ -1058,6 +1172,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
|
|
||||||
row.add(String.valueOf(calculateNum.getTotalEarlyDeparturesNumber()));
|
row.add(String.valueOf(calculateNum.getTotalEarlyDeparturesNumber()));
|
||||||
row.add(String.valueOf(calculateNum.getTotalEarlyDeparturesTimeStr()));
|
row.add(String.valueOf(calculateNum.getTotalEarlyDeparturesTimeStr()));
|
||||||
|
row.add(String.valueOf(calculateNum.getTotalLeaveNumber()));
|
||||||
row.add(String.valueOf(calculateNum.getTotalUpMissingCardsNumber()));
|
row.add(String.valueOf(calculateNum.getTotalUpMissingCardsNumber()));
|
||||||
row.add(String.valueOf(calculateNum.getTotalDownMissingCardsNumber()));
|
row.add(String.valueOf(calculateNum.getTotalDownMissingCardsNumber()));
|
||||||
row.add(String.valueOf(calculateNum.getTotalMinerDays()));
|
row.add(String.valueOf(calculateNum.getTotalMinerDays()));
|
||||||
@ -1067,7 +1182,8 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
EasyExcel.write(response.getOutputStream())
|
// EasyExcel.write(response.getOutputStream())
|
||||||
|
EasyExcel.write("/Users/aikai/Downloads/" + System.currentTimeMillis() + "考勤统计按日导出.xls")
|
||||||
.head(generateHead(headTitle, detailedHead))
|
.head(generateHead(headTitle, detailedHead))
|
||||||
.autoCloseStream(false)
|
.autoCloseStream(false)
|
||||||
.excelType(ExcelTypeEnum.XLS)
|
.excelType(ExcelTypeEnum.XLS)
|
||||||
@ -1075,7 +1191,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
.sheet("考勤统计按月导出")
|
.sheet("考勤统计按月导出")
|
||||||
.doWrite(data);
|
.doWrite(data);
|
||||||
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("考勤统计", StandardCharsets.UTF_8.name()));
|
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("考勤统计", StandardCharsets.UTF_8.name()));
|
||||||
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
// response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@ -1096,6 +1212,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
head.add(Arrays.asList(headTitle, detailedHead, "迟到时长", "迟到时长"));
|
head.add(Arrays.asList(headTitle, detailedHead, "迟到时长", "迟到时长"));
|
||||||
head.add(Arrays.asList(headTitle, detailedHead, "早退次数", "早退次数"));
|
head.add(Arrays.asList(headTitle, detailedHead, "早退次数", "早退次数"));
|
||||||
head.add(Arrays.asList(headTitle, detailedHead, "早退时长", "早退时长"));
|
head.add(Arrays.asList(headTitle, detailedHead, "早退时长", "早退时长"));
|
||||||
|
head.add(Arrays.asList(headTitle, detailedHead, "请假漏卡次数", "请假漏卡次数"));
|
||||||
head.add(Arrays.asList(headTitle, detailedHead, "上班缺卡次数", "上班缺卡次数"));
|
head.add(Arrays.asList(headTitle, detailedHead, "上班缺卡次数", "上班缺卡次数"));
|
||||||
head.add(Arrays.asList(headTitle, detailedHead, "下班缺卡次数", "下班缺卡次数"));
|
head.add(Arrays.asList(headTitle, detailedHead, "下班缺卡次数", "下班缺卡次数"));
|
||||||
head.add(Arrays.asList(headTitle, detailedHead, "旷工天数", "旷工天数"));
|
head.add(Arrays.asList(headTitle, detailedHead, "旷工天数", "旷工天数"));
|
||||||
@ -1140,6 +1257,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
head.add(Arrays.asList(headTitle, detailedHead, "迟到时长", "迟到时长"));
|
head.add(Arrays.asList(headTitle, detailedHead, "迟到时长", "迟到时长"));
|
||||||
// head.add(Arrays.asList(headTitle, detailedHead, "早退次数", "早退次数"));
|
// head.add(Arrays.asList(headTitle, detailedHead, "早退次数", "早退次数"));
|
||||||
head.add(Arrays.asList(headTitle, detailedHead, "早退时长", "早退时长"));
|
head.add(Arrays.asList(headTitle, detailedHead, "早退时长", "早退时长"));
|
||||||
|
head.add(Arrays.asList(headTitle, detailedHead, "请假漏卡次数", "请假漏卡次数"));
|
||||||
head.add(Arrays.asList(headTitle, detailedHead, "上班缺卡次数", "上班缺卡次数"));
|
head.add(Arrays.asList(headTitle, detailedHead, "上班缺卡次数", "上班缺卡次数"));
|
||||||
head.add(Arrays.asList(headTitle, detailedHead, "下班缺卡次数", "下班缺卡次数"));
|
head.add(Arrays.asList(headTitle, detailedHead, "下班缺卡次数", "下班缺卡次数"));
|
||||||
// head.add(Arrays.asList(headTitle, detailedHead, "旷工天数", "旷工天数"));
|
// head.add(Arrays.asList(headTitle, detailedHead, "旷工天数", "旷工天数"));
|
||||||
@ -1319,7 +1437,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 迟到次数
|
* 缺卡次数 - 上下班区分开
|
||||||
*
|
*
|
||||||
* @param workMap
|
* @param workMap
|
||||||
*/
|
*/
|
||||||
|
@ -9,13 +9,15 @@ import java.time.LocalDateTime;
|
|||||||
public class AttendanceOnTheDayDTO {
|
public class AttendanceOnTheDayDTO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打卡状态 0正常 1迟到 2早退 3缺卡 4未打卡(还没到打卡时间)
|
* 打卡状态 0正常 1迟到 2早退 3缺卡 4未打卡(还没到打卡时间) 5补卡 6请假
|
||||||
*/
|
*/
|
||||||
public static final Integer PUNCH_STATUS_NORMAL = 0;
|
public static final Integer PUNCH_STATUS_NORMAL = 0;
|
||||||
public static final Integer PUNCH_STATUS_LATE = 1;
|
public static final Integer PUNCH_STATUS_LATE = 1;
|
||||||
public static final Integer PUNCH_STATUS_LEAVE_EARLY = 2;
|
public static final Integer PUNCH_STATUS_LEAVE_EARLY = 2;
|
||||||
public static final Integer PUNCH_STATUS_MISS = 3;
|
public static final Integer PUNCH_STATUS_MISS = 3;
|
||||||
public static final Integer PUNCH_STATUS_UN_PUNCH = 4;
|
public static final Integer PUNCH_STATUS_UN_PUNCH = 4;
|
||||||
|
public static final Integer REPLACEMENT_CARD = 5;
|
||||||
|
public static final Integer ASK_FOR_LEAVE = 6;
|
||||||
|
|
||||||
@Schema(description = "子表id")
|
@Schema(description = "子表id")
|
||||||
private Long id;
|
private Long id;
|
||||||
@ -44,7 +46,7 @@ public class AttendanceOnTheDayDTO {
|
|||||||
@Schema(description = "后打卡时间(分钟) 默认 120分钟")
|
@Schema(description = "后打卡时间(分钟) 默认 120分钟")
|
||||||
private Integer afterPunchTime;
|
private Integer afterPunchTime;
|
||||||
|
|
||||||
@Schema(description = "打卡状态 0正常 1迟到 2早退 3缺卡 4未打卡(还没到打卡时间)")
|
@Schema(description = "打卡状态 0正常 1迟到 2早退 3缺卡 4未打卡(还没到打卡时间) 5补卡 6请假")
|
||||||
private Integer punchStatus;
|
private Integer punchStatus;
|
||||||
|
|
||||||
@Schema(description = "是否外勤 0否 1是", example = "1")
|
@Schema(description = "是否外勤 0否 1是", example = "1")
|
||||||
@ -75,4 +77,4 @@ public class AttendanceOnTheDayDTO {
|
|||||||
@Schema(description = "早退时长时间戳")
|
@Schema(description = "早退时长时间戳")
|
||||||
private Long leaveEarlyTime;
|
private Long leaveEarlyTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.system.service.attendance.punchrecord;
|
package cn.iocoder.yudao.module.system.service.attendance.punchrecord;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.system.api.attendance.dto.AttendancePunchRecordDTO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordPageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordPageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordSaveReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO;
|
||||||
@ -112,4 +113,11 @@ public interface AttendancePunchRecordService {
|
|||||||
* @param editList
|
* @param editList
|
||||||
*/
|
*/
|
||||||
void batchUpdate(List<AttendancePunchRecordDO> editList);
|
void batchUpdate(List<AttendancePunchRecordDO> editList);
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 请假修改状态
|
||||||
|
*
|
||||||
|
* @param dto
|
||||||
|
*/
|
||||||
|
void askingForLeaveAfterwardsToModifyAttendance(AttendancePunchRecordDTO dto);
|
||||||
|
}
|
||||||
|
@ -6,9 +6,11 @@ import cn.hutool.core.map.MapUtil;
|
|||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import cn.iocoder.yudao.framework.common.Constants;
|
import cn.iocoder.yudao.framework.common.Constants;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.BpmOALeaveDTO;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.module.system.api.attendance.dto.AttendancePunchRecordDTO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordPageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordPageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordSaveReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.punchrecord.vo.AttendancePunchRecordSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO;
|
||||||
@ -26,7 +28,9 @@ import cn.iocoder.yudao.module.system.service.attendance.punch.dto.AttendanceOnT
|
|||||||
import cn.iocoder.yudao.module.system.service.attendance.scheduling.AttendanceSchedulingService;
|
import cn.iocoder.yudao.module.system.service.attendance.scheduling.AttendanceSchedulingService;
|
||||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.data.redis.core.HashOperations;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -206,7 +210,7 @@ public class AttendancePunchRecordServiceImpl implements AttendancePunchRecordSe
|
|||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
Map<String, String[]> delLeaveMap = new HashMap<>();
|
||||||
for (Map.Entry<Long, Long> entry : map.entrySet()) {
|
for (Map.Entry<Long, Long> entry : map.entrySet()) {
|
||||||
String key = Constants.ATTENDANCE + Constants.UNDERLINE + entry.getKey() + Constants.UNDERLINE; // + 时间
|
String key = Constants.ATTENDANCE + Constants.UNDERLINE + entry.getKey() + Constants.UNDERLINE; // + 时间
|
||||||
AttendanceGroupDO attendanceGroupDO = groupMap.get(entry.getKey());
|
AttendanceGroupDO attendanceGroupDO = groupMap.get(entry.getKey());
|
||||||
@ -221,7 +225,9 @@ public class AttendancePunchRecordServiceImpl implements AttendancePunchRecordSe
|
|||||||
List<AttendanceOnTheDayDTO> attendanceOnTheDayDTOS = attendanceService.buildAttendanceOnTheDay(attendanceGroupShiftItemDOS);
|
List<AttendanceOnTheDayDTO> attendanceOnTheDayDTOS = attendanceService.buildAttendanceOnTheDay(attendanceGroupShiftItemDOS);
|
||||||
for (Long userId : userIds) {
|
for (Long userId : userIds) {
|
||||||
AdminUserDO adminUserDO = userMap.get(userId);
|
AdminUserDO adminUserDO = userMap.get(userId);
|
||||||
|
Map<Object, Object> leaveRedisMap = this.getAttendanceLeaveRedisMap(userId);
|
||||||
Long deptId = adminUserDO == null ? null : adminUserDO.getDeptId();
|
Long deptId = adminUserDO == null ? null : adminUserDO.getDeptId();
|
||||||
|
List<String> leaveIds = new ArrayList<>();
|
||||||
for (AttendanceOnTheDayDTO attendanceOnTheDayDTO : attendanceOnTheDayDTOS) {
|
for (AttendanceOnTheDayDTO attendanceOnTheDayDTO : attendanceOnTheDayDTOS) {
|
||||||
AttendancePunchRecordDO attendancePunchRecordDO = new AttendancePunchRecordDO();
|
AttendancePunchRecordDO attendancePunchRecordDO = new AttendancePunchRecordDO();
|
||||||
attendancePunchRecordDO.setUserId(userId);
|
attendancePunchRecordDO.setUserId(userId);
|
||||||
@ -239,21 +245,67 @@ public class AttendancePunchRecordServiceImpl implements AttendancePunchRecordSe
|
|||||||
attendancePunchRecordDO.setFieldServiceFlag(Constants.FALSE);
|
attendancePunchRecordDO.setFieldServiceFlag(Constants.FALSE);
|
||||||
attendancePunchRecordDO.setNextDayFlag(Constants.TRUE);
|
attendancePunchRecordDO.setNextDayFlag(Constants.TRUE);
|
||||||
attendancePunchRecordDO.setDayTime(time);
|
attendancePunchRecordDO.setDayTime(time);
|
||||||
|
|
||||||
LocalDateTime shouldPunchTime = LocalDateTime.ofInstant(DateUtils.buildHHmmTime(attendanceOnTheDayDTO.getTime(),
|
LocalDateTime shouldPunchTime = LocalDateTime.ofInstant(DateUtils.buildHHmmTime(attendanceOnTheDayDTO.getTime(),
|
||||||
(attendanceOnTheDayDTO.getNextDayFlag() == 0 ? localDateTime : nextDayLocalDateTime)).toInstant(), ZoneId.systemDefault());
|
(attendanceOnTheDayDTO.getNextDayFlag() == 0 ? localDateTime : nextDayLocalDateTime)).toInstant(), ZoneId.systemDefault());
|
||||||
|
// -- 请假插入预设
|
||||||
|
for (Map.Entry<Object, Object> leaveEntry : leaveRedisMap.entrySet()) {
|
||||||
|
BpmOALeaveDTO dto = JSONUtil.toBean(leaveEntry.getValue().toString(), BpmOALeaveDTO.class);
|
||||||
|
// - 如果在这个区间之内 - 那么就是需要设为请假的
|
||||||
|
if ((dto.getStartTime().isBefore(shouldPunchTime) || dto.getStartTime().equals(shouldPunchTime)) &&
|
||||||
|
(dto.getEndTime().isAfter(shouldPunchTime) || dto.getEndTime().equals(shouldPunchTime))) {
|
||||||
|
attendancePunchRecordDO.setStatus(AttendanceOnTheDayDTO.ASK_FOR_LEAVE);
|
||||||
|
attendancePunchRecordDO.setLeaveId(dto.getId());
|
||||||
|
} else if (dto.getEndTime().isBefore(shouldPunchTime)) {
|
||||||
|
leaveIds.add(dto.getId().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String actualDayTime = shouldPunchTime.format(Constants.REPO_DATE_FORMAT);
|
||||||
|
attendancePunchRecordDO.setActualDayTime(actualDayTime);
|
||||||
attendancePunchRecordDO.setShouldPunchTime(shouldPunchTime);
|
attendancePunchRecordDO.setShouldPunchTime(shouldPunchTime);
|
||||||
attendancePunchRecordDO.setLatestPunchTime(shouldPunchTime.plusMinutes(attendanceOnTheDayDTO.getAfterPunchTime()));
|
attendancePunchRecordDO.setLatestPunchTime(shouldPunchTime.plusMinutes(attendanceOnTheDayDTO.getAfterPunchTime()));
|
||||||
attendancePunchRecordDOList.add(attendancePunchRecordDO);
|
attendancePunchRecordDOList.add(attendancePunchRecordDO);
|
||||||
}
|
}
|
||||||
stringRedisTemplate.opsForHash().put(key + time, userId.toString(), JSONUtil.toJsonStr(attendanceOnTheDayDTOS));
|
stringRedisTemplate.opsForHash().put(key + time, userId.toString(), JSONUtil.toJsonStr(attendanceOnTheDayDTOS));
|
||||||
|
if (!leaveIds.isEmpty()) {
|
||||||
|
delLeaveMap.put("leave" + "_" + userId, leaveIds.toArray(new String[0]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//设置缓存 2天
|
//设置缓存 2天
|
||||||
stringRedisTemplate.expire(key + time, 2, TimeUnit.DAYS);
|
stringRedisTemplate.expire(key + time, 2, TimeUnit.DAYS);
|
||||||
}
|
}
|
||||||
|
// -- 删除redis中的请假数据
|
||||||
|
this.delLeave(delLeaveMap);
|
||||||
// -- 批量
|
// -- 批量
|
||||||
this.saveBatch(attendancePunchRecordDOList);
|
this.saveBatch(attendancePunchRecordDOList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除redis中的请假数据
|
||||||
|
*
|
||||||
|
* @param delLeaveMap
|
||||||
|
*/
|
||||||
|
private void delLeave(Map<String, String[]> delLeaveMap) {
|
||||||
|
if (MapUtil.isNotEmpty(delLeaveMap)) {
|
||||||
|
for (Map.Entry<String, String[]> entry : delLeaveMap.entrySet()) {
|
||||||
|
stringRedisTemplate.opsForHash().delete(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户请假redisMap
|
||||||
|
*
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Map<Object, Object> getAttendanceLeaveRedisMap(Long userId) {
|
||||||
|
HashOperations<String, Object, Object> hashOps = stringRedisTemplate.opsForHash();
|
||||||
|
String key = "leave" + "_" + userId.toString();
|
||||||
|
return hashOps.entries(key);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AttendancePunchRecordDO> getNotReminded(LocalDateTime localDateTime) {
|
public List<AttendancePunchRecordDO> getNotReminded(LocalDateTime localDateTime) {
|
||||||
String targetDayStr = localDateTime.format(Constants.REPO_DATE_FORMAT);
|
String targetDayStr = localDateTime.format(Constants.REPO_DATE_FORMAT);
|
||||||
@ -268,6 +320,17 @@ public class AttendancePunchRecordServiceImpl implements AttendancePunchRecordSe
|
|||||||
punchRecordMapper.updateBatch(editList);
|
punchRecordMapper.updateBatch(editList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void askingForLeaveAfterwardsToModifyAttendance(AttendancePunchRecordDTO dto) {
|
||||||
|
punchRecordMapper.update(new AttendancePunchRecordDO()
|
||||||
|
.setStatus(AttendanceOnTheDayDTO.ASK_FOR_LEAVE)
|
||||||
|
.setLeaveId(dto.getLeaveId()),
|
||||||
|
new LambdaUpdateWrapper<AttendancePunchRecordDO>().eq(AttendancePunchRecordDO::getUserId, dto.getUserId())
|
||||||
|
.ge(AttendancePunchRecordDO::getShouldPunchTime, dto.getStartTime())
|
||||||
|
.le(AttendancePunchRecordDO::getShouldPunchTime, dto.getEndTime()));
|
||||||
|
}
|
||||||
|
|
||||||
private Map<Long, Long> getAttendanceGroupShiftIdGroupByGroup(List<AttendanceGroupDO> attendanceGroupDOS, LocalDateTime localDateTime) {
|
private Map<Long, Long> getAttendanceGroupShiftIdGroupByGroup(List<AttendanceGroupDO> attendanceGroupDOS, LocalDateTime localDateTime) {
|
||||||
Map<Long, Long> map = new HashMap<>();
|
Map<Long, Long> map = new HashMap<>();
|
||||||
List<AttendanceGroupDO> fixedList = attendanceGroupDOS.stream().filter(a -> a.getType().equals(1)).collect(Collectors.toList());
|
List<AttendanceGroupDO> fixedList = attendanceGroupDOS.stream().filter(a -> a.getType().equals(1)).collect(Collectors.toList());
|
||||||
@ -287,4 +350,4 @@ public class AttendancePunchRecordServiceImpl implements AttendancePunchRecordSe
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,4 +32,4 @@
|
|||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
Loading…
Reference in New Issue
Block a user