Explorar el Código

考勤异常提醒

dzx hace 8 meses
padre
commit
65c13badbd

+ 38 - 34
src/main/java/com/xjrsoft/module/job/AttenDanceWarnNoticeTask.java

@@ -13,8 +13,6 @@ import com.xjrsoft.module.attendance.service.IAttendanceRuleCategoryService;
 import com.xjrsoft.module.concat.service.IXjrUserService;
 import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
 import com.xjrsoft.module.organization.service.IWeChatService;
-import com.xjrsoft.module.outint.service.IStudentOutInRecordService;
-import com.xjrsoft.module.outint.service.ITeacherOutInRecordService;
 import com.xjrsoft.module.system.entity.WechatMessageLog;
 import com.xjrsoft.module.system.service.IWechatMessageLogService;
 import com.xjrsoft.module.teacher.entity.XjrUser;
@@ -95,11 +93,6 @@ public class AttenDanceWarnNoticeTask {
             allUserStatus.put(userRelation.getUserId(), userRelation);
         }
 
-        //判断所有当前时间下,哪几条规则需要进行提醒
-        Map<Long, Integer> ruleDetailsJudgeMap = judgeExecuteNotice(now, ruleDetailsList);
-
-        //查询
-
         //根据规则中的用户id查询出所有绑定了微信的学生和教师
         if(allTodyRule.isEmpty()){
             log.info("未能查询出规则,不进行推送");
@@ -123,6 +116,9 @@ public class AttenDanceWarnNoticeTask {
             return;
         }
 
+        //判断所有当前时间下,哪几条规则需要进行提醒
+        Map<Long, Integer> ruleDetailsJudgeMap = judgeExecuteNotice(now, ruleDetailsList, recentlyTime);
+
         WechatMessageLog messageLog = new WechatMessageLog();
         messageLog.setTemplateId(wechatTemplate);
         messageLog.setSendTime(recentlyTime);
@@ -134,11 +130,6 @@ public class AttenDanceWarnNoticeTask {
             if(status == 0){
                 continue;
             }
-            //查询这个用户最新的考勤状态
-            AttendanceUserRelation userRelation = allUserStatus.get(xjrUser.getId());
-            if(userRelation.getAttendanceTime().toLocalDate().isEqual(now.toLocalDate()) && "到校".equals(userRelation.getAttendanceStatus())){
-                continue;
-            }
 
             WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
             weChatSendMessageDto.setUserId(xjrUser.getOpenId());
@@ -156,9 +147,17 @@ public class AttenDanceWarnNoticeTask {
 
             JSONObject const12 = new JSONObject();
             if(status == 1){
-                const12.put("value", "进校");
+                const12.put("value", "未打卡");
             }else{
-                const12.put("value", "出校");
+                const12.put("value", "待打卡");
+            }
+            //查询这个用户最新的考勤状态
+            AttendanceUserRelation userRelation = allUserStatus.get(xjrUser.getId());
+            if(userRelation != null
+                    && userRelation.getAttendanceTime() !=null
+                    && userRelation.getAttendanceTime().toLocalDate().isEqual(now.toLocalDate())
+                    && "到校".equals(userRelation.getAttendanceStatus())){
+                const12.put("value", "已打卡");
             }
             paramJson.put("const12", const12);
 
@@ -177,53 +176,58 @@ public class AttenDanceWarnNoticeTask {
      * 判断所有规则,哪些需要发送
      * @param judgeTime
      * @param ruleDetailsList
-     * @return 0:不需要提醒,-1:待打卡,1:未打卡
+     * @return 0:不需要提醒,1:未打卡,2:待打卡
      */
-    Map<Long, Integer> judgeExecuteNotice(LocalDateTime judgeTime, List<AttendanceRuleDetails> ruleDetailsList){
+    Map<Long, Integer> judgeExecuteNotice(LocalDateTime judgeTime, List<AttendanceRuleDetails> ruleDetailsList, LocalDateTime recentlyTime){
         Map<Long, Integer> result = new HashMap<>();
         for (AttendanceRuleDetails ruleDetails : ruleDetailsList) {
-            if(ruleDetails.getIsAllowInOutSchool() != null && ruleDetails.getIsAllowInOutSchool() != 1
+            if(ruleDetails.getIsAllowInOutSchool() != null && ruleDetails.getIsAllowInOutSchool() == 1
                     && ruleDetails.getIsAttendance() != null && ruleDetails.getIsAttendance() == 1){
                 if(ruleDetails.getAmStartTime() != null){
                     LocalDateTime amStartTime = judgeTime.with(ruleDetails.getAmStartTime().toLocalTime());
-                    long amBetween = ChronoUnit.MINUTES.between(judgeTime, amStartTime);
-                    if(amBetween == ruleDetails.getAgoMinutes()){
-                        result.put(ruleDetails.getId(), - 1);
-                    }else if(amBetween == ruleDetails.getOverMinutes()){
-                        result.put(ruleDetails.getId(), - 1);
+                    if(recentlyTime.isEqual(amStartTime)){
+                        Long amBetween = ChronoUnit.MINUTES.between(judgeTime, amStartTime);
+                        if(judgeTime.isBefore(amStartTime) && amBetween >= ruleDetails.getAgoMinutes() - 1 && amBetween <= ruleDetails.getAgoMinutes() + 1){//相差分钟数小于0
+                            result.put(ruleDetails.getId(), 1);
+                        }else if(judgeTime.isAfter(amStartTime) && amBetween >= ruleDetails.getOverMinutes() - 1 && amBetween <= ruleDetails.getOverMinutes() + 1){
+                            result.put(ruleDetails.getId(), 2);
+                        }
                     }
                 }
                 if(ruleDetails.getPmStartTime() != null){
                     LocalDateTime pmStartTime = judgeTime.with(ruleDetails.getPmStartTime().toLocalTime());
-                    long pmBetween = ChronoUnit.MINUTES.between(judgeTime, pmStartTime);
-                    if(pmBetween == ruleDetails.getAgoMinutes()){
-                        result.put(ruleDetails.getId(), - 1);
-                    }else if(pmBetween == ruleDetails.getOverMinutes()){
-                        result.put(ruleDetails.getId(), - 1);
+                    if(recentlyTime.isEqual(pmStartTime)){
+                        Long pmBetween = ChronoUnit.MINUTES.between(judgeTime, pmStartTime);
+                        if(judgeTime.isBefore(pmStartTime) && pmBetween >= ruleDetails.getAgoMinutes() - 1 && pmBetween <= ruleDetails.getAgoMinutes() + 1){
+                            result.put(ruleDetails.getId(), 1);
+                        }else if(judgeTime.isAfter(pmStartTime) && pmBetween >= ruleDetails.getOverMinutes() - 1 && pmBetween <= ruleDetails.getOverMinutes() + 1){
+                            result.put(ruleDetails.getId(), 2);
+                        }
                     }
                 }
 
                 if(ruleDetails.getEveningStartTime() != null){
                     LocalDateTime eveningStartTime = judgeTime.with(ruleDetails.getEveningStartTime().toLocalTime());
-                    long eveningBetween = ChronoUnit.MINUTES.between(judgeTime, eveningStartTime);
-                    if(eveningBetween == ruleDetails.getAgoMinutes()){
-                        result.put(ruleDetails.getId(), - 1);
-                    }else if(eveningBetween == ruleDetails.getOverMinutes()){
-                        result.put(ruleDetails.getId(), - 1);
+                    if(recentlyTime.isEqual(eveningStartTime)){
+                        Long eveningBetween = ChronoUnit.MINUTES.between(judgeTime, eveningStartTime);
+                        if(judgeTime.isBefore(eveningStartTime) && eveningBetween >= ruleDetails.getAgoMinutes() - 1 && eveningBetween <= ruleDetails.getAgoMinutes() + 1){
+                            result.put(ruleDetails.getId(), 1);
+                        }else if(judgeTime.isAfter(eveningStartTime)  && eveningBetween >= ruleDetails.getOverMinutes() - 1 && eveningBetween <= ruleDetails.getOverMinutes() + 1){
+                            result.put(ruleDetails.getId(), 2);
+                        }
                     }
                 }
 
-
                 if(!result.containsKey(ruleDetails.getId())){
                     result.put(ruleDetails.getId(), 0);
                 }
             }else{
                 result.put(ruleDetails.getId(), 0);
             }
-
         }
         return result;
     }
+
     /**
      * 查询出所有用户信息(openId不为空的)
      * @param userIds 需要插叙的userid

+ 252 - 9
src/test/java/com/xjrsoft/module/job/AttenDanceWarnNoticeTaskTest.java

@@ -1,30 +1,273 @@
 package com.xjrsoft.module.job;
 
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.xjrsoft.common.utils.WeChatUtil;
+import com.xjrsoft.module.attendance.entity.AttendanceRuleDetails;
+import com.xjrsoft.module.attendance.entity.AttendanceUserRelation;
+import com.xjrsoft.module.attendance.mapper.AttendanceUserRelationMapper;
+import com.xjrsoft.module.attendance.service.IAttendanceRuleCategoryService;
+import com.xjrsoft.module.concat.service.IXjrUserService;
+import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
+import com.xjrsoft.module.organization.service.IWeChatService;
+import com.xjrsoft.module.system.entity.WechatMessageLog;
+import com.xjrsoft.module.system.service.IWechatMessageLogService;
+import com.xjrsoft.module.teacher.entity.XjrUser;
 import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
 
-import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.LocalTime;
-
-import static org.junit.jupiter.api.Assertions.*;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * @author dzx
  * @date 2024/6/4
  */
+@SpringBootTest
 class AttenDanceWarnNoticeTaskTest {
 
 
+    @Autowired
+    private IAttendanceRuleCategoryService categoryService;
+
+    @Autowired
+    private IXjrUserService userService;
+
+    @Autowired
+    private AttendanceUserRelationMapper relationMapper;
+
+    @Autowired
+    private IWeChatService weChatService;
+
+    @Autowired
+    private WeChatUtil weChatUtil;
+
+    @Autowired
+    private IWechatMessageLogService wechatMessageLogService;
+
     @Test
-    void test(){
+    public void RefreshConnectionPool() {
+        String active = SpringUtil.getActiveProfile();
+        if(!"dev".equals(active)){
+            return;
+        }
+        //获取当前时间
         LocalDateTime now = LocalDateTime.now();
-        System.out.println(now.getDayOfWeek().name());
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        String timeStr = now.format(formatter);
+
+        //查询今天所有的考勤规则
+        List<AttendanceRuleDetails> ruleDetailsList = categoryService.getTodayRules();
+        Map<Long, AttendanceRuleDetails> ruleDetailsMap = new HashMap<>();
+        for (AttendanceRuleDetails ruleDetail : ruleDetailsList) {
+            ruleDetailsMap.put(ruleDetail.getAttendanceRuleCategoryId(), ruleDetail);
+        }
+
+        //查询出所有人的考勤规则
+        List<AttendanceUserRelation> relationList = relationMapper.selectList(
+                new QueryWrapper<AttendanceUserRelation>().lambda()
+                        .eq(AttendanceUserRelation::getDeleteMark, 0)
+        );
+        Map<Long, AttendanceRuleDetails> allTodyRule = new HashMap<>();
+        for (AttendanceUserRelation userRelation : relationList) {
+            allTodyRule.put(userRelation.getUserId(), ruleDetailsMap.get(userRelation.getAttendanceRuleCategoryId()));
+        }
+
+        Map<Long, AttendanceUserRelation> allUserStatus = new HashMap<>();
+        for (AttendanceUserRelation userRelation : relationList) {
+            allUserStatus.put(userRelation.getUserId(), userRelation);
+        }
+
+        //根据规则中的用户id查询出所有绑定了微信的学生和教师
+        if(allTodyRule.isEmpty()){
+            System.out.println("未能查询出规则,不进行推送");
+            return;
+        }
+
+        //获取最近的时间
+        LocalDateTime recentlyTime = getRecentlyTime(ruleDetailsList, now);
+        if(!recentlyTime.isEqual(now)){
+            System.out.println("未到时间,不进行推送");
+//            return;
+        }
+        String wechatTemplate = weChatUtil.getAttenDanceWarnTemplate();
+//        WechatMessageLog log = wechatMessageLogService.getOne(
+//                new QueryWrapper<WechatMessageLog>().lambda()
+//                        .select(WechatMessageLog.class, x -> VoToColumnUtil.fieldsToColumns(WechatMessageLog.class).contains(x.getProperty()))
+//                        .eq(WechatMessageLog::getSendTime, recentlyTime)
+//                        .eq(WechatMessageLog::getTemplateId, wechatTemplate)
+//        );
+//        if(log != null){//已经推送过,不再进行推送
+////            return;
+//        }
+
+        //判断所有当前时间下,哪几条规则需要进行提醒
+        Map<Long, Integer> ruleDetailsJudgeMap = judgeExecuteNotice(now, ruleDetailsList, recentlyTime);
+
+        WechatMessageLog messageLog = new WechatMessageLog();
+        messageLog.setTemplateId(wechatTemplate);
+        messageLog.setSendTime(recentlyTime);
+
+        List<XjrUser> userList = getUserList(allTodyRule.keySet());
+        for (XjrUser xjrUser : userList) {
+            AttendanceRuleDetails ruleDetails = allTodyRule.get(xjrUser.getId());
+            Integer status = ruleDetailsJudgeMap.get(ruleDetails.getId());
+            if(status == 0){
+                continue;
+            }
+
+            WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
+            weChatSendMessageDto.setUserId(xjrUser.getOpenId());
+            weChatSendMessageDto.setTemplateId(wechatTemplate);
+            weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
+            JSONObject paramJson = new JSONObject();
+
+            JSONObject thing8 = new JSONObject();
+            thing8.put("value", xjrUser.getName());
+            paramJson.put("thing8", thing8);
+
+            JSONObject time9 = new JSONObject();
+            time9.put("value", timeStr);
+            paramJson.put("time9", time9);
+
+            JSONObject const12 = new JSONObject();
+            if(status == 1){
+                const12.put("value", "未打卡");
+            }else{
+                const12.put("value", "待打卡");
+            }
+            //查询这个用户最新的考勤状态
+            AttendanceUserRelation userRelation = allUserStatus.get(xjrUser.getId());
+            if(userRelation != null
+                    && userRelation.getAttendanceTime() !=null
+                    && userRelation.getAttendanceTime().toLocalDate().isEqual(now.toLocalDate())
+                    && "到校".equals(userRelation.getAttendanceStatus())){
+                const12.put("value", "已打卡");
+            }
+            paramJson.put("const12", const12);
+
+            weChatSendMessageDto.setContent(paramJson);
+            weChatService.sendTemplateMessage(weChatSendMessageDto);
+        }
+
+        messageLog.setCreateDate(new Date());
+        messageLog.setContent("消息推送人数:" + userList.size());
+        wechatMessageLogService.save(messageLog);
+
+    }
+
+    /**
+     * 判断所有规则,哪些需要发送
+     * @param judgeTime
+     * @param ruleDetailsList
+     * @return 0:不需要提醒,1:未打卡,2:待打卡
+     */
+    Map<Long, Integer> judgeExecuteNotice(LocalDateTime judgeTime, List<AttendanceRuleDetails> ruleDetailsList, LocalDateTime recentlyTime){
+        Map<Long, Integer> result = new HashMap<>();
+        for (AttendanceRuleDetails ruleDetails : ruleDetailsList) {
+            if(ruleDetails.getIsAllowInOutSchool() != null && ruleDetails.getIsAllowInOutSchool() == 1
+                    && ruleDetails.getIsAttendance() != null && ruleDetails.getIsAttendance() == 1){
+                if(ruleDetails.getAmStartTime() != null){
+                    LocalDateTime amStartTime = judgeTime.with(ruleDetails.getAmStartTime().toLocalTime());
+                    if(recentlyTime.isEqual(amStartTime)){
+                        Long amBetween = ChronoUnit.MINUTES.between(judgeTime, amStartTime);
+                        if(judgeTime.isBefore(amStartTime) && amBetween >= ruleDetails.getAgoMinutes() - 1 && amBetween <= ruleDetails.getAgoMinutes() + 1){//相差分钟数小于0
+                            result.put(ruleDetails.getId(), 1);
+                        }else if(judgeTime.isAfter(amStartTime) && amBetween >= ruleDetails.getOverMinutes() - 1 && amBetween <= ruleDetails.getOverMinutes() + 1){
+                            result.put(ruleDetails.getId(), 2);
+                        }
+                    }
+                }
+                if(ruleDetails.getPmStartTime() != null){
+                    LocalDateTime pmStartTime = judgeTime.with(ruleDetails.getPmStartTime().toLocalTime());
+                    if(recentlyTime.isEqual(pmStartTime)){
+                        Long pmBetween = ChronoUnit.MINUTES.between(judgeTime, pmStartTime);
+                        if(judgeTime.isBefore(pmStartTime) && pmBetween >= ruleDetails.getAgoMinutes() - 1 && pmBetween <= ruleDetails.getAgoMinutes() + 1){
+                            result.put(ruleDetails.getId(), 1);
+                        }else if(judgeTime.isAfter(pmStartTime) && pmBetween >= ruleDetails.getOverMinutes() - 1 && pmBetween <= ruleDetails.getOverMinutes() + 1){
+                            result.put(ruleDetails.getId(), 2);
+                        }
+                    }
+                }
+
+                if(ruleDetails.getEveningStartTime() != null){
+                    LocalDateTime eveningStartTime = judgeTime.with(ruleDetails.getEveningStartTime().toLocalTime());
+                    if(recentlyTime.isEqual(eveningStartTime)){
+                        Long eveningBetween = ChronoUnit.MINUTES.between(judgeTime, eveningStartTime);
+                        if(judgeTime.isBefore(eveningStartTime) && eveningBetween >= ruleDetails.getAgoMinutes() - 1 && eveningBetween <= ruleDetails.getAgoMinutes() + 1){
+                            result.put(ruleDetails.getId(), 1);
+                        }else if(judgeTime.isAfter(eveningStartTime)  && eveningBetween >= ruleDetails.getOverMinutes() - 1 && eveningBetween <= ruleDetails.getOverMinutes() + 1){
+                            result.put(ruleDetails.getId(), 2);
+                        }
+                    }
+                }
+
+                if(!result.containsKey(ruleDetails.getId())){
+                    result.put(ruleDetails.getId(), 0);
+                }
+            }else{
+                result.put(ruleDetails.getId(), 0);
+            }
+        }
+        return result;
+    }
+    /**
+     * 查询出所有用户信息(openId不为空的)
+     * @param userIds 需要插叙的userid
+     * @return 用户信息
+     */
+    List<XjrUser> getUserList(Set<Long> userIds){
+        return userService.list(
+                new QueryWrapper<XjrUser>().lambda()
+                        .in(XjrUser::getId, userIds)
+//                        .isNotNull(XjrUser::getOpenId)
+        );
+    }
 
-        LocalTime amStartTime = LocalTime.of(8,0,0);
-        System.out.println(now.with(amStartTime));
+    LocalDateTime getRecentlyTime(List<AttendanceRuleDetails> ruleDetails, LocalDateTime now){
+        List<LocalDateTime> result = new ArrayList<>();
+        for (AttendanceRuleDetails ruleDetail : ruleDetails) {
+            if(ruleDetail.getIsAllowInOutSchool() != null && ruleDetail.getIsAllowInOutSchool() == 1
+                    && ruleDetail.getIsAttendance() != null && ruleDetail.getIsAttendance() == 1){
+                if(ruleDetail.getAmStartTime() != null){
+                    LocalDateTime amStartTime = now.with(ruleDetail.getAmStartTime().toLocalTime());
+                    result.add(amStartTime);
+                }
+                if(ruleDetail.getPmStartTime() != null){
+                    LocalDateTime pmStartTime = now.with(ruleDetail.getPmStartTime().toLocalTime());
+                    result.add(pmStartTime);
+                }
 
-        System.out.println(1L == 1);
+                if(ruleDetail.getEveningStartTime() != null){
+                    LocalDateTime eveningStartTime = now.with(ruleDetail.getEveningStartTime().toLocalTime());
+                    result.add(eveningStartTime);
+                }
+            }
+        }
+        if(result.isEmpty()){
+            return null;
+        }
+        Map<Long, LocalDateTime> timeMap = new HashMap<>();
+        for (LocalDateTime localDateTime : result) {
+            long between = ChronoUnit.SECONDS.between(now, localDateTime);
+            timeMap.put(Math.abs(between), localDateTime);
+        }
+        List<Long> collect = timeMap.keySet().stream().collect(Collectors.toList());
+        Collections.sort(collect, Long::compare);
 
+        return timeMap.get(collect.get(0));
     }
 
 }