数据推送跨月历史数据推送问题修改

工作异常添加
This commit is contained in:
fl 2024-12-11 17:28:21 +08:00
parent c323536e2d
commit 7714717268
7 changed files with 207 additions and 80 deletions

View File

@ -143,4 +143,17 @@ public interface AttSourceDataDao {
List<AttSourceDataBean> getSourceAttNoInOutData();
void delHisData(String date);
/**
* 查询人员固定时间请假消息
* @param attSourceDataBean
* @return
*/
int getLeaveDataByUserId(AttSourceDataBean attSourceDataBean);
/**
* 插入工作异常
* @param longBreakRecords
*/
void insertWorkAbnormal(List<AttSourceDataBean> longBreakRecords);
}

View File

@ -39,6 +39,16 @@ public class AttGroupBean {
*/
private String offWorkTime;
/**
* 休息开始时间
*/
private String breakStartTime;
/**
* 休息结束时间
*/
private String breakEndTime;
/**
* 每天打卡
*/
@ -69,6 +79,11 @@ public class AttGroupBean {
*/
private Long absenteeismLeaveMinute;
/**
* 工作异常时长分钟
*/
private Long workAbnormalMinute;
/**
* 应出勤时长
*/

View File

@ -60,7 +60,7 @@ public class AttTasks {
private volatile boolean executed = false; // 标志位表示任务是否已经执行过
// @Scheduled(cron = "0 0/10 * * * ?")
@Scheduled(initialDelay = 60000 * 5,fixedDelay = 60000 * 10)
// @Scheduled(initialDelay = 60000 * 5, fixedDelay = 60000 * 10)
@Async
public void getAttTasks() {
log.info("--------考勤定时器开启------");
@ -72,7 +72,7 @@ public class AttTasks {
/**
* 历史考勤数据
*/
// @Scheduled(fixedDelay = 60000 * 30)
@Scheduled(fixedDelay = 60000 * 30)
@Async
public void getHisAttTasks() {
log.info("--------考勤定时器开启------");
@ -80,8 +80,8 @@ public class AttTasks {
return; // 如果任务已经执行过直接返回
}
executed = true; // 设置标志位表示任务已经执行过
String startDate = "2024-11-20";
String endDate = "2024-11-21";
String startDate = "2024-11-01";
String endDate = "2024-11-05";
List<String> dateList = getStrDateListBetween(startDate, endDate);
// 创建固定大小的线程池
ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
@ -343,7 +343,7 @@ public class AttTasks {
groupList.forEach(c -> {
//应考勤天
List<String> attDayList = WorkdayCalculator.getWorkDay(c.getAttDay(),
Integer.parseInt(c.getAttType()), holidays);
Integer.parseInt(c.getAttType()), holidays,pushDate);
c.setAttWorkDayBean(new PersonAttWorkDayBean(c.getGroupId(), attDayList.size(), attDayList));
});
return groupList;
@ -603,34 +603,10 @@ public class AttTasks {
list.add(backOffWorkBean);
}
}
// if (nextOffWork != null) {
// if (StringUtils.isNotEmpty(nextOffWork.getAttCurrentTime())) {
// list.add(nextOffWork);
// }
// }
});
return list;
}
public AttSourceDataBean getNextOffWorkDate(List<AttSourceDataBean> v) {
AttSourceDataBean nextOffWork = v.stream()
.filter(a -> {
String time = a.getAttCurrentTime();
String startTime = DateUtils.getYyyyMmDd(a.getAttCurrentTime()) + " 00:00:00";
String endTime = DateUtils.getYyyyMmDd(a.getAttCurrentTime()) + " 04:59:59";
return DateUtils.getTimeIsRange(time, startTime, endTime);
})
.collect(Collectors.toList())
.stream().max(Comparator.comparing(AttSourceDataBean::getAttCurrentTime)).orElse(null);
if (nextOffWork != null) {
if (StringUtils.isNotEmpty(nextOffWork.getAttCurrentTime())) {
nextOffWork.setAttType("2");
nextOffWork.setAttCurrentDay(DateUtils.getAfterDate(nextOffWork.getAttCurrentDay()));
return nextOffWork;
}
}
return null;
}
/**
* 固定考勤数据计算
@ -703,11 +679,11 @@ public class AttTasks {
//最新一次下班时间插入list
newList.add(backOffWorkBean);
}
if(v.get(0).getName().equals("肖阳")){
System.out.println("c.getAttCurrentTime() = ");
}
// if(v.get(0).getName().equals("肖阳")){
// System.out.println("c.getAttCurrentTime() = ");
// }
// 处理逻辑 出入异常的逻辑
Map<Boolean, List<AttSourceDataBean>> result = checkAdjacentAttType1WithGapAndCheckTypesBefore(v,attGroupBean.getEntryAbnormalMinute());
Map<Boolean, List<AttSourceDataBean>> result = checkAdjacentAttType1WithGapAndCheckTypesBefore(v, attGroupBean.getEntryAbnormalMinute());
if (result.containsKey(true)) {
List<AttSourceDataBean> matchingItems = result.get(true);
frontToWorkBean = matchingItems.get(0);
@ -717,15 +693,102 @@ public class AttTasks {
}
//没有下班卡则添加第一次打卡数据
newList.add(frontToWorkBean);
//获取工作异常
LocalTime lastOutTime = null;
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
//存储工作异常的list
List<AttSourceDataBean> longBreakRecords = new ArrayList<>();
for (int i = 0; i < v.size(); i++) {
AttSourceDataBean record = v.get(i);
// 如果是的记录保存时间
if ("2".equals(record.getAttType())) {
lastOutTime = LocalDateTime.parse(record.getAttCurrentTime(), dateTimeFormatter).toLocalTime();
if(lastOutTime.isAfter(LocalTime.parse(attGroupBean.getOffWorkTime(), timeFormatter))){
//进在下班之后不考虑
break;
}
}
// 如果是的记录并且之前有的记录
else if ("1".equals(record.getAttType()) && lastOutTime != null) {
LocalTime inTime = LocalDateTime.parse(record.getAttCurrentTime(), dateTimeFormatter).toLocalTime();
// 计算实际工作时间不包括午休时间
// if(record.getName().equals("何波")){
// System.out.println("11111111111");
// }
// - 的时间在上班时间前去除
if(inTime.isBefore(LocalTime.parse(attGroupBean.getToWorkTime(), timeFormatter))){
//进在上班之后不考虑
break;
}
Duration workDuration = calculateWorkDuration(lastOutTime, inTime, attGroupBean);
// 如果工作时间外出超过了规定时间记录下这对
if (workDuration != null && !workDuration.isNegative() && workDuration.toMinutes() > attGroupBean.getWorkAbnormalMinute()) {
AttSourceDataBean longBreakRecord = new AttSourceDataBean();
longBreakRecord.setUserId(record.getUserId());
longBreakRecord.setName(record.getName());
longBreakRecord.setOrgId(attGroupBean.getOrgId());
longBreakRecord.setAttCurrentDay(record.getAttCurrentDay());
longBreakRecord.setAttCurrentTime(v.get(i - 1).getAttCurrentTime() + " " + record.getAttCurrentTime());
longBreakRecord.setAttAddress(v.get(i - 1).getAttAddress() + " " + record.getAttAddress());
longBreakRecords.add(longBreakRecord);
}
// 更新lastOutTime为null因为已经处理了这一对
lastOutTime = null;
}
}
//判断有没有临时外出请假等等
if(!longBreakRecords.isEmpty()){
int x = attSourceDataDao.getLeaveDataByUserId(longBreakRecords.get(0));
if(x==0){
attSourceDataDao.insertWorkAbnormal(longBreakRecords);
}
}
}
});
return newList;
}
private static Duration calculateWorkDuration(LocalTime outTime, LocalTime inTime, AttGroupBean group) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
// 解析上班下班午休开始结束时间
LocalTime offWorkTime = LocalTime.parse(group.getOffWorkTime(), formatter);
LocalTime breakStartTime = LocalTime.parse(group.getBreakStartTime(), formatter);
LocalTime breakEndTime = LocalTime.parse(group.getBreakEndTime(), formatter);
// 如果出勤时间在午休时间内调整出勤时间为午休结束时间
if (outTime.isAfter(breakStartTime) && outTime.isBefore(breakEndTime)) {
outTime = breakEndTime;
}
// 如果进入时间在午休时间内调整进入时间为午休开始时间
if (inTime.isAfter(breakStartTime) && inTime.isBefore(breakEndTime)) {
inTime = breakStartTime;
}
// 如果进入时间在下班时间内调整进入时间为下班时间
if (inTime.isAfter(offWorkTime)) {
inTime = offWorkTime;
}
// 计算总的工作时间
Duration totalDuration = Duration.between(outTime, inTime);
// 如果时间段跨越了午休时间减去午休时长
if (outTime.isBefore(breakEndTime) && inTime.isAfter(breakStartTime)) {
Duration breakDuration = Duration.between(breakStartTime, breakEndTime);
totalDuration = totalDuration.minus(breakDuration);
}
return totalDuration;
} catch (DateTimeParseException e) {
// 处理解析异常例如记录日志或返回默认值
System.err.println("时间解析错误: " + e.getMessage());
return null; // 或者返回一个默认的 LocalDateTime
}
}
/**
* 根据getAttCurrentTime对List<AttSourceDataBean>进行正序排序
* 遍历排序后的列表找到最早相邻且间隔时间大于2分钟的两个attType = 1的数据项
* 检查这两个数据项之前的数据集合是否同时包含attType = 1和attType = 2的数据
*
* @param items
* @param entryAbnormalMinute
* @return
@ -861,10 +924,11 @@ public class AttTasks {
if (minutesDiff >= attGroupBean.getAttendanceDuration()) {
backOffWorkBean.setAttStatus(1);
} else {
if (minutesDiff < attGroupBean.getAbsenteeismLateMinute()) {
if (minutesDiff > attGroupBean.getAbsenteeismLateMinute()) {
backOffWorkBean.setAttStatus(1);
}else if (minutesDiff > attGroupBean.getAbsenteeismLeaveMinute()) {
backOffWorkBean.setAttStatus(4);
}
if (minutesDiff < attGroupBean.getAbsenteeismLeaveMinute()) {
}else{
backOffWorkBean.setAttStatus(3);
}
}

View File

@ -61,9 +61,9 @@ import static com.bonus.system.att.utils.DistanceCalculator.calculateDistance;
* 微信小程序数据同步接口
*/
@Configuration
@EnableScheduling
@Slf4j
@EnableAsync
//@EnableScheduling
//@EnableAsync
public class WechatTasks {
@Resource(name = "WechatPushDao")
@ -75,7 +75,7 @@ public class WechatTasks {
* 人员基础数据同步定时器
*/
// @Scheduled(cron = "0 0/10 * * * ?")
@Scheduled(initialDelay = 60000 * 1,fixedDelay = 60000 * 1)
// @Scheduled(initialDelay = 60000 * 1,fixedDelay = 60000 * 1)
@Async
public void pushPersonTask() {
log.info("--------人员基础数据同步定时器开启------");
@ -103,7 +103,7 @@ public class WechatTasks {
/**
* 休假出差数据同步定时器
*/
@Scheduled(initialDelay = 60000 * 2,fixedDelay = 60000 * 1)
// @Scheduled(initialDelay = 60000 * 2,fixedDelay = 60000 * 1)
@Async
public void leaveTask() {
log.info("--------休假出差数据定时器开启------");
@ -182,7 +182,7 @@ public class WechatTasks {
/**
* 考勤数据同步定时器
*/
@Scheduled(initialDelay = 60000 * 3,fixedDelay = 60000 * 1)
// @Scheduled(initialDelay = 60000 * 3,fixedDelay = 60000 * 1)
@Async
public void wechatAttTask() {
log.info("--------考勤数据定时器开启------");

View File

@ -2,11 +2,16 @@ package com.bonus.system.att.utils;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.system.att.entity.Holiday;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.*;
/**
* 计算工作日
*
* @author zys
*/
public class WorkdayCalculator {
@ -16,35 +21,45 @@ public class WorkdayCalculator {
Calendar.FRIDAY, Calendar.SATURDAY, Calendar.SUNDAY};
public static void main(String[] args) {
getWorkDay("1,0,1,1,1,0,1", 1, getHolidays());
getWorkDay("1,0,1,1,1,0,1", 1, getHolidays(), "2024-11-05");
}
public static List<String> getWorkDay(String attDays, int type, List<Holiday> holidays){
public static List<String> getWorkDay(String attDays, int type, List<Holiday> holidays, String pushDate) {
List<Integer> dueWorkDates = getDueWorkDates(attDays);
String year = DateUtils.getYear();
String month = DateUtils.getMm();
// 获取工作日集合排除周末
List<Date> workDays = getWorkDays(Integer.parseInt(year), Integer.parseInt(month), dueWorkDates);
// 获取工作日字符串集合
List<String> dateString = getDateString(workDays);
// 获取法定节假日集合
if(type == 1) {
holidays.forEach(c -> {
if (c.getType().equals("1")) {
dateString.remove(c.getDate());
} else if (c.getType().equals("2")) {
dateString.add(c.getDate());
}
});
// 定义日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
try {
// 解析日期字符串为 LocalDate 对象
LocalDate date = LocalDate.parse(pushDate, formatter);
// 获取年份和月份
int year = date.getYear();
int month = date.getMonthValue(); // 获取月份1-12
// 获取工作日集合排除周末
List<Date> workDays = getWorkDays(year, month, dueWorkDates);
// 获取工作日字符串集合
List<String> dateString = getDateString(workDays);
// 获取法定节假日集合
if (type == 1) {
holidays.forEach(c -> {
if (c.getType().equals("1")) {
dateString.remove(c.getDate());
} else if (c.getType().equals("2")) {
dateString.add(c.getDate());
}
});
}
return dateString;
} catch (Exception e) {
e.printStackTrace();
}
return dateString;
return new ArrayList<>();
}
private static List<Integer> getDueWorkDates(String s) {
List<Integer> week = new ArrayList<>();
List<String> list = new ArrayList<>(Arrays.asList(s.split(",")));
for (int i = 0; i < list.size(); i++) {
if(list.get(i).equals("1")){
if (list.get(i).equals("1")) {
week.add(weekDays[i]);
}
}
@ -71,7 +86,7 @@ public class WorkdayCalculator {
// 返回工作日集合只排除周末
public static List<Date> getWorkDays(int year, int month, List<Integer> dueWorkDates){
public static List<Date> getWorkDays(int year, int month, List<Integer> dueWorkDates) {
// 用于储存每月工作日
List<Date> dates = new ArrayList<Date>();
@ -82,19 +97,19 @@ public class WorkdayCalculator {
cal.set(Calendar.MONTH, month - 1);
// 设置为当月第一天
cal.set(Calendar.DATE, 1);
while(cal.get(Calendar.YEAR) == year && cal.get(Calendar.MONTH) < month){
while (cal.get(Calendar.YEAR) == year && cal.get(Calendar.MONTH) < month) {
// 判断当前天为本周的第几天
int day = cal.get(Calendar.DAY_OF_WEEK);
// 如果不为周六或者周天,将日期进行储存
List<Boolean> list = new ArrayList<>();
dueWorkDates.forEach(c->{
if(day == c){
dueWorkDates.forEach(c -> {
if (day == c) {
list.add(true);
}
});
if(!list.isEmpty()){
if(list.stream().allMatch(Boolean::booleanValue)){
dates.add((Date)cal.getTime().clone());
if (!list.isEmpty()) {
if (list.stream().allMatch(Boolean::booleanValue)) {
dates.add((Date) cal.getTime().clone());
}
}
// if(!(day == Calendar.SUNDAY || day == Calendar.SATURDAY)){
@ -108,16 +123,15 @@ public class WorkdayCalculator {
}
/**
*
* @param dateList
* @return 返回日期字符串集合
*/
public static List<String> getDateString(List<Date> dateList){
public static List<String> getDateString(List<Date> dateList) {
// 储存日期字符串
List<String> dateString = new ArrayList<>();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
for (Date date : dateList){
for (Date date : dateList) {
String date2 = simpleDateFormat.format(date);
dateString.add(date2);
}

View File

@ -5,7 +5,7 @@
<mapper namespace="com.bonus.system.att.dao.AttGroupDao">
<select id="selectAttGroupList" resultType="com.bonus.system.att.entity.AttGroupBean">
select ags.*, ag.id as groupId, ag.group_name, ag.att_type from att_group ag
select ags.*, ag.id as groupId, ag.group_name, ag.att_type,agpr.org_id from att_group ag
left join att_group_setting ags on ags.group_id = ag.id and ags.is_active = 1
left join att_group_person_relation agpr on agpr.group_id = ag.id and agpr.is_active = 1
where ag.is_active = 1

View File

@ -50,6 +50,12 @@
insert into att_data_update(user_id, org_id, att_current_day, att_status, att_type)
values (#{userId}, #{orgId}, #{attCurrentDay}, #{attStatus}, #{attType})
</insert>
<insert id="insertWorkAbnormal">
<foreach collection="list" item="item" separator=";">
replace into att_work_abnormal(user_id, user_name,org_id, att_current_day,att_current_time, att_address)
values (#{item.userId}, #{item.name},#{item.orgId}, #{item.attCurrentDay}, #{item.attCurrentTime}, #{item.attAddress})
</foreach>
</insert>
<!-- replace into att_data(user_id, org_id, att_current_day, att_current_time,-->
<!-- att_type, att_address, att_lon, att_lat, data_source, att_status, error_remake)-->
@ -102,10 +108,13 @@
<!-- delete from att_source_data where att_current_day = #{date};-->
<!-- update att_data set att_current_time = null,att_status = 0,att_address = null,att_lon = null,att_lat = null where att_current_day = #{date};-->
<!-- update att_data_update set att_current_time = null,att_status = 0,att_address = null,att_lon = null,att_lat = null where att_current_day = #{date};-->
<!-- delete from att_source_data where att_current_day = #{date};-->
<!-- delete from att_data where att_current_day = #{date};-->
<!-- delete from att_data_update where att_current_day = #{date};-->
<delete id="delHisData">
delete from att_source_data where att_current_day = #{date};
delete from att_data where att_current_day = #{date};
delete from att_data_update where att_current_day = #{date};
update att_data set att_current_time = null,att_status = 0,att_address = null,att_lon = null,att_lat = null where att_current_day = #{date};
update att_data_update set att_current_time = null,att_status = 0,att_address = null,att_lon = null,att_lat = null where att_current_day = #{date};
</delete>
<select id="getQsyAttendances" resultType="com.bonus.system.att.entity.AttSourceDataBean">
@ -116,7 +125,7 @@
from gz_cloud_test.fc_sup_attendance sup
where sup.attendance_date
<if test=' pushType == "1" '>
>= #{pushDate} - INTERVAL 3 DAY
>= #{pushDate}
</if>
<if test=' pushType == "2" '>
= #{pushDate}
@ -156,7 +165,7 @@
from v_att_update_data
where att_current_day
<if test=' pushType == "1" '>
>= #{pushDate} - INTERVAL 3 DAY
>= #{pushDate}
</if>
<if test=' pushType == "2" '>
= #{pushDate}
@ -196,7 +205,7 @@
from sys_holiday
where `date`
<if test=' pushType == "1" '>
>= #{pushDate} - INTERVAL 3 DAY
>= #{pushDate}
</if>
<if test=' pushType == "2" '>
= #{pushDate}
@ -229,7 +238,7 @@
left join att_group g on g.id = ag.group_id
where att_current_day
<if test=' pushType == "1" '>
>= #{pushDate} - INTERVAL 3 DAY
>= #{pushDate}
</if>
<if test=' pushType == "2" '>
= #{pushDate}
@ -247,7 +256,7 @@
left join att_group g on g.id = ag.group_id
where att_current_day
<if test=' pushType == "1" '>
>= #{pushDate} - INTERVAL 3 DAY
>= #{pushDate}
</if>
<if test=' pushType == "2" '>
= #{pushDate}
@ -294,7 +303,7 @@
left join zkeco.userinfo u on u.userid = c.userid
where DATE_FORMAT(c.checktime, '%Y-%m-%d')
<if test=' pushType == "1" '>
>= #{pushDate} - INTERVAL 3 DAY
>= #{pushDate}
</if>
<if test=' pushType == "2" '>
= #{pushDate}
@ -325,9 +334,21 @@
left join sys_user su on su.user_name = asd.name
left join att_group_person_relation ag on ag.user_id = su.user_id and ag.is_active = 1
left join att_group g on g.id = ag.group_id
where att_current_day >= CURDATE() - INTERVAL 3 DAY
where att_current_day >= CURDATE()
and g.id is not null
and asd.data_source = 2
and asd.att_type = 0
</select>
<select id="getLeaveDataByUserId" resultType="java.lang.Integer">
SELECT
count(1)
FROM
leave_apply la
WHERE
la.is_active = 1
AND la.examine_status = 1
AND user_id = #{userId}
AND #{attCurrentDay} BETWEEN leave_start_date and leave_end_date
</select>
</mapper>