package com.ruoyi.task; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Console; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import com.ruoyi.bgt.domain.BgtProjectRecruit; import com.ruoyi.bgt.domain.BgtProjectRecruitApply; import com.ruoyi.bgt.domain.dto.BgtScoreDTO; import com.ruoyi.bgt.service.IBgtMessageService; import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService; import com.ruoyi.bgt.service.IBgtProjectRecruitService; import com.ruoyi.common.constants.BgtMessageConstant; import com.ruoyi.common.constants.WgzAndBgtMessageConstant; import com.ruoyi.common.enums.RecruitApplyStatus; import com.ruoyi.common.enums.RecruitStatus; import com.ruoyi.fbs.domain.FbsProjectTask; import com.ruoyi.fbs.service.IFbsProjectTaskService; import com.ruoyi.wgz.domain.WgzAttendance; import com.ruoyi.wgz.domain.WgzLeave; import com.ruoyi.wgz.domain.WgzMessage; import com.ruoyi.wgz.domain.WgzScoreRecord; import com.ruoyi.wgz.service.IWgzAttendanceService; import com.ruoyi.wgz.service.IWgzLeaveService; import com.ruoyi.wgz.service.IWgzMessageService; import com.ruoyi.wgz.service.IWgzScoreRecordService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; import static com.ruoyi.common.constants.WgzAndBgtMessageConstant.*; /** * 业务定时任务 * * @author ruoyi businessTask.leave */ @Slf4j @Component("businessTask") public class BusinessTask { @Autowired private IBgtProjectRecruitService recruitService; @Autowired private IBgtProjectRecruitApplyService recruitApplyService; @Autowired private IBgtProjectRecruitApplyService iBgtProjectRecruitApplyService; @Autowired private IFbsProjectTaskService iFbsProjectTaskService; @Autowired private IWgzMessageService iWgzMessageService; @Autowired private IWgzAttendanceService iWgzAttendanceService; @Autowired private IWgzLeaveService iWgzLeaveService; @Autowired private IWgzScoreRecordService wgzScoreRecordService; @Autowired private IBgtMessageService iBgtMessageService; @Autowired private IBgtProjectRecruitService iBgtProjectRecruitService; public void ryNoParams() { Console.log("-------------------------------------------------------------------------"); Console.log("测试任务执行了"); Console.log("-------------------------------------------------------------------------"); } /** * 招工任务招工时间结束自动拒绝未选择的务工者 */ public void recruitRefuse() { Console.log("开始招工拒绝任务"); List status = Arrays.asList(RecruitApplyStatus.SIGN_UP.getCode(), RecruitApplyStatus.BGT_PASS.getCode(), RecruitApplyStatus.WGZ_PASS.getCode()); List recruitList = recruitService.list(Wrappers.lambdaQuery() .lt(BgtProjectRecruit::getRecruitEndTime, LocalDate.now())); if(CollectionUtil.isNotEmpty(recruitList)){ List recruitIds = recruitList.stream().map(BgtProjectRecruit::getId).collect(Collectors.toList()); List list = recruitApplyService.list(Wrappers.lambdaQuery() .in(BgtProjectRecruitApply::getRecruitId, recruitIds) .in(BgtProjectRecruitApply::getStatus, status) ); List recruitApplyIds = list.stream().map(BgtProjectRecruitApply::getId).collect(Collectors.toList()); recruitApplyService.lambdaUpdate() .in(BgtProjectRecruitApply::getId, recruitApplyIds) .set(BgtProjectRecruitApply::getStatus,RecruitApplyStatus.BGT_REFUSE.getCode()) .update(); recruitService.lambdaUpdate().in(BgtProjectRecruit::getId, recruitIds) .set(BgtProjectRecruit::getStatus,RecruitStatus.OVERDUE.getCode()).update(); //处理消息操作状态 List bgtMessageHandleIds = list.stream().filter(vo->RecruitApplyStatus.SIGN_UP.getCode().equals(vo.getStatus())).map(BgtProjectRecruitApply::getId).collect(Collectors.toList()); iBgtMessageService.operationBatch(bgtMessageHandleIds,SqlHelper.table(BgtProjectRecruitApply.class).getTableName(), BgtMessageConstant.BGT_LARGE_OTHER, BgtMessageConstant.BGT_SMALL_SIGN_UP ); List wgzMessageList = list.stream().filter(vo->RecruitApplyStatus.BGT_PASS.getCode().equals(vo.getStatus())).collect(Collectors.toList()); iWgzMessageService.operationBatchSignUp(wgzMessageList); //发送消息 iWgzMessageService.operationBatchReject(list); } Console.log("招工拒绝任务结束,此次拒绝任务个数:"+recruitList.size()); } /** * 务工者同意并到了进场时间修改状态为进场 */ public void entry() { Console.log("开始招工进场任务"); // recruitApplyService.lambdaUpdate() // .le(BgtProjectRecruitApply::getEntryTime, LocalDate.now()) // .eq(BgtProjectRecruitApply::getStatus,RecruitApplyStatus.WGZ_PASS.getCode()) // .set(BgtProjectRecruitApply::getStatus,RecruitApplyStatus.BGT_REFUSE.getCode()) // .update(); Console.log("招工进场任务结束!"); } /** * 自动给两个月前的任务下的人员默认5分的评价 */ public void score() { Console.log("开始进行务工评价任务"); //搜索时间在两个月前的已完结的任务 List taskList = iFbsProjectTaskService.list(Wrappers.lambdaQuery() .eq(FbsProjectTask::getStatus, "2") .lt(FbsProjectTask::getTaskBeginTime, LocalDate.now().plusMonths(-2))); List taskIds = taskList.stream().map(FbsProjectTask::getId).collect(Collectors.toList()); if(CollectionUtil.isNotEmpty(taskIds)){ //任务下的招工 List recruitList = recruitService.list(Wrappers.lambdaQuery() .in(BgtProjectRecruit::getTaskId, taskIds)); Map map = recruitList.stream().collect(Collectors.toMap(BgtProjectRecruit::getId, BgtProjectRecruit::getUserId)); List recruitIds = recruitList.stream().map(BgtProjectRecruit::getId).collect(Collectors.toList()); if(CollectionUtil.isNotEmpty(recruitIds)){ //招工下的人员 List applyList = recruitApplyService.list(Wrappers.lambdaQuery() .in(BgtProjectRecruitApply::getRecruitId, recruitIds)); //筛选已离场的 List outList = applyList.stream().filter(apply -> apply.getStatus().equals(RecruitApplyStatus.OUT_WORK.getCode())).collect(Collectors.toList()); for (BgtProjectRecruitApply bgtProjectRecruitApply : outList) { WgzScoreRecord byUserIdAndRecruitApplyId = wgzScoreRecordService.getByUserIdAndRecruitApplyId(bgtProjectRecruitApply.getUserId(), bgtProjectRecruitApply.getId()); if (byUserIdAndRecruitApplyId == null) { BgtScoreDTO bgtScoreDTO = new BgtScoreDTO(); bgtScoreDTO.setScore(new BigDecimal(5)); bgtScoreDTO.setRecruitId(bgtProjectRecruitApply.getRecruitId()); bgtScoreDTO.setRecruitApplyId(bgtProjectRecruitApply.getId()); bgtScoreDTO.setUserId(bgtProjectRecruitApply.getUserId()); bgtScoreDTO.setScoreBy(map.get(bgtProjectRecruitApply.getRecruitId())); bgtScoreDTO.setContent("默认评分"); bgtScoreDTO.setCreateBy("系统"); bgtScoreDTO.setUpdateBy("系统"); iBgtProjectRecruitApplyService.score(bgtScoreDTO); } } } } Console.log("务工评价任务结束!"); } /** * 上班缺卡 */ public void workCardShortage(){ //1、获取所有正在进行中的任务 List ongoingTask = iFbsProjectTaskService.findOngoingTask(); if(CollectionUtil.isEmpty(ongoingTask)){ return; } //2、获取所有招工信息 List taskIds = new ArrayList<>(); for (FbsProjectTask fbsProjectTask : ongoingTask) { taskIds.add(fbsProjectTask.getId()); } List applyList = recruitService.list( Wrappers.lambdaQuery() .in(BgtProjectRecruit::getTaskId, taskIds) ); //3、获取每个招工下面的员工,然后判断他们是否上班缺卡 LocalDate now = LocalDate.now(); List lists = new ArrayList<>(); List messages = new ArrayList<>(); Map mp = new HashMap<>(); mp.put("data",now.toString()); for (BgtProjectRecruit recruit : applyList) { List recruitApply = iBgtProjectRecruitApplyService.list( Wrappers.lambdaQuery() .eq(BgtProjectRecruitApply::getRecruitId, recruit.getId()) .eq(BgtProjectRecruitApply::getStatus, "5") ); for (BgtProjectRecruitApply by : recruitApply) { int count = iWgzAttendanceService.count( Wrappers.lambdaQuery() .eq(WgzAttendance::getUserId, by.getUserId()) .eq(WgzAttendance::getRecruitId, by.getRecruitId()) .eq(WgzAttendance::getDate, now) ); //表示有上班缺卡,添加缺卡信息 if (count == 0) { //添加缺卡信息 WgzAttendance attendance = new WgzAttendance() .setRecruitId(by.getRecruitId()) .setApplyKey(by.getId()) .setUserId(by.getUserId()) .setDailyWage(recruit.getRecruitAmount()) .setDate(now) .setMissedIn(1) .setExceptionType("3,").setUpdateBy("系统").setCreateBy("系统"); lists.add(attendance); //添加消息提醒 WgzMessage wgzMessage = new WgzMessage(). setSenderType(USERTYPE_SYSTEM). setRecipientType(WgzAndBgtMessageConstant.USERTYPE_WGZ). setRecipientId(by.getUserId()). setHeadline(WgzAndBgtMessageConstant.wgzMessage(mp,"113")). setSubheading(WgzAndBgtMessageConstant.wgzMessage(mp,"114")). // setTableId(apply.getId()). // setTableName(SqlHelper.table(BgtProjectRecruitApply.class).getTableName()). setMessageLargeType(LARGE_OTHER). setMessageSmallType(SMALL_SYSTEM).setUpdateBy("系统").setCreateBy("系统"); messages.add(wgzMessage); } } } //4、批量添加缺卡信息 Boolean b = iWgzAttendanceService.addAMissingCardRecord(lists); if (!b){ log.error("批量添加上班缺卡信息失败!"); } //5、批量添加缺卡消息 boolean b1 = iWgzMessageService.saveBatch(messages); if (!b1){ log.error("批量添加上班缺卡消息失败!"); } } /** * 下班缺卡 */ public void missingCard(){ //1、获取所有正在进行中的任务 List ongoingTask = iFbsProjectTaskService.findOngoingTask(); if(CollectionUtil.isEmpty(ongoingTask)){ return; } //2、获取所有招工信息 List taskIds = new ArrayList<>(); for (FbsProjectTask fbsProjectTask : ongoingTask) { taskIds.add(fbsProjectTask.getId()); } List applyList = recruitService.list( Wrappers.lambdaQuery() .in(BgtProjectRecruit::getTaskId, taskIds) ); //3、获取每个招工下面的员工,然后判断他们是否上班缺卡 LocalDate now = LocalDate.now(); List lists = new ArrayList<>(); List messages = new ArrayList<>(); Map mp = new HashMap<>(); mp.put("data",now.toString()); for (BgtProjectRecruit recruit : applyList) { List recruitApply = iBgtProjectRecruitApplyService.list( Wrappers.lambdaQuery() .eq(BgtProjectRecruitApply::getRecruitId, recruit.getId()) .eq(BgtProjectRecruitApply::getStatus, "5") ); for (BgtProjectRecruitApply by : recruitApply) { WgzAttendance one = iWgzAttendanceService.getOne( Wrappers.lambdaQuery() .eq(WgzAttendance::getUserId, by.getUserId()) .eq(WgzAttendance::getRecruitId, by.getRecruitId()) .eq(WgzAttendance::getDate, now) .isNull(WgzAttendance::getLeaveMarkId) .isNull(WgzAttendance::getClockOutTime) ); //表示有下班缺卡,添加缺卡信息 if (one != null) { //添加缺卡信息 WgzAttendance attendance = new WgzAttendance() .setId(one.getId()) .setMissedOut(1) .setExceptionType(one.getExceptionType()+"4,").setUpdateBy("系统").setCreateBy("系统"); lists.add(attendance); //添加消息提醒 WgzMessage wgzMessage = new WgzMessage(). setSenderType(USERTYPE_SYSTEM). setRecipientType(USERTYPE_WGZ). setRecipientId(by.getUserId()). setHeadline(WgzAndBgtMessageConstant.wgzMessage(mp,"115")). setSubheading(WgzAndBgtMessageConstant.wgzMessage(mp,"116")). // setTableId(apply.getId()). // setTableName(SqlHelper.table(BgtProjectRecruitApply.class).getTableName()). setMessageLargeType(LARGE_OTHER). setMessageSmallType(SMALL_SYSTEM).setUpdateBy("系统").setCreateBy("系统"); messages.add(wgzMessage); } } } //4、批量添加缺卡信息 boolean b = iWgzAttendanceService.updateBatchById(lists); if (!b){ log.error("批量修改下班缺卡消息失败!"); } //5、批量添加缺卡消息 boolean b1 = iWgzMessageService.saveBatch(messages); if (!b1){ log.error("批量添加下班缺卡消息失败!"); } } /** * 请假 */ @Transactional public void leave(){ List updataList = new ArrayList<>(); List attendanceList = new ArrayList<>(); List messagesList = new ArrayList<>(); LocalDate now = LocalDate.now(); Map mp = new HashMap<>(); mp.put("data",now.toString()); //1、获取所有正在审核的请假消息,如果超时就批量改变状态为请假超时 List wgzLeaveList = iWgzLeaveService.list( Wrappers.lambdaQuery() .in(WgzLeave::getAuditorType, new String[]{"0", "1"}) ); for (WgzLeave wgzLeave : wgzLeaveList) { LocalDate startTime = wgzLeave.getStartTime().toLocalDate(); // startTime大于等于now,那么就修改状态为请假超时 if (startTime.isEqual(now) || startTime.isAfter(now)){ // WgzLeave st = new WgzLeave() // .setId(wgzLeave.getId()) // .setAuditorType("5"); wgzLeave.setAuditorType("5"); updataList.add(wgzLeave); //组装请假超时的消息 WgzMessage wgzMessage = new WgzMessage(). setSenderType(USERTYPE_SYSTEM). setRecipientType(WgzAndBgtMessageConstant.USERTYPE_WGZ). setRecipientId(wgzLeave.getUserId()). setHeadline(WgzAndBgtMessageConstant.wgzMessage(mp,"117")). setSubheading(WgzAndBgtMessageConstant.wgzMessage(mp,"118")). setMessageLargeType(LARGE_OTHER). setMessageSmallType(SMALL_SYSTEM); wgzMessage.setUpdateBy("系统").setCreateBy("系统"); messagesList.add(wgzMessage); //状态超时需要把对应消息的状态变更为【不需要操作】 BgtProjectRecruit recruit = iBgtProjectRecruitService.getById(wgzLeave.getRecruitId()); iBgtMessageService.operation( USERTYPE_WGZ, wgzLeave.getUserId(), USERTYPE_BGT, recruit.getUserId(), wgzLeave.getId(), SqlHelper.table(WgzLeave.class).getTableName() ); } } //3、发送请假超时的消息,然后批量修改请假消息的状态为超时且发送超时消息 if (!updataList.isEmpty()){ iWgzLeaveService.updateBatchById(updataList); iWgzMessageService.saveBatch(messagesList); } //4、获取所有审批成功的请假消息,然后批量新增请假打卡数据到考勤表(如若需要日薪就需要连表查询) List wgzLeaveListTwo = iWgzLeaveService.list( Wrappers.lambdaQuery() .eq(WgzLeave::getAuditorType, "2") ); for (WgzLeave wgzLeave : wgzLeaveListTwo) { //获取请假的具体天数(目前的请假是全天,没有分时间段) List formattedDates = getFormattedDates(wgzLeave.getStartTime(), wgzLeave.getEndTime()); //业务逻辑 for (LocalDate formattedDate : formattedDates) { //如果formattedDate小于当前日期,就跳过 if (formattedDate.isBefore(now)){ continue; } //查询当前人、当前项目、当前打卡时间是否存在,如若存在就跳过 int count = iWgzAttendanceService.count( Wrappers.lambdaQuery() .eq(WgzAttendance::getUserId, wgzLeave.getUserId()) .eq(WgzAttendance::getRecruitId, wgzLeave.getRecruitId()) .eq(WgzAttendance::getDate, formattedDate) ); if (count > 0){ continue; } //获取到请假天数 WgzAttendance wgzAttendance = new WgzAttendance(). setRecruitId(wgzLeave.getRecruitId()). setApplyKey(wgzLeave.getApplyKey()). setUserId(wgzLeave.getUserId()). setLeaveMarkId(wgzLeave.getId()). setDate(formattedDate). setExceptionType("7,").setUpdateBy("系统").setCreateBy("系统"); attendanceList.add(wgzAttendance); } } if (!attendanceList.isEmpty()){ iWgzAttendanceService.addAMissingCardRecord(attendanceList); } } /** * 获取两个LocalDateTime的年月日 * * 2025-02-24 17:35:20 * 2025-02-24 17:35:20 * 得到2025-02-24 * 2025-02-24 17:35:20 * 2025-02-25 17:35:20 * 得到2025-02-24 2025-02-25 */ public static List getFormattedDates(LocalDateTime dateTime1, LocalDateTime dateTime2) { // 获取两个 LocalDateTime 对象对应的 LocalDate 对象 LocalDate localDate1 = dateTime1.toLocalDate(); LocalDate localDate2 = dateTime2.toLocalDate(); // 创建一个集合来存储不同的日期 List dates = new ArrayList<>(); if (!dates.contains(localDate1)) { dates.add(localDate1); } if (!dates.contains(localDate2)) { dates.add(localDate2); } // 定义日期格式化器 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 将日期集合格式化为字符串并使用空格连接 return dates; } }