From d5635e0387e886f450f35b087690d16ba0700f74 Mon Sep 17 00:00:00 2001 From: cwchen <1048842385@qq.com> Date: Wed, 27 Aug 2025 13:06:30 +0800 Subject: [PATCH] =?UTF-8?q?8=E6=9C=88=E8=80=83=E5=8B=A4=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bonus/ahsbs/base/dao/IAttSyncDao.java | 50 ++++++++ .../base/entity/FcFaceContrastOldBean.java | 72 +++++++++++ .../bonus/ahsbs/base/task/AttSyncTask.java | 112 ++++++++++++++++++ .../bonus/ahsbs/base/task/AttendanceTask.java | 108 ++++++++++++----- .../bonus/ahsbs/base/task/WorkNumTask.java | 9 +- .../resources/mappers/base/AttSyncMapper.xml | 111 +++++++++++++++++ 6 files changed, 429 insertions(+), 33 deletions(-) create mode 100644 src/main/java/com/bonus/ahsbs/base/dao/IAttSyncDao.java create mode 100644 src/main/java/com/bonus/ahsbs/base/entity/FcFaceContrastOldBean.java create mode 100644 src/main/java/com/bonus/ahsbs/base/task/AttSyncTask.java create mode 100644 src/main/resources/mappers/base/AttSyncMapper.xml diff --git a/src/main/java/com/bonus/ahsbs/base/dao/IAttSyncDao.java b/src/main/java/com/bonus/ahsbs/base/dao/IAttSyncDao.java new file mode 100644 index 0000000..acbb51f --- /dev/null +++ b/src/main/java/com/bonus/ahsbs/base/dao/IAttSyncDao.java @@ -0,0 +1,50 @@ +package com.bonus.ahsbs.base.dao; + +import com.bonus.ahsbs.base.entity.FcFaceContrastOldBean; +import org.springframework.stereotype.Repository; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * @className:IAttSyncDao + * @author:cwchen + * @date:2025-08-26-16:48 + * @version:1.0 + * @description:8月份考勤数据同步 + */ +@Repository(value = "IAttSyncDao") +public interface IAttSyncDao { + int countByTimeRange(@Param("startTime") String startTime, @Param("endTime") String endTime); + + /** + * 查询8月份考勤数据 + * @param startTime + * @param endTime + * @param offset + * @param limit + * @return List + * @author cwchen + * @date 2025/8/26 17:40 + */ + List pageByTimeRange(@Param("startTime") String startTime, + @Param("endTime") String endTime, + @Param("offset") int offset, + @Param("limit") int limit); + + /** + * 8月份数据考勤是否已经添加完成 + * @return int + * @author cwchen + * @date 2025/8/26 17:54 + */ + int isAddData(@Param("startTime") String startTime, @Param("endTime") String endTime); + + /** + * 添加8月份考勤数据 + * @param list + * @return void + * @author cwchen + * @date 2025/8/26 17:58 + */ + void addAttData(@Param("list") List list); +} diff --git a/src/main/java/com/bonus/ahsbs/base/entity/FcFaceContrastOldBean.java b/src/main/java/com/bonus/ahsbs/base/entity/FcFaceContrastOldBean.java new file mode 100644 index 0000000..2facb7f --- /dev/null +++ b/src/main/java/com/bonus/ahsbs/base/entity/FcFaceContrastOldBean.java @@ -0,0 +1,72 @@ +package com.bonus.ahsbs.base.entity; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @className:FcFaceContrastBean + * @author:cwchen + * @date:2025-07-09-11:13 + * @version:1.0 + * @description:人员考勤-vo + */ +@Data +public class FcFaceContrastOldBean { + + /**身份证号*/ + private String idCard; + /**姓名*/ + private String userName; + /**工程ID*/ + private Long proId; + /**分包ID*/ + private Long subId; + /**班组ID*/ + private Long teamId; + /**组织ID*/ + private Long orgId; + /**岗位ID*/ + private Long postId; + /**银行卡信息*/ + private String bankCard; + /**施工人员合同ID*/ + private String contractId; + /**工资标准*/ + private BigDecimal wageCriterion = BigDecimal.ZERO; + /**绩效-max*/ + private BigDecimal maxAchievementsMoney = BigDecimal.ZERO; + /**绩效-min*/ + private BigDecimal minAchievementsMoney = BigDecimal.ZERO; + /**合同生效日期*/ + private String effectDate; + /**工种名称*/ + private String workName; + /**工种类型*/ + private String workType; + + private String isRepair; + + private String address; + private String lat; + private String lon; + + private String overHours; + private String workHours; + private String auditRemark; + private String auditStatus; + private String auditTime; + private String auditor; + private String isSuccess; + private String uploadType; + private String photoPath; + private String uploadTime; + private String addTime; + private String currentDay; + private String dataType; + private String checkMoney; + private String userId; + private String remark; + + +} diff --git a/src/main/java/com/bonus/ahsbs/base/task/AttSyncTask.java b/src/main/java/com/bonus/ahsbs/base/task/AttSyncTask.java new file mode 100644 index 0000000..31dfb59 --- /dev/null +++ b/src/main/java/com/bonus/ahsbs/base/task/AttSyncTask.java @@ -0,0 +1,112 @@ +package com.bonus.ahsbs.base.task; +import com.bonus.ahsbs.base.dao.IAttSyncDao; +import com.bonus.ahsbs.base.entity.FcFaceContrastOldBean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import javax.annotation.Resource; +import java.util.List; + +/** + * @className:AttSyncTask + * @author:cwchen + * @date:2025-08-26-16:46 + * @version:1.0 + * @description:8月份考勤数据同步 + */ +@Component +@Slf4j +@EnableScheduling +@EnableAsync +public class AttSyncTask { + + @Resource(name = "IAttSyncDao") + private IAttSyncDao dao; + + /** + * 定时任务:每日 02:10 触发一次,同步当前自然月数据([当月1号00:00:00, 次月1号00:00:00)) + */ +// @Scheduled(cron = "0 0/1 1-18 * * ?") // 本地调试 + @Scheduled(cron = "0 0/30 23 * * ?") // 生产 + public void scheduledSyncCurrentMonth() { + String startTime = "2025-08-01"; + String endTime = "2025-08-31"; + int pageSize = 1000; + boolean addData = isAddData(startTime, endTime); + if(!addData){ + log.info("定时任务开始:考勤数据分页同步,区间[{}, {}],pageSize={}", startTime, endTime, pageSize); + syncByPages(startTime, endTime, pageSize); + log.info("定时任务结束:考勤数据分页同步"); + }else { + log.info("8月份考勤数据已补"); + } + + } + + /** + * 8月份数据考勤是否已经添加完成 + */ + public boolean isAddData(String startTime, String endTime) { + try { + int num = dao.isAddData(startTime,endTime); + if(num > 0){ + return true; + } + return false; + } catch (Exception e) { + log.error(e.toString(), e); + } + return true; + } + + /** + * 先查询总数,再按页查询 + * @param startTime 开始时间,例如 2025-08-01 + * @param endTime 结束时间,例如 2025-08-31 + * @param pageSize 每页大小 + */ + public void syncByPages(String startTime, String endTime, int pageSize) { + // 查询总条数 + int total = dao.countByTimeRange(startTime, endTime); + if (total <= 0) { + log.info("区间内无数据,无需同步。startTime={}, endTime={}", startTime, endTime); + return; + } + int pages = (total + pageSize - 1) / pageSize; + log.info("开始分页同步,总数={},页大小={},总页数={},区间[{}, {}]", total, pageSize, pages, startTime, endTime); + + for (int pageIndex = 0; pageIndex < pages; pageIndex++) { + int offset = pageIndex * pageSize; + List rows = dao.pageByTimeRange(startTime, endTime, offset, pageSize); + try { + if (rows == null || rows.isEmpty()) { + log.info("第{}页无数据,跳过。", pageIndex + 1); + continue; + } + // 在此处处理分页数据 rows,例如批量写入目标库/下游系统 + handlePageData(rows, pageIndex + 1, pages); + } finally { + // 释放已处理数据并触发垃圾回收 + if (rows != null) { + rows.clear(); + } + rows = null; + System.gc(); + } + } + + log.info("分页同步完成,总数={},区间[{}, {}]", total, startTime, endTime); + } + + private void handlePageData(List rows, int currentPage, int totalPages) { + log.info("处理第{}/{}页,记录数={}", currentPage, totalPages, rows.size()); + try { + // 添加8月份考勤数据 + dao.addAttData(rows); + } catch (Exception e) { + log.error(e.toString(), e); + } + } +} diff --git a/src/main/java/com/bonus/ahsbs/base/task/AttendanceTask.java b/src/main/java/com/bonus/ahsbs/base/task/AttendanceTask.java index 03872d5..d030ce1 100644 --- a/src/main/java/com/bonus/ahsbs/base/task/AttendanceTask.java +++ b/src/main/java/com/bonus/ahsbs/base/task/AttendanceTask.java @@ -128,31 +128,50 @@ public class AttendanceTask { @Scheduled(cron = "0 0/5 7-20 * * ?") // 生产 // @Scheduled(cron = "0 0/1 7-20 * * ?") // 本地调试 @Async - public void newEntryByToday(){ + public void newEntryByToday() { log.info("今日新入场施工人员,并且已经签订合同 考勤数据入库定时任务开始执行"); + List newEntryWorkers = null; + List bePutInStorage = null; + List missDataList = null; + List updateDataList = null; try { String day = DateTimeHelper.getNowDate(); // 1.查询今日新入场,并且已经签订合同的施工人员 - List newEntryWorkers = dao.getNewEntryWorkers(day); + newEntryWorkers = dao.getNewEntryWorkers(day); // 2.查询已经入考勤库的人员 - List bePutInStorage= dao.getBePutInStorage(day); + bePutInStorage = dao.getBePutInStorage(day); // 3.比对出未入考勤库人员 - List missDataList = findMissingInB(bePutInStorage, newEntryWorkers); + missDataList = findMissingInB(bePutInStorage, newEntryWorkers); // 4.已入考勤库人员,并对基本信息进行更新 - List updateDataList = findExitInB(bePutInStorage, newEntryWorkers); + updateDataList = findExitInB(bePutInStorage, newEntryWorkers); // 5. 添加未入考勤库人员数据 int result = 0; - if(CollectionUtils.isNotEmpty(missDataList)){ + if (CollectionUtils.isNotEmpty(missDataList)) { result = dao.addAttData(missDataList, day); } // 6. 更新已入考勤库人员数据 int result2 = 0; - if(CollectionUtils.isNotEmpty(updateDataList)){ + if (CollectionUtils.isNotEmpty(updateDataList)) { result2 = dao.updateData(updateDataList, day); } - log.info("考勤数据入库成功,新入场数据:"+result+"条,更新数据:"+result2+"条"); + log.info("考勤数据入库成功,新入场数据:" + result + "条,更新数据:" + result2 + "条"); } catch (Exception e) { - log.error(e.toString(),e); + log.error(e.toString(), e); + } finally { + // 释放已处理数据并触发垃圾回收 + if (CollectionUtils.isNotEmpty(newEntryWorkers)) { + newEntryWorkers.clear(); + } + if (CollectionUtils.isNotEmpty(bePutInStorage)) { + bePutInStorage.clear(); + } + if (CollectionUtils.isNotEmpty(missDataList)) { + missDataList.clear(); + } + if (CollectionUtils.isNotEmpty(updateDataList)) { + updateDataList.clear(); + } + System.gc(); } log.info("今日新入场施工人员,并且已经签订合同 考勤数据入库定时任务结束执行"); } @@ -166,29 +185,56 @@ public class AttendanceTask { */ public void addData(List dates){ for (String day : dates) { - // 1.查询已出场的施工人员(按日期) - List idNumbers = dao.getExitWorkerByDay(day); - if(CollectionUtils.isNotEmpty(idNumbers)){ - // 2.删除已经出场施工人员,并且已入考勤库的数据(未打卡) - dao.delAttByExitData(day,idNumbers); + List idNumbers = null; + List workers = null; + List bePutInStorage = null; + List missDataList = null; + List updateDataList = null; + try { + // 1.查询已出场的施工人员(按日期) + idNumbers = dao.getExitWorkerByDay(day); + if (CollectionUtils.isNotEmpty(idNumbers)) { + // 2.删除已经出场施工人员,并且已入考勤库的数据(未打卡) + dao.delAttByExitData(day, idNumbers); + } + // 3.查询未出场的施工人员(有施工合同) + workers = dao.getWorkersByDay(day); + // 4.查询已经入考勤库的人员 + bePutInStorage = dao.getBePutInStorage(day); + // 5.比对出未入考勤库人员 + missDataList = findMissingInB(bePutInStorage, workers); + // 6.已入考勤库人员,并对基本信息进行更新 + updateDataList = findExitInB(bePutInStorage, workers); + // 7. 添加未入考勤库人员数据 + if (CollectionUtils.isNotEmpty(missDataList)) { + dao.addAttData(missDataList, day); + } + // 8. 更新已入考勤库人员数据 + if (CollectionUtils.isNotEmpty(updateDataList)) { + dao.updateData(updateDataList, day); + } + log.info("考勤数据入库成功,新增数据:" + missDataList.size() + "条,更新数据:" + updateDataList.size() + "条"); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + // 释放已处理数据并触发垃圾回收 + if (CollectionUtils.isNotEmpty(idNumbers)) { + idNumbers.clear(); + } + if (CollectionUtils.isNotEmpty(workers)) { + workers.clear(); + } + if (CollectionUtils.isNotEmpty(bePutInStorage)) { + bePutInStorage.clear(); + } + if (CollectionUtils.isNotEmpty(missDataList)) { + missDataList.clear(); + } + if (CollectionUtils.isNotEmpty(updateDataList)) { + updateDataList.clear(); + } + System.gc(); } - // 3.查询未出场的施工人员(有施工合同) - List workers = dao.getWorkersByDay(day); - // 4.查询已经入考勤库的人员 - List bePutInStorage= dao.getBePutInStorage(day); - // 5.比对出未入考勤库人员 - List missDataList = findMissingInB(bePutInStorage, workers); - // 6.已入考勤库人员,并对基本信息进行更新 - List updateDataList = findExitInB(bePutInStorage, workers); - // 7. 添加未入考勤库人员数据 - if(CollectionUtils.isNotEmpty(missDataList)){ - dao.addAttData(missDataList, day); - } - // 8. 更新已入考勤库人员数据 - if(CollectionUtils.isNotEmpty(updateDataList)){ - dao.updateData(updateDataList, day); - } - log.info("考勤数据入库成功,新增数据:"+missDataList.size()+"条,更新数据:"+updateDataList.size()+"条"); } } diff --git a/src/main/java/com/bonus/ahsbs/base/task/WorkNumTask.java b/src/main/java/com/bonus/ahsbs/base/task/WorkNumTask.java index 8d6c3ed..bbd5f4c 100644 --- a/src/main/java/com/bonus/ahsbs/base/task/WorkNumTask.java +++ b/src/main/java/com/bonus/ahsbs/base/task/WorkNumTask.java @@ -83,8 +83,8 @@ public class WorkNumTask { * @date 2025/7/10 13:12 */ public void addData(List dates){ + List dataList = new ArrayList<>(); try { - List dataList = new ArrayList<>(); // 1.查询所有工程 List list = Optional.ofNullable(dao.getAllProData()).orElseGet(ArrayList::new); for (String day : dates) { @@ -114,9 +114,14 @@ public class WorkNumTask { if(CollectionUtils.isNotEmpty(dataList)){ dao.batchInsertOrUpdate(dataList); } - dataList.clear(); } catch (Exception e) { log.error(e.toString(), e); + }finally { + // 释放已处理数据并触发垃圾回收 + if (CollectionUtils.isNotEmpty(dataList)) { + dataList.clear(); + } + System.gc(); } } diff --git a/src/main/resources/mappers/base/AttSyncMapper.xml b/src/main/resources/mappers/base/AttSyncMapper.xml new file mode 100644 index 0000000..ceb2657 --- /dev/null +++ b/src/main/resources/mappers/base/AttSyncMapper.xml @@ -0,0 +1,111 @@ + + + + + + INSERT INTO xbg_user_attendance( + id_card, user_id, user_name, data_type, check_time, check_image, + check_money, lat, lon, address, gx_id, gx_name, contract_id, + work_name, work_type, wage_criterion, min_perfor, max_perfor, + audit_status, audti_user, audit_time, audit_remark, team_id, + is_repair, repair_time, repair_remark, pro_id, sub_id, remark, + create_date, create_user, create_time, effect_date, bank_card, + post_id + ) + VALUES + + ( + #{item.idCard}, #{item.userId}, #{item.userName}, #{item.dataType}, #{item.uploadTime}, #{item.photoPath}, + #{item.checkMoney}, #{item.lat}, #{item.lon}, #{item.address}, NULL, NULL, #{item.contractId}, + #{item.workName}, #{item.workType}, #{item.wageCriterion}, #{item.minAchievementsMoney}, #{item.maxAchievementsMoney}, + #{item.auditStatus}, #{item.auditor}, #{item.auditTime}, #{item.auditRemark}, #{item.teamId}, + #{item.isRepair}, NULL,NULL, #{item.proId}, #{item.subId}, #{item.remark}, + #{item.currentDay}, 1, NOW(), #{item.effectDate}, #{item.bankCard}, + #{item.postId} + ) + + + + + + + + + + + +