From b0a89422bbb30d0567ffe24b4b338de0dce658ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=B9=E4=BA=AE?= Date: Fri, 19 Sep 2025 17:54:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=89=E8=A1=A8=E4=B8=80=E5=86=8C=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9D=A5=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bonus/job/domain/MapBeanVo.java | 25 ++ .../job/domain/ThreeTableOneRosterPo.java | 47 ++++ .../com/bonus/job/domain/WorkerAttDayVo.java | 29 +++ .../com/bonus/job/mapper/WorkerJobMapper.java | 44 ++++ .../job/task/ThreeTableOneRosterTask.java | 239 ++++++++++++++++++ .../resources/mapper/job/WorkerJobMapper.xml | 141 +++++++++++ 6 files changed, 525 insertions(+) create mode 100644 bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/MapBeanVo.java create mode 100644 bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/ThreeTableOneRosterPo.java create mode 100644 bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/WorkerAttDayVo.java create mode 100644 bonus-modules/bonus-job/src/main/java/com/bonus/job/task/ThreeTableOneRosterTask.java diff --git a/bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/MapBeanVo.java b/bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/MapBeanVo.java new file mode 100644 index 0000000..929dc9e --- /dev/null +++ b/bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/MapBeanVo.java @@ -0,0 +1,25 @@ +package com.bonus.job.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MapBeanVo { + + private String key; + + private String value; + + private Integer id; + + private String name; + + public MapBeanVo(String key, String value){ + this.value = value; + this.key = key; + } + +} diff --git a/bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/ThreeTableOneRosterPo.java b/bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/ThreeTableOneRosterPo.java new file mode 100644 index 0000000..a7acb05 --- /dev/null +++ b/bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/ThreeTableOneRosterPo.java @@ -0,0 +1,47 @@ +package com.bonus.job.domain; + +import lombok.Data; + +@Data +public class ThreeTableOneRosterPo { + private Integer proId; + private String attMonth; + private Integer subId; + private String subName; + private Integer teamId; + private String teamName; + private Integer workerId; + private String name; + private String sex; + private Integer postId; + private String postName; + private String idNumber; + private String address; + private String phone; + private String proName; + //1.花名册 + private String firstEinTime; + private String lastExitTime; + //2.农民工实名制工资信息报审表 + private String bankName; + private String bankCardCode; + private String bankIdentifierCode; + private Integer contractId; + private Double priceWage; + private String payment; + private String payDay; + private String remark; + + //3.考勤明细表 + private String einDay; + private String attDay; + private String isRepair; + private String attendanceDay; + private Integer checkDay; + private Integer repairNum; + private Integer attendanceNum; + //4.工资明细表 + private Double payMoney; + private Double deductMoney; + private Double actualMoney; +} diff --git a/bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/WorkerAttDayVo.java b/bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/WorkerAttDayVo.java new file mode 100644 index 0000000..7d410f6 --- /dev/null +++ b/bonus-modules/bonus-job/src/main/java/com/bonus/job/domain/WorkerAttDayVo.java @@ -0,0 +1,29 @@ +package com.bonus.job.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class WorkerAttDayVo { + + /** + * 日期 + */ + private String day; + /** + * 是否在场 + */ + private String isEin; + /** + * 是否打卡 + */ + private String isAtt; + /** + * 是否为补卡 + */ + private String isRepair; + +} diff --git a/bonus-modules/bonus-job/src/main/java/com/bonus/job/mapper/WorkerJobMapper.java b/bonus-modules/bonus-job/src/main/java/com/bonus/job/mapper/WorkerJobMapper.java index 5ba4c5d..354f3db 100644 --- a/bonus-modules/bonus-job/src/main/java/com/bonus/job/mapper/WorkerJobMapper.java +++ b/bonus-modules/bonus-job/src/main/java/com/bonus/job/mapper/WorkerJobMapper.java @@ -1,7 +1,10 @@ package com.bonus.job.mapper; import com.bonus.job.domain.BmWorkerBlackJob; +import com.bonus.job.domain.MapBeanVo; import com.bonus.job.domain.PmWorkerJob; +import com.bonus.job.domain.ThreeTableOneRosterPo; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -33,4 +36,45 @@ public interface WorkerJobMapper { int insertWorkerBlack(List list); void updateWorkerEinDayRecordBlackStatus(List list); + + /** + * 查询所有有人在场的工程 + * @param lastMonth + * @return + */ + List getAllPro(String lastMonth); + + /** + * 人员花名册 + * @param attMonth + * @param startTime + * @param endTime + * @param proId + * @return + */ + List getWorkerRosterData(@Param("attMonth") String attMonth, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("proId") Integer proId); + + /** + * 农民工实名制工资信息报审表 + * @param attMonth + * @param proId + * @return + */ + List getWorkerApplyData(@Param("attMonth") String attMonth, @Param("proId") Integer proId); + + /** + * 农民工实名制工资信息考勤表 + * @param attMonth + * @param proId + * @return + */ + List getWorkerAttData(@Param("attMonth") String attMonth, @Param("proId") Integer proId); + + /** + * 农民工实名制工资信息支付表 + * @param attMonth + * @param proId + * @return + */ + List getWorkerPayData(@Param("attMonth") String attMonth, @Param("proId") Integer proId); } diff --git a/bonus-modules/bonus-job/src/main/java/com/bonus/job/task/ThreeTableOneRosterTask.java b/bonus-modules/bonus-job/src/main/java/com/bonus/job/task/ThreeTableOneRosterTask.java new file mode 100644 index 0000000..cdc6ae2 --- /dev/null +++ b/bonus-modules/bonus-job/src/main/java/com/bonus/job/task/ThreeTableOneRosterTask.java @@ -0,0 +1,239 @@ +package com.bonus.job.task; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.bonus.job.domain.MapBeanVo; +import com.bonus.job.domain.ThreeTableOneRosterPo; +import com.bonus.job.domain.WorkerAttDayVo; +import com.bonus.job.mapper.WorkerJobMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.YearMonth; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 三表一册定时任务调度 + * + * @author bonus + */ +@Component("threeTableOneRosterTask") +public class ThreeTableOneRosterTask { + + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + @Resource + private WorkerJobMapper mapper; + + /** + * 三表一册生成 + * 每月1号生成上月数据 + */ + public void createThreeTableOneRosterData(){ + try{ + // 获取当前年月 + YearMonth current = YearMonth.now(); + // 获取上一个月 + YearMonth lastMonth = current.minusMonths(1); + // 本月第一天 + LocalDate firstDayOfThisMonth = YearMonth.now().atDay(1); + // 上个月第一天:先得到本月第一天,再减一个月 + LocalDate firstDayOfLastMonth = YearMonth.now().minusMonths(1).atDay(1); + + String startTime = firstDayOfLastMonth.format(FORMATTER)+" 00:00:00"; + String endTime = firstDayOfThisMonth.format(FORMATTER)+" 00:00:00"; + + //查询所有有人在场的工程 + List listPro = mapper.getAllPro(lastMonth.toString()); + listPro.forEach(mapBeanVo -> { + //每个工程去循环生成 + //1.花名册 + List listRoster = mapper.getWorkerRosterData(lastMonth.toString(),startTime,endTime,mapBeanVo.getId()); + //2.农民工实名制工资信息报审表 + List listApply = mapper.getWorkerApplyData(lastMonth.toString(),mapBeanVo.getId()); + //3.考勤明细表 + List listAtt = mapper.getWorkerAttData(lastMonth.toString(),mapBeanVo.getId()); + List listAttDeal = dealAttData(listAtt,lastMonth); + //4.农民工资支付表 + // 数据串联生成工资支付数据 + // 通过workerId,proId将listApply、listAttDeal数据填充到listRoster + // 先将listApply按workerId和proId分组 + Map applyMap = listApply.stream() + .collect(Collectors.toMap( + item -> item.getWorkerId() + "_" + item.getProId(), + item -> item, + (existing, replacement) -> existing + )); + + // 将listAttDeal按workerId和proId分组 + Map attDealMap = listAttDeal.stream() + .collect(Collectors.toMap( + item -> item.getWorkerId() + "_" + item.getProId(), + item -> item, + (existing, replacement) -> existing + )); + + // 遍历listRoster,填充数据 + listRoster.forEach(roster -> { + String key = roster.getWorkerId() + "_" + roster.getProId(); + // 从listApply中查找匹配的数据 + ThreeTableOneRosterPo applyData = applyMap.get(key); + if (applyData != null) { + // 填充apply相关字段 + roster.setBankName(applyData.getBankName()); + roster.setBankCardCode(applyData.getBankCardCode()); + roster.setBankIdentifierCode(applyData.getBankIdentifierCode()); + roster.setContractId(applyData.getContractId()); + roster.setPriceWage(applyData.getPriceWage()); + roster.setPayment(applyData.getPayment()); + } + + // 从listAttDeal中查找匹配的数据 + ThreeTableOneRosterPo attDealData = attDealMap.get(key); + if (attDealData != null) { + // 填充attDeal相关字段 + roster.setAttendanceDay(attDealData.getAttendanceDay()); + roster.setAttendanceNum(attDealData.getAttendanceNum()); + roster.setRepairNum(attDealData.getRepairNum()); + roster.setCheckDay(attDealData.getCheckDay()); + // 根据实际需要填充其他字段 + } + // 计算工资,使用精度计算,如果有null返回0 + double calculatePayMoney = Optional.ofNullable(roster.getPriceWage()).orElse(0.0) * + Optional.ofNullable(roster.getAttendanceNum()).orElse(0); + roster.setPayMoney(calculatePayMoney); + roster.setDeductMoney(0.0); + roster.setActualMoney(calculatePayMoney); + }); + + }); + + + + //1.花名册 + + }catch (Exception e){ + logger.error("人员入场更新表失败,{}",e.getMessage()); + } + } + + private List dealAttData(List listAtt, YearMonth lastMonth) { + // 按照 workerId 分组 + Map> groupedByWorkerId = listAtt.stream() + .collect(Collectors.groupingBy(ThreeTableOneRosterPo::getWorkerId)); + // 获取上个月的所有日期 + List daysOfMonth = generateDaysOfMonth(lastMonth); + // 处理每个员工的考勤数据 + // 处理每个员工的考勤数据 + // 获取第一条数据作为基础数据 + // 处理考勤日数据 + // 将处理后的考勤日数据设置到基础数据中 + return groupedByWorkerId.entrySet().stream() + .map(entry -> { + Integer workerId = entry.getKey(); + List workerAttendance = entry.getValue(); + // 获取第一条数据作为基础数据 + ThreeTableOneRosterPo baseData = workerAttendance.get(0); + // 处理考勤日数据 + List attendanceDays = processWorkerAttendance(workerId, workerAttendance, daysOfMonth); + //计算出勤天数 + int attNum = 0; + int repairNum = 0; + for (WorkerAttDayVo attendanceDay : attendanceDays) { + if("1".equals(attendanceDay.getIsAtt())){ + attNum++; + if("1".equals(attendanceDay.getIsRepair())){ + repairNum++; + } + } + } + baseData.setAttendanceNum(attNum); + baseData.setRepairNum(repairNum); + baseData.setCheckDay(attNum-repairNum); + JSONArray o = (JSONArray)JSON.toJSON(attendanceDays); + // 将处理后的考勤日数据设置到基础数据中 + baseData.setAttendanceDay(JSON.toJSONString(o)); + return baseData; + }) + .collect(Collectors.toList()); + } + + /** + * 生成指定年月的所有日期列表 + * @param yearMonth 指定的年月 + * @return 日期列表,包含 yyyy-MM-dd 和 dd 两个字段的 MapBeanVo + */ + private List generateDaysOfMonth(YearMonth yearMonth) { + List days = new ArrayList<>(); + LocalDate firstDay = yearMonth.atDay(1); + LocalDate lastDay = yearMonth.atEndOfMonth(); + LocalDate currentDate = firstDay; + while (!currentDate.isAfter(lastDay)) { + MapBeanVo dayInfo = new MapBeanVo(); + dayInfo.setValue(currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + dayInfo.setKey(String.format("%02d", currentDate.getDayOfMonth())); + days.add(dayInfo); + currentDate = currentDate.plusDays(1); + } + return days; + } + + /** + * 处理单个员工的考勤数据 + * @param workerId 员工ID + * @param attendanceRecords 该员工的考勤记录 + * @param daysOfMonth 月份中的所有日期 + * @return 处理后的考勤数据列表 + */ + private List processWorkerAttendance(Integer workerId, + List attendanceRecords, List daysOfMonth) { + List result = new ArrayList<>(); + // 将该员工的考勤记录按日期分组,便于快速查找 + // 将该员工的考勤记录按日期分组,便于快速查找 + Map einByDate = attendanceRecords.stream() + .collect(Collectors.toMap( + ThreeTableOneRosterPo::getEinDay, + record -> record, + (existing, replacement) -> existing)); + // 遍历月份中的每一天 + for (MapBeanVo dayInfo : daysOfMonth) { + String dateStr = dayInfo.getValue(); + String dayStr = dayInfo.getKey(); + WorkerAttDayVo dayRecord = new WorkerAttDayVo(); + dayRecord.setDay(dayStr); + // 查找该日期是否有考勤记录 + ThreeTableOneRosterPo einForDate = einByDate.get(dateStr); + if (einForDate != null) { + // 存在考勤记录 + dayRecord.setIsEin("1"); // 在场 + // 检查是否有打卡记录 + if (einForDate.getAttDay() != null) { + dayRecord.setIsAtt("1"); // 打卡 + } + // 检查是否有补卡记录 + if ("1".equals(einForDate.getIsRepair())) { + dayRecord.setIsRepair("1"); // 补卡 + } + } else { + // 无考勤记录 + dayRecord.setIsEin("0"); // 不在场 + dayRecord.setIsAtt("0"); // 未打卡 + dayRecord.setIsRepair("0"); // 未补卡 + } + result.add(dayRecord); + } + return result; + } + + +} diff --git a/bonus-modules/bonus-job/src/main/resources/mapper/job/WorkerJobMapper.xml b/bonus-modules/bonus-job/src/main/resources/mapper/job/WorkerJobMapper.xml index af230c8..40c612b 100644 --- a/bonus-modules/bonus-job/src/main/resources/mapper/job/WorkerJobMapper.xml +++ b/bonus-modules/bonus-job/src/main/resources/mapper/job/WorkerJobMapper.xml @@ -94,4 +94,145 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{item.id} + + + + + + + + + +