Przeglądaj źródła

Merge branch 'pre'

dzx 1 rok temu
rodzic
commit
12bf4646b7
24 zmienionych plików z 776 dodań i 163 usunięć
  1. 17 5
      src/main/java/com/xjrsoft/module/hikvision/controller/EventController.java
  2. 53 43
      src/main/java/com/xjrsoft/module/hikvision/util/OutInRecordUtil.java
  3. 39 8
      src/main/java/com/xjrsoft/module/job/AttenDanceWarnNoticeTask.java
  4. 89 41
      src/main/java/com/xjrsoft/module/job/AttendanceMessageTask.java
  5. 5 1
      src/main/java/com/xjrsoft/module/student/controller/PbSemesterConfigController.java
  6. 65 0
      src/main/java/com/xjrsoft/module/system/entity/WechatMessageLog.java
  7. 16 0
      src/main/java/com/xjrsoft/module/system/mapper/WechatMessageLogMapper.java
  8. 34 0
      src/main/java/com/xjrsoft/module/system/service/IWechatMessageLogService.java
  9. 43 0
      src/main/java/com/xjrsoft/module/system/service/impl/WechatMessageLogServiceImpl.java
  10. 0 3
      src/main/java/com/xjrsoft/module/teacher/mapper/FaceImportMapper.java
  11. 8 10
      src/main/java/com/xjrsoft/module/textbook/controller/TextbookController.java
  12. 6 0
      src/main/java/com/xjrsoft/module/textbook/dto/AddTextbookDto.java
  13. 4 4
      src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookServiceImpl.java
  14. 3 3
      src/main/resources/application-dev.yml
  15. 4 4
      src/main/resources/application-pre.yml
  16. 1 1
      src/main/resources/application-prod.yml
  17. 1 1
      src/main/resources/mapper/base/BaseClassCourse.xml
  18. 6 26
      src/main/resources/mapper/teacher/TeacherFaceImportMapper.xml
  19. 5 4
      src/main/resources/mapper/textbook/TextbookMapper.xml
  20. 0 0
      src/main/resources/sqlScript/20240428_sql.sql
  21. 0 0
      src/main/resources/sqlScript/20240508_sql.sql
  22. 326 8
      src/test/java/com/xjrsoft/module/job/AttendanceMessageTaskTest.java
  23. 2 1
      src/test/java/com/xjrsoft/module/job/HikvisionBaseDataTaskTest.java
  24. 49 0
      src/test/java/com/xjrsoft/module/liteflow/node/ImportStudentFaceNodeTest.java

+ 17 - 5
src/main/java/com/xjrsoft/module/hikvision/controller/EventController.java

@@ -120,15 +120,27 @@ public class EventController {
                         weChatSendMessageDto.setMsgId(member.getId().toString());
                         weChatSendMessageDto.setMsgId(member.getId().toString());
                         JSONObject paramJson = new JSONObject();
                         JSONObject paramJson = new JSONObject();
 
 
-                        paramJson.put("thing1", student.getName());
-                        paramJson.put("time3", recordTimeStr);
-                        paramJson.put("thing2", baseClass.getName());
+                        JSONObject thing1 = new JSONObject();
+                        thing1.put("value", student.getName());
+                        paramJson.put("thing1", thing1);
+
+                        JSONObject time3 = new JSONObject();
+                        time3.put("value", recordTimeStr);
+                        paramJson.put("time3", time3);
+
+                        JSONObject thing2 = new JSONObject();
+                        thing2.put("value", baseClass.getName());
+                        paramJson.put("thing2", thing2);
+
+                        JSONObject const4 = new JSONObject();
                         if(status == 1){
                         if(status == 1){
-                            paramJson.put("const4", "进校");
+                            const4.put("value", "进校");
                         }else{
                         }else{
-                            paramJson.put("const4", "出校");
+                            const4.put("value", "出校");
                         }
                         }
 
 
+                        paramJson.put("const4", const4);
+
                         weChatSendMessageDto.setContent(paramJson);
                         weChatSendMessageDto.setContent(paramJson);
                         weChatService.sendTemplateMessage(weChatSendMessageDto);
                         weChatService.sendTemplateMessage(weChatSendMessageDto);
                     }
                     }

+ 53 - 43
src/main/java/com/xjrsoft/module/hikvision/util/OutInRecordUtil.java

@@ -5,6 +5,7 @@ import com.google.gson.Gson;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonObject;
+import com.microsoft.schemas.office.office.BulletAttribute;
 import com.xjrsoft.module.attendance.entity.AttendanceRuleDetails;
 import com.xjrsoft.module.attendance.entity.AttendanceRuleDetails;
 import com.xjrsoft.module.teacher.mapper.FaceImportMapper;
 import com.xjrsoft.module.teacher.mapper.FaceImportMapper;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
@@ -25,17 +26,20 @@ public class OutInRecordUtil {
     private static final Logger log = LoggerFactory.getLogger(OutInRecordUtil.class);
     private static final Logger log = LoggerFactory.getLogger(OutInRecordUtil.class);
 
 
     private void teacherInsertRecord(Db db, Long userId, String recordTime, String facePhoto, int status, String eventId, String attendanceStatus) throws SQLException {
     private void teacherInsertRecord(Db db, Long userId, String recordTime, String facePhoto, int status, String eventId, String attendanceStatus) throws SQLException {
+        String photoValue = (facePhoto != null && !facePhoto.equals("null")) ? facePhoto : "";
 
 
         String sql = "INSERT INTO teacher_out_in_record(create_date, user_id, record_time, face_photo, eventId, status,delete_mark,enabled_mark, attendance_status) " +
         String sql = "INSERT INTO teacher_out_in_record(create_date, user_id, record_time, face_photo, eventId, status,delete_mark,enabled_mark, attendance_status) " +
                 "VALUES(now(), '"  + userId + "', '" + recordTime + "', '" +
                 "VALUES(now(), '"  + userId + "', '" + recordTime + "', '" +
-                facePhoto + "', '" + eventId + "', '" +status + "',0,1,'" + attendanceStatus + "')";
+                photoValue + "', '" + eventId + "', '" +status + "',0,1,'" + attendanceStatus + "')";
         db.execute(sql);
         db.execute(sql);
     }
     }
 
 
     private void studentInsertRecord(Db db, Long userId, Long teacherId, Long classId, String facePhoto, String recordTime, int status, String eventId, String attendanceStatus) throws SQLException {
     private void studentInsertRecord(Db db, Long userId, Long teacherId, Long classId, String facePhoto, String recordTime, int status, String eventId, String attendanceStatus) throws SQLException {
+        String photoValue = (facePhoto != null && !facePhoto.equals("null")) ? facePhoto : "";
+
         String sql = "INSERT INTO student_out_in_record(create_date, user_id, teacher_id, class_id, face_photo, record_time , eventId,status,delete_mark,enabled_mark, attendance_status) " +
         String sql = "INSERT INTO student_out_in_record(create_date, user_id, teacher_id, class_id, face_photo, record_time , eventId,status,delete_mark,enabled_mark, attendance_status) " +
                 "VALUES(now(), '" + userId + "', '" + teacherId + "', '" +
                 "VALUES(now(), '" + userId + "', '" + teacherId + "', '" +
-                classId + "', '" + facePhoto + "', '" + recordTime + "', '" + eventId + "', '" + status + "',0,1,'" + attendanceStatus + "')";
+                classId + "', '" + photoValue + "', '" + recordTime + "', '" + eventId + "', '" + status + "',0,1,'" + attendanceStatus + "')";
         db.execute(sql);
         db.execute(sql);
     }
     }
 
 
@@ -49,11 +53,15 @@ public class OutInRecordUtil {
 
 
     private void vehicleInsertRecord(Db db, Long carMessageApplyId, String recordTime, int releaseReason, int category, String facePhoto, int status, String planNo, String crossRecordSyscode,
     private void vehicleInsertRecord(Db db, Long carMessageApplyId, String recordTime, int releaseReason, int category, String facePhoto, int status, String planNo, String crossRecordSyscode,
                                      int releaseResult, int releaseWay, int vehicleType, String phone, String name) throws SQLException {
                                      int releaseResult, int releaseWay, int vehicleType, String phone, String name) throws SQLException {
+        String phoneValue = (phone != null && !phone.equals("null")) ? phone : "";
+        String nameValue = (name != null && !name.equals("null")) ? name : "";
+        String photoValue = (facePhoto != null && !facePhoto.equals("null")) ? facePhoto : "";
+
         String sql = "INSERT INTO car_out_in_record(create_date, car_message_apply_id, record_time, face_photo, status,release_reason, plan_no, " +
         String sql = "INSERT INTO car_out_in_record(create_date, car_message_apply_id, record_time, face_photo, status,release_reason, plan_no, " +
                 "cross_record_syscode, release_result, release_way, vehicle_type, phone, name, category,delete_mark,enabled_mark) " +
                 "cross_record_syscode, release_result, release_way, vehicle_type, phone, name, category,delete_mark,enabled_mark) " +
                 "VALUES(now(), '"  + carMessageApplyId + "', '" +
                 "VALUES(now(), '"  + carMessageApplyId + "', '" +
-                recordTime + "', '" + facePhoto + "', '" + status + "', '" + releaseReason + "', '" + planNo + "', '" +
-                crossRecordSyscode + "', '" + releaseResult + "', '" + releaseWay + "', '" + vehicleType + "', '" + phone + "', '" + name + "', '" + category  +  "',0,1)";
+                recordTime + "', '" + photoValue + "', '" + status + "', '" + releaseReason + "', '" + planNo + "', '" +
+                crossRecordSyscode + "', '" + releaseResult + "', '" + releaseWay + "', '" + vehicleType + "', '" + phoneValue + "', '" + nameValue + "', '" + category  +  "',0,1)";
         db.execute(sql);
         db.execute(sql);
     }
     }
 
 
@@ -97,7 +105,17 @@ public class OutInRecordUtil {
             }
             }
             if (personId == null) continue;
             if (personId == null) continue;
 
 
-            int status = item.get("inAndOutType").getAsInt();
+            int statusInt = item.get("inAndOutType").getAsInt();
+            int status = -1;
+            switch (statusInt){
+                case 0:
+                    status = 1;
+                    break;
+                case 1:
+                    status = 0;
+                    break;
+            }
+
             String uri = item.get("picUri").isJsonNull() ? null : item.get("picUri").getAsString();
             String uri = item.get("picUri").isJsonNull() ? null : item.get("picUri").getAsString();
             String recordTime = item.get("eventTime").isJsonNull() ? null : item.get("eventTime").getAsString();
             String recordTime = item.get("eventTime").isJsonNull() ? null : item.get("eventTime").getAsString();
             String eventId = item.get("eventId").isJsonNull() ? null : item.get("eventId").getAsString();
             String eventId = item.get("eventId").isJsonNull() ? null : item.get("eventId").getAsString();
@@ -118,7 +136,7 @@ public class OutInRecordUtil {
                 LocalDateTime recordTimeDate = LocalDateTime.parse(recordTimeStr, formatter);
                 LocalDateTime recordTimeDate = LocalDateTime.parse(recordTimeStr, formatter);
                 String attendanceStatus = discernStudentStatus(use, recordTimeDate, status, personId);
                 String attendanceStatus = discernStudentStatus(use, recordTimeDate, status, personId);
                 studentInsertRecord(use, personId, faceImportMapper.GetTeacherIdByPersonId(personId),
                 studentInsertRecord(use, personId, faceImportMapper.GetTeacherIdByPersonId(personId),
-                        faceImportMapper.GetClassIdByPersonId(personId), ApiUtil.GetRedirectURL(uri), recordTimeStr, status,eventId, attendanceStatus);
+                        faceImportMapper.GetClassIdByPersonId(personId), ApiUtil.GetRedirectURL(uri), recordTimeStr, status, eventId, attendanceStatus);
             }
             }
         }
         }
     }
     }
@@ -178,7 +196,6 @@ public class OutInRecordUtil {
         return attendanceStatus;
         return attendanceStatus;
     }
     }
 
 
-
     String discernStudentStatus(Db use, LocalDateTime recordTime, int status, Long studentUserId) throws SQLException {
     String discernStudentStatus(Db use, LocalDateTime recordTime, int status, Long studentUserId) throws SQLException {
         String attendanceStatus = "";
         String attendanceStatus = "";
         String dayOfWeek = recordTime.getDayOfWeek().name();
         String dayOfWeek = recordTime.getDayOfWeek().name();
@@ -361,7 +378,7 @@ public class OutInRecordUtil {
             JsonObject item = element.getAsJsonObject();
             JsonObject item = element.getAsJsonObject();
 
 
             String carMessageApplyIdStr = faceImportMapper.GetCarMessageApplyIdByCarNumber(item.get("plateNo").getAsString().trim());
             String carMessageApplyIdStr = faceImportMapper.GetCarMessageApplyIdByCarNumber(item.get("plateNo").getAsString().trim());
-            Long carId = (carMessageApplyIdStr == null || carMessageApplyIdStr.isEmpty()) ? 0 : Long.parseLong(carMessageApplyIdStr);
+            Long carId = (carMessageApplyIdStr == null || carMessageApplyIdStr.isEmpty()) ? null : Long.parseLong(carMessageApplyIdStr);
             String category = null;
             String category = null;
             int categoryInt = 0;
             int categoryInt = 0;
             if (item.has("carCategory")){
             if (item.has("carCategory")){
@@ -417,16 +434,7 @@ public class OutInRecordUtil {
             System.out.println(facePicUri + "haha");
             System.out.println(facePicUri + "haha");
 
 
             String phone = faceImportMapper.GetPhoneNumberByPlanNum(plateNo);
             String phone = faceImportMapper.GetPhoneNumberByPlanNum(plateNo);
-            if (phone == null){
-                phone = faceImportMapper.GetPhoneNumberByPlanNumView(plateNo);
-                if (phone == null) phone = "";
-            }
-
             String name = faceImportMapper.GetNameByPlanNum(plateNo);
             String name = faceImportMapper.GetNameByPlanNum(plateNo);
-            if (name == null){
-                name = faceImportMapper.GetNameByPlanNumView(plateNo);
-                if (name == null) name = "";
-            }
 
 
             if(vehicle_id_list.contains(crossRecordSyscode)) continue;
             if(vehicle_id_list.contains(crossRecordSyscode)) continue;
 
 
@@ -467,11 +475,23 @@ public class OutInRecordUtil {
 
 
                 String idNum = null;
                 String idNum = null;
                 if (dataObject.has("ExtEventPersonNo")) {
                 if (dataObject.has("ExtEventPersonNo")) {
-                    idNum = dataObject.get("ExtEventPersonNo").getAsString();
+                    String idNumStr = dataObject.get("ExtEventPersonNo").getAsString();
+                    if (!idNumStr.isEmpty()) {
+                        idNum = idNumStr;
+                    }
                 }
                 }
                 String happenTime = eventObject.get("happenTime").getAsString();
                 String happenTime = eventObject.get("happenTime").getAsString();
                 String extEventPictureURL = dataObject.get("ExtEventPictureURL").getAsString();
                 String extEventPictureURL = dataObject.get("ExtEventPictureURL").getAsString();
-                int status = eventObject.get("status").getAsInt();
+                int statusInt = dataObject.get("ExtEventInOut").getAsInt();
+                int status = -1;
+                switch (statusInt){
+                    case 0:
+                        status = 1;
+                        break;
+                    case 1:
+                        status = 0;
+                        break;
+                }
                 String eventId = eventObject.get("eventId").getAsString();
                 String eventId = eventObject.get("eventId").getAsString();
                 String recordTimeStr = ChangeTime(happenTime);
                 String recordTimeStr = ChangeTime(happenTime);
 
 
@@ -517,16 +537,18 @@ public class OutInRecordUtil {
                     String carNum = dataObject.get("plateNo").getAsString().trim();
                     String carNum = dataObject.get("plateNo").getAsString().trim();
                     String eventIndex = dataObject.get("eventIndex").getAsString().trim();
                     String eventIndex = dataObject.get("eventIndex").getAsString().trim();
                     String carMessageApplyIdStr = faceImportMapper.GetCarMessageApplyIdByCarNumber(carNum);
                     String carMessageApplyIdStr = faceImportMapper.GetCarMessageApplyIdByCarNumber(carNum);
-                    Long carId = (carMessageApplyIdStr == null || carMessageApplyIdStr.isEmpty()) ? 0 : Long.parseLong(carMessageApplyIdStr);
+                    Long carId = (carMessageApplyIdStr == null || carMessageApplyIdStr.isEmpty()) ? null : Long.parseLong(carMessageApplyIdStr);
                     String eventTime = ChangeTime(dataObject.get("time").getAsString());
                     String eventTime = ChangeTime(dataObject.get("time").getAsString());
 
 
-                    int releaseWayInt = 0;
-                    int releaseReasonInt = 0;
-                    int releaseResultInt = 0;
+                    int releaseWayInt = -1;
+                    int releaseReasonInt = -1;
+                    int releaseResultInt = -1;
                     JsonObject inResultObject = dataObject.getAsJsonObject("inResult");
                     JsonObject inResultObject = dataObject.getAsJsonObject("inResult");
-                    if (inResultObject != null) {
-                        JsonObject rlsResultObject = inResultObject.getAsJsonObject("rlsResult");
-                        if (rlsResultObject != null && rlsResultObject.has("releaseWay") && rlsResultObject.has("releaseReason") && rlsResultObject.has("releaseResult")) {
+                    JsonObject outResultObject = dataObject.getAsJsonObject("outResult");
+                    JsonObject inoutResult = (inResultObject != null && !inResultObject.isJsonNull()) ? inResultObject : outResultObject;
+                    if (inoutResult != null) {
+                        JsonObject rlsResultObject = inoutResult.getAsJsonObject("rlsResult");
+                        if (rlsResultObject.has("releaseWay") && rlsResultObject.has("releaseReason") && rlsResultObject.has("releaseResult")) {
                             releaseWayInt = rlsResultObject.get("releaseWay").getAsInt();
                             releaseWayInt = rlsResultObject.get("releaseWay").getAsInt();
                             releaseReasonInt = rlsResultObject.get("releaseReason").getAsInt();
                             releaseReasonInt = rlsResultObject.get("releaseReason").getAsInt();
                             releaseResultInt = rlsResultObject.get("releaseResult").getAsInt();
                             releaseResultInt = rlsResultObject.get("releaseResult").getAsInt();
@@ -551,28 +573,16 @@ public class OutInRecordUtil {
                         facePicUri = picUrlObject.get("vehiclePicUrl").getAsString();
                         facePicUri = picUrlObject.get("vehiclePicUrl").getAsString();
                     }
                     }
 
 
-                    int status = eventObject.get("status").getAsInt();
+                    String statusStr = dataObject.get("roadwayName").getAsString();
                     int statusInt = 0;
                     int statusInt = 0;
-                    switch (status){
-                        case 0:
-                            statusInt = 1;
-                            break;
-                        case 1:
-                            statusInt = 0;
-                            break;
+                    if (statusStr.contains("入")) {
+                        statusInt = 0;
+                    } else if (statusStr.contains("出")) {
+                        statusInt = 1;
                     }
                     }
 
 
                     String phone = faceImportMapper.GetPhoneNumberByPlanNum(carNum);
                     String phone = faceImportMapper.GetPhoneNumberByPlanNum(carNum);
-                    if (phone == null){
-                        phone = faceImportMapper.GetPhoneNumberByPlanNumView(carNum);
-                        if (phone == null) phone = "";
-                    }
-
                     String name = faceImportMapper.GetNameByPlanNum(carNum);
                     String name = faceImportMapper.GetNameByPlanNum(carNum);
-                    if (name == null){
-                        name = faceImportMapper.GetNameByPlanNumView(carNum);
-                        if (name == null) name = "";
-                    }
 
 
                     if (vehicle_id_list.contains(eventIndex)) continue;
                     if (vehicle_id_list.contains(eventIndex)) continue;
 
 

+ 39 - 8
src/main/java/com/xjrsoft/module/job/AttenDanceWarnNoticeTask.java

@@ -1,5 +1,6 @@
 package com.xjrsoft.module.job;
 package com.xjrsoft.module.job;
 
 
+import cn.hutool.extra.spring.SpringUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.xjrsoft.common.utils.WeChatUtil;
 import com.xjrsoft.common.utils.WeChatUtil;
@@ -10,6 +11,8 @@ import com.xjrsoft.module.attendance.service.IAttendanceRuleCategoryService;
 import com.xjrsoft.module.concat.service.IXjrUserService;
 import com.xjrsoft.module.concat.service.IXjrUserService;
 import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
 import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
 import com.xjrsoft.module.organization.service.IWeChatService;
 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 com.xjrsoft.module.teacher.entity.XjrUser;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -19,13 +22,15 @@ import org.springframework.stereotype.Component;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
 
 
 /**
 /**
- * 考勤预警通知
+ * 考勤预警通知,提醒教师和学生是否该上课等
  * @author dzx
  * @author dzx
  * @date 2024年5月21日
  * @date 2024年5月21日
  */
  */
@@ -47,8 +52,16 @@ public class AttenDanceWarnNoticeTask {
     @Autowired
     @Autowired
     private WeChatUtil weChatUtil;
     private WeChatUtil weChatUtil;
 
 
+    @Autowired
+    private IWechatMessageLogService wechatMessageLogService;
+
     @Scheduled(cron = "0 */10 * * * ?")
     @Scheduled(cron = "0 */10 * * * ?")
     public void RefreshConnectionPool() {
     public void RefreshConnectionPool() {
+        String active = SpringUtil.getActiveProfile();
+        if(!"prod".equals(active)){
+            log.info("非正式环境,无法执行数据推送");
+            return;
+        }
         //获取当前时间
         //获取当前时间
         LocalDateTime now = LocalDateTime.now();
         LocalDateTime now = LocalDateTime.now();
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@@ -78,8 +91,14 @@ public class AttenDanceWarnNoticeTask {
 
 
         //根据规则中的用户id查询出所有绑定了微信的学生和教师
         //根据规则中的用户id查询出所有绑定了微信的学生和教师
         if(allTodyRule.isEmpty()){
         if(allTodyRule.isEmpty()){
+            log.info("未能查询出规则,不进行推送");
             return;
             return;
         }
         }
+        String wechatTemplate = weChatUtil.getAttenDanceWarnTemplate();
+        WechatMessageLog messageLog = new WechatMessageLog();
+        messageLog.setTemplateId(wechatTemplate);
+//        messageLog.setSendTime(recentlyTime);
+
         List<XjrUser> userList = getUserList(allTodyRule.keySet());
         List<XjrUser> userList = getUserList(allTodyRule.keySet());
         for (XjrUser xjrUser : userList) {
         for (XjrUser xjrUser : userList) {
             AttendanceRuleDetails ruleDetails = allTodyRule.get(xjrUser.getId());
             AttendanceRuleDetails ruleDetails = allTodyRule.get(xjrUser.getId());
@@ -90,23 +109,35 @@ public class AttenDanceWarnNoticeTask {
 
 
             WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
             WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
             weChatSendMessageDto.setUserId(xjrUser.getOpenId());
             weChatSendMessageDto.setUserId(xjrUser.getOpenId());
-            weChatSendMessageDto.setTemplateId(weChatUtil.getAttenDanceWarnTemplate());
+            weChatSendMessageDto.setTemplateId(wechatTemplate);
             weChatSendMessageDto.setMsgId(xjrUser.getId().toString());
             weChatSendMessageDto.setMsgId(xjrUser.getId().toString());
             JSONObject paramJson = new JSONObject();
             JSONObject paramJson = new JSONObject();
 
 
-            paramJson.put("thing8", xjrUser.getName());
-            paramJson.put("time9", timeStr);
+            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){
             if(status == 1){
-                paramJson.put("const12", "进校");
+                const12.put("value", "进校");
             }else{
             }else{
-                paramJson.put("const12", "出校");
+                const12.put("value", "出校");
             }
             }
-
-
+            paramJson.put("const12", const12);
 
 
             weChatSendMessageDto.setContent(paramJson);
             weChatSendMessageDto.setContent(paramJson);
             weChatService.sendTemplateMessage(weChatSendMessageDto);
             weChatService.sendTemplateMessage(weChatSendMessageDto);
+
         }
         }
+
+        messageLog.setCreateDate(new Date());
+        messageLog.setContent("消息推送人数:" + userList.size());
+        wechatMessageLogService.save(messageLog);
+
     }
     }
 
 
     /**
     /**

+ 89 - 41
src/main/java/com/xjrsoft/module/job/AttendanceMessageTask.java

@@ -5,6 +5,7 @@ import cn.hutool.extra.spring.SpringUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.common.utils.WeChatUtil;
 import com.xjrsoft.common.utils.WeChatUtil;
 import com.xjrsoft.config.CommonPropertiesConfig;
 import com.xjrsoft.config.CommonPropertiesConfig;
 import com.xjrsoft.module.attendance.entity.AttendanceMessageSet;
 import com.xjrsoft.module.attendance.entity.AttendanceMessageSet;
@@ -23,8 +24,11 @@ import com.xjrsoft.module.outint.entity.TeacherOutInRecord;
 import com.xjrsoft.module.outint.service.IStudentOutInRecordService;
 import com.xjrsoft.module.outint.service.IStudentOutInRecordService;
 import com.xjrsoft.module.outint.service.ITeacherOutInRecordService;
 import com.xjrsoft.module.outint.service.ITeacherOutInRecordService;
 import com.xjrsoft.module.student.entity.BaseStudent;
 import com.xjrsoft.module.student.entity.BaseStudent;
+import com.xjrsoft.module.system.entity.WechatMessageLog;
+import com.xjrsoft.module.system.service.IWechatMessageLogService;
 import com.xjrsoft.module.teacher.entity.BaseTeacher;
 import com.xjrsoft.module.teacher.entity.BaseTeacher;
 import com.xjrsoft.module.teacher.entity.XjrUser;
 import com.xjrsoft.module.teacher.entity.XjrUser;
+import com.yomahub.liteflow.util.JsonUtil;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.scheduling.annotation.Scheduled;
@@ -37,13 +41,14 @@ import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 /**
 /**
- * 考勤消息通知
+ * 考勤消息通知,给领导推送每个时段的考勤情况
  * @author dzx
  * @author dzx
  * @date 2024年6月7日
  * @date 2024年6月7日
  */
  */
@@ -77,6 +82,9 @@ public class AttendanceMessageTask {
     @Autowired
     @Autowired
     private WeChatUtil weChatUtil;
     private WeChatUtil weChatUtil;
 
 
+    @Autowired
+    private IWechatMessageLogService wechatMessageLogService;
+
     @Scheduled(cron = "0 */15 * * * ?")
     @Scheduled(cron = "0 */15 * * * ?")
     public void RefreshConnectionPool() {
     public void RefreshConnectionPool() {
         String active = SpringUtil.getActiveProfile();
         String active = SpringUtil.getActiveProfile();
@@ -84,12 +92,16 @@ public class AttendanceMessageTask {
             log.info("非正式环境,无法执行数据推送");
             log.info("非正式环境,无法执行数据推送");
             return;
             return;
         }
         }
+        doExecute();
+    }
+
+    public void doExecute(){
         LocalDateTime now = LocalDateTime.now();
         LocalDateTime now = LocalDateTime.now();
         HolidayDate holidayDate = holidayDateService.getOne(
         HolidayDate holidayDate = holidayDateService.getOne(
-                new QueryWrapper<HolidayDate>().lambda()
-                        .eq(HolidayDate::getDate, now.toLocalDate())
+            new QueryWrapper<HolidayDate>().lambda()
+            .eq(HolidayDate::getDate, now.toLocalDate())
         );
         );
-        if(holidayDate.getWay() != null && holidayDate.getWay() != 0){
+        if(holidayDate != null && holidayDate.getWay() != null && holidayDate.getWay() != 0){
             log.info("非工作日,不需要提醒");
             log.info("非工作日,不需要提醒");
             return;
             return;
         }
         }
@@ -97,9 +109,23 @@ public class AttendanceMessageTask {
         List<AttendanceRuleDetails> ruleDetails = ruleCategoryService.getTodayRules();
         List<AttendanceRuleDetails> ruleDetails = ruleCategoryService.getTodayRules();
         //获取最近的时间
         //获取最近的时间
         LocalDateTime recentlyTime = getRecentlyTime(ruleDetails, now);
         LocalDateTime recentlyTime = getRecentlyTime(ruleDetails, now);
+        String wechatTemplate = weChatUtil.getAttendanceMessageTemplate();
+        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;
+        }
+
+        WechatMessageLog messageLog = new WechatMessageLog();
+        messageLog.setTemplateId(wechatTemplate);
+        messageLog.setSendTime(recentlyTime);
 
 
         List<AttendanceMessageSet> list = messageSetService.list(
         List<AttendanceMessageSet> list = messageSetService.list(
-            new QueryWrapper<AttendanceMessageSet>().lambda()
+                new QueryWrapper<AttendanceMessageSet>().lambda()
         );
         );
         //判断是上午还是下午
         //判断是上午还是下午
         Integer timePeriod = null;
         Integer timePeriod = null;
@@ -118,6 +144,8 @@ public class AttendanceMessageTask {
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         String format = recentlyTime.format(formatter);
         String format = recentlyTime.format(formatter);
 
 
+        int userCount = 0;
+
         for (AttendanceMessageSet messageSet : list) {
         for (AttendanceMessageSet messageSet : list) {
             if(!messageSet.getTimePeriod().contains(timePeriod + "")){
             if(!messageSet.getTimePeriod().contains(timePeriod + "")){
                 continue;
                 continue;
@@ -125,6 +153,8 @@ public class AttendanceMessageTask {
             //查询需要通知的人
             //查询需要通知的人
             List<XjrUser> userList = userService.list(
             List<XjrUser> userList = userService.list(
                 new MPJLambdaWrapper<XjrUser>()
                 new MPJLambdaWrapper<XjrUser>()
+                .select(XjrUser::getId)
+                .select(XjrUser.class, x -> VoToColumnUtil.fieldsToColumns(XjrUser.class).contains(x.getProperty()))
                 .leftJoin(UserRoleRelation.class, UserRoleRelation::getUserId, XjrUser::getId)
                 .leftJoin(UserRoleRelation.class, UserRoleRelation::getUserId, XjrUser::getId)
                 .leftJoin(AttendanceMessageUserRelation.class, AttendanceMessageUserRelation::getUserId, XjrUser::getId)
                 .leftJoin(AttendanceMessageUserRelation.class, AttendanceMessageUserRelation::getUserId, XjrUser::getId)
                 .eq(UserRoleRelation::getRoleId, messageSet.getRoleType())
                 .eq(UserRoleRelation::getRoleId, messageSet.getRoleType())
@@ -134,34 +164,43 @@ public class AttendanceMessageTask {
             if(userList.isEmpty()){
             if(userList.isEmpty()){
                 continue;
                 continue;
             }
             }
+            userCount += userList.size();
             if(messageSet.getRoleType() != null && messageSet.getRoleType() == 2){
             if(messageSet.getRoleType() != null && messageSet.getRoleType() == 2){
                 //教师总人数
                 //教师总人数
                 long teacherCout = userService.count(
                 long teacherCout = userService.count(
-                    new MPJLambdaWrapper<XjrUser>()
-                    .leftJoin(BaseTeacher.class, BaseTeacher::getUserId, XjrUser::getId)
+                        new MPJLambdaWrapper<XjrUser>()
+                                .leftJoin(BaseTeacher.class, BaseTeacher::getUserId, XjrUser::getId)
                 );
                 );
                 //查询进入记录,就是实际到校的人数
                 //查询进入记录,就是实际到校的人数
                 long outInRecords = teachertOutInRecordService.count(
                 long outInRecords = teachertOutInRecordService.count(
-                    new MPJLambdaWrapper<TeacherOutInRecord>()
-                    .le(TeacherOutInRecord::getRecordTime, recentlyTime)
-                    .eq(TeacherOutInRecord::getStatus, 1)
+                        new MPJLambdaWrapper<TeacherOutInRecord>()
+                                .le(TeacherOutInRecord::getRecordTime, recentlyTime)
+                                .eq(TeacherOutInRecord::getStatus, 1)
                 );
                 );
 
 
-                //计算出勤率
-                BigDecimal divide = BigDecimal.ZERO;
-                if(teacherCout != 0){
-                    divide = BigDecimal.valueOf(outInRecords).divide(BigDecimal.valueOf(teacherCout), 4, RoundingMode.HALF_UP);
-                }
-
                 WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
                 WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
-                weChatSendMessageDto.setTemplateId(weChatUtil.getAttendanceMessageTemplate());
+                weChatSendMessageDto.setTemplateId(wechatTemplate);
                 JSONObject paramJson = new JSONObject();
                 JSONObject paramJson = new JSONObject();
 
 
-                paramJson.put("thing6", "教职工");
-                paramJson.put("time11", format);
-                paramJson.put("const23", timePeriodStr);
-                paramJson.put("character_string18", teacherCout - outInRecords);
-                paramJson.put("const3", divide.doubleValue());
+                JSONObject thing6 = new JSONObject();
+                thing6.put("value", "教职工");
+                paramJson.put("thing6", thing6);
+
+                JSONObject time11 = new JSONObject();
+                time11.put("value", format);
+                paramJson.put("time11", time11);
+
+                JSONObject const23 = new JSONObject();
+                const23.put("value", timePeriodStr);
+                paramJson.put("const23", const23);
+
+                JSONObject character_string18 = new JSONObject();
+                character_string18.put("value", teacherCout - outInRecords);
+                paramJson.put("character_string18", character_string18);
+
+                JSONObject character_string16 = new JSONObject();
+                character_string16.put("value", teacherCout);
+                paramJson.put("character_string16", character_string16);
 
 
                 weChatSendMessageDto.setContent(paramJson);
                 weChatSendMessageDto.setContent(paramJson);
                 weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/teacher/index", commonPropertiesConfig.getDomainApp()));
                 weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/teacher/index", commonPropertiesConfig.getDomainApp()));
@@ -174,32 +213,39 @@ public class AttendanceMessageTask {
             }else if(messageSet.getRoleType() != null && messageSet.getRoleType() == 3){
             }else if(messageSet.getRoleType() != null && messageSet.getRoleType() == 3){
                 //教师总人数
                 //教师总人数
                 long teacherCout = userService.count(
                 long teacherCout = userService.count(
-                    new MPJLambdaWrapper<XjrUser>()
-                    .leftJoin(BaseStudent.class, BaseStudent::getUserId, XjrUser::getId)
+                        new MPJLambdaWrapper<XjrUser>()
+                                .leftJoin(BaseStudent.class, BaseStudent::getUserId, XjrUser::getId)
                 );
                 );
                 //查询进入记录,就是实际到校的人数
                 //查询进入记录,就是实际到校的人数
                 long outInRecords = studentOutInRecordService.count(
                 long outInRecords = studentOutInRecordService.count(
-                    new MPJLambdaWrapper<StudentOutInRecord>()
-                    .le(StudentOutInRecord::getRecordTime, recentlyTime)
-                    .eq(StudentOutInRecord::getStatus, 1)
+                        new MPJLambdaWrapper<StudentOutInRecord>()
+                                .le(StudentOutInRecord::getRecordTime, recentlyTime)
+                                .eq(StudentOutInRecord::getStatus, 1)
                 );
                 );
 
 
-                //计算出勤率
-                BigDecimal divide = BigDecimal.ZERO;
-                if(teacherCout != 0){
-                    divide = BigDecimal.valueOf(outInRecords).divide(BigDecimal.valueOf(teacherCout), 4, RoundingMode.HALF_UP);
-                }
-
-
                 WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
                 WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
                 weChatSendMessageDto.setTemplateId(weChatUtil.getAttendanceMessageTemplate());
                 weChatSendMessageDto.setTemplateId(weChatUtil.getAttendanceMessageTemplate());
                 JSONObject paramJson = new JSONObject();
                 JSONObject paramJson = new JSONObject();
 
 
-                paramJson.put("thing6", "学生");
-                paramJson.put("time11", format);
-                paramJson.put("const23", timePeriodStr);
-                paramJson.put("character_string18", teacherCout - outInRecords);
-                paramJson.put("const3", divide.doubleValue());
+                JSONObject thing6 = new JSONObject();
+                thing6.put("value", "教职工");
+                paramJson.put("thing6", thing6);
+
+                JSONObject time11 = new JSONObject();
+                time11.put("value", format);
+                paramJson.put("time11", time11);
+
+                JSONObject const23 = new JSONObject();
+                const23.put("value", timePeriodStr);
+                paramJson.put("const23", const23);
+
+                JSONObject character_string18 = new JSONObject();
+                character_string18.put("value", teacherCout - outInRecords);
+                paramJson.put("character_string18", character_string18);
+
+                JSONObject character_string16 = new JSONObject();
+                character_string16.put("value", teacherCout);
+                paramJson.put("const3", character_string16);
 
 
                 weChatSendMessageDto.setContent(paramJson);
                 weChatSendMessageDto.setContent(paramJson);
                 weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/class/index", commonPropertiesConfig.getDomainApp()));
                 weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/class/index", commonPropertiesConfig.getDomainApp()));
@@ -211,13 +257,15 @@ public class AttendanceMessageTask {
                 }
                 }
             }
             }
         }
         }
-
+        messageLog.setCreateDate(new Date());
+        messageLog.setContent("消息推送人数:" + userCount);
+        wechatMessageLogService.save(messageLog);
     }
     }
 
 
     LocalDateTime getRecentlyTime(List<AttendanceRuleDetails> ruleDetails, LocalDateTime now){
     LocalDateTime getRecentlyTime(List<AttendanceRuleDetails> ruleDetails, LocalDateTime now){
         List<LocalDateTime> result = new ArrayList<>();
         List<LocalDateTime> result = new ArrayList<>();
         for (AttendanceRuleDetails ruleDetail : ruleDetails) {
         for (AttendanceRuleDetails ruleDetail : ruleDetails) {
-            if(ruleDetail.getIsAllowInOutSchool() != null && ruleDetail.getIsAllowInOutSchool() != 1
+            if(ruleDetail.getIsAllowInOutSchool() != null && ruleDetail.getIsAllowInOutSchool() == 1
                     && ruleDetail.getIsAttendance() != null && ruleDetail.getIsAttendance() == 1){
                     && ruleDetail.getIsAttendance() != null && ruleDetail.getIsAttendance() == 1){
                 if(ruleDetail.getAmStartTime() != null){
                 if(ruleDetail.getAmStartTime() != null){
                     LocalDateTime amStartTime = now.with(ruleDetail.getAmStartTime());
                     LocalDateTime amStartTime = now.with(ruleDetail.getAmStartTime());

+ 5 - 1
src/main/java/com/xjrsoft/module/student/controller/PbSemesterConfigController.java

@@ -13,6 +13,7 @@ import com.xjrsoft.common.page.PageOutput;
 import com.xjrsoft.common.model.result.RT;
 import com.xjrsoft.common.model.result.RT;
 import com.xjrsoft.common.utils.TreeUtil;
 import com.xjrsoft.common.utils.TreeUtil;
 import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.module.base.entity.BaseClass;
 import com.xjrsoft.module.base.entity.BaseSemester;
 import com.xjrsoft.module.base.entity.BaseSemester;
 import com.xjrsoft.module.base.service.IBaseSemesterService;
 import com.xjrsoft.module.base.service.IBaseSemesterService;
 import com.xjrsoft.module.student.dto.AddPbSemesterConfigDto;
 import com.xjrsoft.module.student.dto.AddPbSemesterConfigDto;
@@ -56,7 +57,10 @@ public class PbSemesterConfigController {
     @ApiOperation(value = "年和学期树")
     @ApiOperation(value = "年和学期树")
     @SaCheckPermission("pbsemesterconfig:detail")
     @SaCheckPermission("pbsemesterconfig:detail")
     public RT<List<SemesterYeatTreeVo>> tree() {
     public RT<List<SemesterYeatTreeVo>> tree() {
-        List<BaseSemester> baseSemesterList = baseSemesterService.list();
+        LambdaQueryWrapper<BaseSemester> baseSemesterLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        baseSemesterLambdaQueryWrapper
+                .eq(BaseSemester::getDeleteMark, 0);
+        List<BaseSemester> baseSemesterList = baseSemesterService.list(baseSemesterLambdaQueryWrapper);
 
 
         baseSemesterList.forEach(element -> {
         baseSemesterList.forEach(element -> {
             // 处理元素
             // 处理元素

+ 65 - 0
src/main/java/com/xjrsoft/module/system/entity/WechatMessageLog.java

@@ -0,0 +1,65 @@
+package com.xjrsoft.module.system.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+
+/**
+* @title: 微信消息发送记录
+* @Author dzx
+* @Date: 2024年6月11日
+* @Version 1.0
+*/
+@Data
+@TableName("wechat_message_log")
+@ApiModel(value = "微信消息发送记录对象", description = "微信消息发送记录")
+public class WechatMessageLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+
+    @ApiModelProperty("主键编号")
+    @TableId
+    private Long id;
+
+    @ApiModelProperty("创建人")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUserId;
+
+    @ApiModelProperty("创建时间")
+    @TableField(fill = FieldFill.INSERT)
+    private Date createDate;
+
+    @ApiModelProperty("删除标记")
+    @TableField(fill = FieldFill.INSERT)
+    @TableLogic
+    private Integer deleteMark;
+
+    @ApiModelProperty("有效标志")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer enabledMark;
+
+    @ApiModelProperty("序号")
+    private Integer sortCode;
+
+    @ApiModelProperty("发送模板id")
+    private String templateId;
+
+    @ApiModelProperty("发送时间")
+    private LocalDateTime sendTime;
+
+    @ApiModelProperty("发送内容")
+    private String content;
+
+
+}

+ 16 - 0
src/main/java/com/xjrsoft/module/system/mapper/WechatMessageLogMapper.java

@@ -0,0 +1,16 @@
+package com.xjrsoft.module.system.mapper;
+
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.system.entity.WechatMessageLog;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @title: 微信消息发送记录
+ * @Author dzx
+ * @Date: 2024年6月11日
+ * @Version 1.0
+*/
+@Mapper
+public interface WechatMessageLogMapper extends MPJBaseMapper<WechatMessageLog> {
+
+}

+ 34 - 0
src/main/java/com/xjrsoft/module/system/service/IWechatMessageLogService.java

@@ -0,0 +1,34 @@
+package com.xjrsoft.module.system.service;
+
+import com.github.yulichang.base.MPJBaseService;
+import com.xjrsoft.module.system.entity.WechatMessageLog;
+
+import java.util.List;
+
+/**
+ * @title: 微信消息发送记录
+ * @Author dzx
+ * @Date: 2024年6月11日
+ * @Version 1.0
+*/
+
+public interface IWechatMessageLogService extends MPJBaseService<WechatMessageLog> {
+    /**
+    * 新增
+    *
+    */
+    Boolean add(WechatMessageLog wechatMessageLog);
+
+    /**
+    * 更新
+    *
+    */
+    Boolean update(WechatMessageLog wechatMessageLog);
+
+
+    /**
+    * 删除
+    *
+    */
+    Boolean delete(List<Long> ids);
+}

+ 43 - 0
src/main/java/com/xjrsoft/module/system/service/impl/WechatMessageLogServiceImpl.java

@@ -0,0 +1,43 @@
+package com.xjrsoft.module.system.service.impl;
+
+import com.github.yulichang.base.MPJBaseServiceImpl;
+import com.xjrsoft.module.system.entity.WechatMessageLog;
+import com.xjrsoft.module.system.mapper.WechatMessageLogMapper;
+import com.xjrsoft.module.system.service.IWechatMessageLogService;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * @title: 微信消息发送记录
+ * @Author dzx
+ * @Date: 2024年6月11日
+ * @Version 1.0
+*/
+@Service
+@AllArgsConstructor
+public class WechatMessageLogServiceImpl extends MPJBaseServiceImpl<WechatMessageLogMapper, WechatMessageLog> implements IWechatMessageLogService {
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean add(WechatMessageLog wechatMessageLog) {
+        this.baseMapper.insert(wechatMessageLog);
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean update(WechatMessageLog wechatMessageLog) {
+        this.baseMapper.updateById(wechatMessageLog);
+        return true;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean delete(List<Long> ids) {
+        this.baseMapper.deleteBatchIds(ids);
+        return true;
+    }
+}

+ 0 - 3
src/main/java/com/xjrsoft/module/teacher/mapper/FaceImportMapper.java

@@ -32,9 +32,6 @@ public interface FaceImportMapper {
     String GetPhoneNumberByPlanNum(@Param("id") String id);
     String GetPhoneNumberByPlanNum(@Param("id") String id);
     String GetNameByPlanNum(@Param("id") String id);
     String GetNameByPlanNum(@Param("id") String id);
 
 
-    String GetPhoneNumberByPlanNumView(@Param("id") String id);
-    String GetNameByPlanNumView(@Param("id") String id);
-
     List<String> GetVisitIdList();
     List<String> GetVisitIdList();
 }
 }
 
 

+ 8 - 10
src/main/java/com/xjrsoft/module/textbook/controller/TextbookController.java

@@ -14,17 +14,14 @@ import com.xjrsoft.common.model.result.RT;
 import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.page.PageOutput;
 import com.xjrsoft.common.page.PageOutput;
 import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.common.utils.VoToColumnUtil;
-import com.xjrsoft.module.asset.entity.WfAssetManage;
-import com.xjrsoft.module.asset.vo.WfAssetManageVo;
+import com.xjrsoft.module.base.entity.BaseClassCourse;
 import com.xjrsoft.module.base.entity.BaseCourseSubject;
 import com.xjrsoft.module.base.entity.BaseCourseSubject;
 import com.xjrsoft.module.base.entity.BaseSemester;
 import com.xjrsoft.module.base.entity.BaseSemester;
 import com.xjrsoft.module.base.service.IBaseSemesterService;
 import com.xjrsoft.module.base.service.IBaseSemesterService;
 import com.xjrsoft.module.student.entity.BaseClassMajorSet;
 import com.xjrsoft.module.student.entity.BaseClassMajorSet;
-import com.xjrsoft.module.system.entity.DictionaryDetail;
 import com.xjrsoft.module.textbook.dto.*;
 import com.xjrsoft.module.textbook.dto.*;
 import com.xjrsoft.module.textbook.entity.Textbook;
 import com.xjrsoft.module.textbook.entity.Textbook;
 import com.xjrsoft.module.textbook.entity.TextbookClassRelation;
 import com.xjrsoft.module.textbook.entity.TextbookClassRelation;
-import com.xjrsoft.module.textbook.entity.WfTextbookSubscription;
 import com.xjrsoft.module.textbook.service.ITextbookService;
 import com.xjrsoft.module.textbook.service.ITextbookService;
 import com.xjrsoft.module.textbook.vo.*;
 import com.xjrsoft.module.textbook.vo.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
@@ -84,11 +81,11 @@ public class TextbookController {
                 .selectAs(BaseCourseSubject::getName, TextbookSubscriptionListVo::getCourseSubjectIdCn)
                 .selectAs(BaseCourseSubject::getName, TextbookSubscriptionListVo::getCourseSubjectIdCn)
                 .selectSum(BaseClassMajorSet::getTotalStudent, TextbookSubscriptionListVo::getStudentSubscriptionNumber)
                 .selectSum(BaseClassMajorSet::getTotalStudent, TextbookSubscriptionListVo::getStudentSubscriptionNumber)
                 .select(Textbook.class, x -> VoToColumnUtil.fieldsToColumns(TextbookSubscriptionListVo.class).contains(x.getProperty()))
                 .select(Textbook.class, x -> VoToColumnUtil.fieldsToColumns(TextbookSubscriptionListVo.class).contains(x.getProperty()))
-                .leftJoin(TextbookClassRelation.class, TextbookClassRelation::getTextbookId, Textbook::getId)
-                .leftJoin(BaseClassMajorSet.class, BaseClassMajorSet::getClassId, TextbookClassRelation::getClassId)
+                .leftJoin(BaseClassCourse.class, BaseClassCourse::getCourseId, Textbook::getCourseSubjectId)
+                .leftJoin(BaseClassMajorSet.class, BaseClassMajorSet::getClassId, BaseClassCourse::getClassId)
                 .leftJoin(BaseCourseSubject.class, BaseCourseSubject::getId, Textbook::getCourseSubjectId)
                 .leftJoin(BaseCourseSubject.class, BaseCourseSubject::getId, Textbook::getCourseSubjectId)
-                .eq(dto.getBaseSemesterId() != null && dto.getBaseSemesterId() > 0, Textbook::getBaseSemesterId, dto.getBaseSemesterId())
-                .in(!classIdList.isEmpty(),TextbookClassRelation::getClassId, classIdList)
+                .eq(dto.getBaseSemesterId() != null && dto.getBaseSemesterId() > 0, BaseClassCourse::getBaseSemesterId, dto.getBaseSemesterId())
+                .in(!classIdList.isEmpty(),BaseClassCourse::getClassId, classIdList)
                 .groupBy(Textbook::getId)
                 .groupBy(Textbook::getId)
         ;
         ;
         IPage<TextbookSubscriptionListVo> page = textbookService.selectJoinListPage(ConventPage.getPage(dto),TextbookSubscriptionListVo.class,textbookMPJLambdaWrapper);
         IPage<TextbookSubscriptionListVo> page = textbookService.selectJoinListPage(ConventPage.getPage(dto),TextbookSubscriptionListVo.class,textbookMPJLambdaWrapper);
@@ -102,8 +99,9 @@ public class TextbookController {
         return RT.ok(pageOutput);
         return RT.ok(pageOutput);
     }
     }
 
 
+    // TODO 学生确认领取教材列表
     @GetMapping(value = "/page-consumption")
     @GetMapping(value = "/page-consumption")
-    @ApiOperation(value="教材管理列表(分页,学生收费用)")
+    @ApiOperation(value="学生确认领取教材列表(分页,学生收费用)")
     @SaCheckPermission("textbook:detail")
     @SaCheckPermission("textbook:detail")
     public RT<PageOutput<TextbookConsumptionPageVo>> pageConsumption(@Valid TextbookConsumptionPageDto dto){
     public RT<PageOutput<TextbookConsumptionPageVo>> pageConsumption(@Valid TextbookConsumptionPageDto dto){
         MPJLambdaWrapper<Textbook> textbookMPJLambdaWrapper = new MPJLambdaWrapper<>();
         MPJLambdaWrapper<Textbook> textbookMPJLambdaWrapper = new MPJLambdaWrapper<>();
@@ -158,7 +156,7 @@ public class TextbookController {
     @GetMapping(value = "/info-detail")
     @GetMapping(value = "/info-detail")
     @ApiOperation(value="根据id查询教材管理信息")
     @ApiOperation(value="根据id查询教材管理信息")
     @SaCheckPermission("textbook:detail")
     @SaCheckPermission("textbook:detail")
-    public RT<TextbookVo> info(@RequestParam Long id){
+    public RT info(@RequestParam Long id){
         Textbook textbook = textbookService.getById(id);
         Textbook textbook = textbookService.getById(id);
         if (textbook == null) {
         if (textbook == null) {
            return RT.ok();
            return RT.ok();

+ 6 - 0
src/main/java/com/xjrsoft/module/textbook/dto/AddTextbookDto.java

@@ -126,4 +126,10 @@ public class AddTextbookDto implements Serializable {
     */
     */
     @ApiModelProperty("textbookSubscriptionRecord子表")
     @ApiModelProperty("textbookSubscriptionRecord子表")
     private List<AddTextbookSubscriptionRecordDto> textbookSubscriptionRecordList;
     private List<AddTextbookSubscriptionRecordDto> textbookSubscriptionRecordList;
+
+    /**
+     * 使用类型(单位:学期)
+     */
+    @ApiModelProperty("使用类型(单位:学期)")
+    private Integer useType;
 }
 }

+ 4 - 4
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookServiceImpl.java

@@ -449,10 +449,10 @@ public class TextbookServiceImpl extends MPJBaseServiceImpl<TextbookMapper, Text
             recordVos = textbookTextbookMapper.subscriptionList(id);
             recordVos = textbookTextbookMapper.subscriptionList(id);
             for (TextbookSubscriptionRecordVo recordVo : recordVos) {
             for (TextbookSubscriptionRecordVo recordVo : recordVos) {
                 if (ObjectUtil.isNull(recordVo) || StrUtil.isEmpty(recordVo.getClassIds())) {
                 if (ObjectUtil.isNull(recordVo) || StrUtil.isEmpty(recordVo.getClassIds())) {
-                    recordVos.remove(recordVo);
-                    if (recordVos.isEmpty()) {
-                        break;
-                    }
+//                    recordVos.remove(recordVo);
+//                    if (recordVos.isEmpty()) {
+//                        break;
+//                    }
                     continue;
                     continue;
                 }
                 }
                 String[] split = recordVo.getClassIds().split(",");
                 String[] split = recordVo.getClassIds().split(",");

+ 3 - 3
src/main/resources/application-dev.yml

@@ -61,9 +61,9 @@ xjrsoft:
   oss:
   oss:
     #enabled: true
     #enabled: true
     cloud-type: minio
     cloud-type: minio
-    access-key: ycbx
+    access-key: root
     secret-key: qwe123QWE
     secret-key: qwe123QWE
-    endpoint: https://test.minio.yingcaibx.com
+    endpoint: http://10.150.10.140:9000
     endpoint-preview: https://test.minio.yingcaibx.com
     endpoint-preview: https://test.minio.yingcaibx.com
     bucket-name: learun
     bucket-name: learun
     prefix: xjr
     prefix: xjr
@@ -137,7 +137,7 @@ xjrsoft:
   weChatMessageTemplate:
   weChatMessageTemplate:
     commonTemplate: qmpXORPM1Cocqn503Qa4OkNNQ0uxlj2-ed9m6uWO-v4
     commonTemplate: qmpXORPM1Cocqn503Qa4OkNNQ0uxlj2-ed9m6uWO-v4
     assessmentTemplate: ehYfXni7exZUmt6dJX4Ukbm9ETarFfKLfXVYwNnjKMc
     assessmentTemplate: ehYfXni7exZUmt6dJX4Ukbm9ETarFfKLfXVYwNnjKMc
-    attendanceMessageTemplate: uPPJkWOSronnB_GJolcnatrQzGjJREIKL7JZzOieoew
+    attendanceMessageTemplate: uPPJkWOSronnB_GJolcnajRSdnIf8GCoCk4c0v1szPA
     outInTemplate: ERkMebHjsziZO6WBrlzsbENiEuRR4vrlhJw5LR4aDr8
     outInTemplate: ERkMebHjsziZO6WBrlzsbENiEuRR4vrlhJw5LR4aDr8
     attenDanceWarnTemplate: Fg4AWVQRGernl0PiJQ8gRgCUFHEGZuizlClQNuVhqu4
     attenDanceWarnTemplate: Fg4AWVQRGernl0PiJQ8gRgCUFHEGZuizlClQNuVhqu4
   dingtalk:
   dingtalk:

+ 4 - 4
src/main/resources/application-pre.yml

@@ -46,9 +46,9 @@ xjrsoft:
   oss:
   oss:
     #enabled: true
     #enabled: true
     cloud-type: minio
     cloud-type: minio
-    access-key: ycbx
+    access-key: root
     secret-key: qwe123QWE
     secret-key: qwe123QWE
-    endpoint: https://test.minio.yingcaibx.com
+    endpoint: http://10.150.10.140:9000
     endpoint-preview: https://test.minio.yingcaibx.com
     endpoint-preview: https://test.minio.yingcaibx.com
     bucket-name: learun
     bucket-name: learun
     prefix: xjr
     prefix: xjr
@@ -118,9 +118,9 @@ xjrsoft:
   weChatMessageTemplate:
   weChatMessageTemplate:
     commonTemplate: qmpXORPM1Cocqn503Qa4OkNNQ0uxlj2-ed9m6uWO-v4
     commonTemplate: qmpXORPM1Cocqn503Qa4OkNNQ0uxlj2-ed9m6uWO-v4
     assessmentTemplate: ehYfXni7exZUmt6dJX4Ukbm9ETarFfKLfXVYwNnjKMc
     assessmentTemplate: ehYfXni7exZUmt6dJX4Ukbm9ETarFfKLfXVYwNnjKMc
-    attendanceMessageTemplate: uPPJkWOSronnB_GJolcnatrQzGjJREIKL7JZzOieoew
+    attendanceMessageTemplate: o-KboOcqcJ3YpjPN2xwgM_NcjN-0yzwWlDDXYfTM0Q4
     outInTemplate: ERkMebHjsziZO6WBrlzsbENiEuRR4vrlhJw5LR4aDr8
     outInTemplate: ERkMebHjsziZO6WBrlzsbENiEuRR4vrlhJw5LR4aDr8
-    attenDanceWarnTemplate: Fg4AWVQRGernl0PiJQ8gRgCUFHEGZuizlClQNuVhqu4
+    attenDanceWarnTemplate: vdFsy-QUk5L56OmGgBsRC_RB-45qRTkLzMPQotV2A4Y
   appletWeChat:
   appletWeChat:
     appKey: wx72e974483a9174e4
     appKey: wx72e974483a9174e4
     appSecret: 3bbe99f6964c9f4fc11a8aa1224ac4b3
     appSecret: 3bbe99f6964c9f4fc11a8aa1224ac4b3

+ 1 - 1
src/main/resources/application-prod.yml

@@ -114,7 +114,7 @@ xjrsoft:
   weChatMessageTemplate:
   weChatMessageTemplate:
     commonTemplate: qmpXORPM1Cocqn503Qa4OkNNQ0uxlj2-ed9m6uWO-v4
     commonTemplate: qmpXORPM1Cocqn503Qa4OkNNQ0uxlj2-ed9m6uWO-v4
     assessmentTemplate: ehYfXni7exZUmt6dJX4Ukbm9ETarFfKLfXVYwNnjKMc
     assessmentTemplate: ehYfXni7exZUmt6dJX4Ukbm9ETarFfKLfXVYwNnjKMc
-    attendanceMessageTemplate: uPPJkWOSronnB_GJolcnatrQzGjJREIKL7JZzOieoew
+    attendanceMessageTemplate: uPPJkWOSronnB_GJolcnajRSdnIf8GCoCk4c0v1szPA
     outInTemplate: ERkMebHjsziZO6WBrlzsbENiEuRR4vrlhJw5LR4aDr8
     outInTemplate: ERkMebHjsziZO6WBrlzsbENiEuRR4vrlhJw5LR4aDr8
     attenDanceWarnTemplate: Fg4AWVQRGernl0PiJQ8gRgCUFHEGZuizlClQNuVhqu4
     attenDanceWarnTemplate: Fg4AWVQRGernl0PiJQ8gRgCUFHEGZuizlClQNuVhqu4
   appletWeChat:
   appletWeChat:

+ 1 - 1
src/main/resources/mapper/base/BaseClassCourse.xml

@@ -35,7 +35,7 @@
         LEFT JOIN xjr_department t4 ON t4.id = t.org_id
         LEFT JOIN xjr_department t4 ON t4.id = t.org_id
         WHERE t.delete_mark = 0
         WHERE t.delete_mark = 0
         <if test="dto.className != null and dto.className != ''">
         <if test="dto.className != null and dto.className != ''">
-            and t.name = #{dto.className}
+            and t.name = like concat('%', #{dto.className}, '%')
         </if>
         </if>
         <if test="dto.deptId != null">
         <if test="dto.deptId != null">
             and t4.id = #{dto.deptId}
             and t4.id = #{dto.deptId}

+ 6 - 26
src/main/resources/mapper/teacher/TeacherFaceImportMapper.xml

@@ -125,38 +125,18 @@
     </select>
     </select>
 
 
     <select id="GetPhoneNumberByPlanNum" resultType="java.lang.String">
     <select id="GetPhoneNumberByPlanNum" resultType="java.lang.String">
-        SELECT c_phone
-        FROM base_car_management
-        where delete_mark = 0
+        SELECT 手机号
+        FROM car_info
         <if test="id != null">
         <if test="id != null">
-            and car_no = #{id}
+            where 车牌号码 = #{id}
         </if>
         </if>
     </select>
     </select>
 
 
     <select id="GetNameByPlanNum" resultType="java.lang.String">
     <select id="GetNameByPlanNum" resultType="java.lang.String">
-        SELECT c_name
-        FROM base_car_management
-        where delete_mark = 0
-        <if test="id != null">
-            and car_no = #{id}
-        </if>
-    </select>
-
-    <select id="GetPhoneNumberByPlanNumView" resultType="java.lang.String">
-        SELECT phone
-        FROM reservation_school_people
-        where delete_mark = 0
-        <if test="id != null">
-            and plate_number = #{id}
-        </if>
-    </select>
-
-    <select id="GetNameByPlanNumView" resultType="java.lang.String">
-        SELECT name
-        FROM reservation_school_people
-        where delete_mark = 0
+        SELECT 车主姓名
+        FROM car_info
         <if test="id != null">
         <if test="id != null">
-            and plate_number = #{id}
+            where 车牌号码 = #{id}
         </if>
         </if>
     </select>
     </select>
 
 

+ 5 - 4
src/main/resources/mapper/textbook/TextbookMapper.xml

@@ -23,9 +23,9 @@
         <if test="dto.textbookType != null and dto.textbookType != ''">
         <if test="dto.textbookType != null and dto.textbookType != ''">
             and t1.textbook_type = #{dto.textbookType}
             and t1.textbook_type = #{dto.textbookType}
         </if>
         </if>
-        <if test="dto.baseSemesterId != null and dto.baseSemesterId > 0">
-            and t1.base_semester_id = #{dto.baseSemesterId}
-        </if>
+<!--        <if test="dto.baseSemesterId != null and dto.baseSemesterId > 0">-->
+<!--            and t1.base_semester_id = #{dto.baseSemesterId}-->
+<!--        </if>-->
         <if test="dto.subjectGroupId != null and dto.subjectGroupId > 0">
         <if test="dto.subjectGroupId != null and dto.subjectGroupId > 0">
             and t1.subject_group_id = #{dto.subjectGroupId}
             and t1.subject_group_id = #{dto.subjectGroupId}
         </if>
         </if>
@@ -121,9 +121,10 @@
     </select>
     </select>
 
 
     <select id="warehouseList" resultType="com.xjrsoft.module.textbook.vo.TextbookWarehouseRecordListVo">
     <select id="warehouseList" resultType="com.xjrsoft.module.textbook.vo.TextbookWarehouseRecordListVo">
-        SELECT t1.create_date AS warehouse_date, t2.name AS warehouse_user, t1.warehouse_number, t1.source
+        SELECT t1.create_date AS warehouse_date, t2.name AS warehouse_user, t1.warehouse_number, t3.name as source
         FROM textbook_warehouse_record t1
         FROM textbook_warehouse_record t1
                  LEFT JOIN xjr_user t2 ON t1.create_user_id = t2.id
                  LEFT JOIN xjr_user t2 ON t1.create_user_id = t2.id
+                 LEFT JOIN xjr_dictionary_detail t3 ON t1.source = t3.code and item_id = 1739821114335490050
         WHERE t1.delete_mark = 0
         WHERE t1.delete_mark = 0
           AND t1.textbook_id = #{id}
           AND t1.textbook_id = #{id}
         order by t1.sort_code
         order by t1.sort_code

+ 0 - 0
src/main/resources/sqlScript/200240428_sql.sql → src/main/resources/sqlScript/20240428_sql.sql


+ 0 - 0
src/main/resources/sqlScript/200240508_sql.sql → src/main/resources/sqlScript/20240508_sql.sql


+ 326 - 8
src/test/java/com/xjrsoft/module/job/AttendanceMessageTaskTest.java

@@ -1,26 +1,344 @@
 package com.xjrsoft.module.job;
 package com.xjrsoft.module.job;
 
 
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.xjrsoft.XjrSoftApplication;
+import com.xjrsoft.common.enums.WeChatType;
+import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.common.utils.WeChatUtil;
+import com.xjrsoft.config.CommonPropertiesConfig;
+import com.xjrsoft.module.attendance.entity.AttendanceMessageSet;
+import com.xjrsoft.module.attendance.entity.AttendanceMessageUserRelation;
+import com.xjrsoft.module.attendance.entity.AttendanceRuleDetails;
+import com.xjrsoft.module.attendance.service.IAttendanceMessageSetService;
+import com.xjrsoft.module.attendance.service.IAttendanceRuleCategoryService;
+import com.xjrsoft.module.concat.service.IXjrUserService;
+import com.xjrsoft.module.holiday.entity.HolidayDate;
+import com.xjrsoft.module.holiday.service.IHolidayDateService;
+import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
+import com.xjrsoft.module.organization.entity.UserRoleRelation;
+import com.xjrsoft.module.organization.service.IWeChatService;
+import com.xjrsoft.module.outint.entity.StudentOutInRecord;
+import com.xjrsoft.module.outint.entity.TeacherOutInRecord;
+import com.xjrsoft.module.outint.service.IStudentOutInRecordService;
+import com.xjrsoft.module.outint.service.ITeacherOutInRecordService;
+import com.xjrsoft.module.student.entity.BaseStudent;
+import com.xjrsoft.module.system.entity.WechatMessageLog;
+import com.xjrsoft.module.system.service.IWechatMessageLogService;
+import com.xjrsoft.module.teacher.entity.BaseTeacher;
+import com.xjrsoft.module.teacher.entity.XjrUser;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
 
 
-import java.time.DayOfWeek;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
-import java.time.format.TextStyle;
-import java.util.Locale;
-
-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.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  * @author dzx
  * @author dzx
  * @date 2024/5/23
  * @date 2024/5/23
  */
  */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = XjrSoftApplication.class)
 class AttendanceMessageTaskTest {
 class AttendanceMessageTaskTest {
+    @Autowired
+    private IAttendanceMessageSetService messageSetService;
+
+    @Autowired
+    private IAttendanceRuleCategoryService ruleCategoryService;
+
+    @Autowired
+    private IHolidayDateService holidayDateService;
+
+    @Autowired
+    private IXjrUserService userService;
+
+    @Autowired
+    private IStudentOutInRecordService studentOutInRecordService;
+
+    @Autowired
+    private ITeacherOutInRecordService teachertOutInRecordService;
+
+    @Autowired
+    private IWeChatService weChatService;
+
+    @Autowired
+    private CommonPropertiesConfig commonPropertiesConfig;
+
+    @Autowired
+    private WeChatUtil weChatUtil;
+
+    @Autowired
+    private IWechatMessageLogService wechatMessageLogService;
+
+
+    @Test
+    void test2(){
+        String  wechatTemplate = "o-KboOcqcJ3YpjPN2xwgM_NcjN-0yzwWlDDXYfTM0Q4";
+        WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
+        weChatSendMessageDto.setTemplateId(wechatTemplate);
+        JSONObject paramJson = new JSONObject();
+
+        JSONObject thing6 = new JSONObject();
+        thing6.put("value", "教职工");
+        paramJson.put("thing6", thing6);
+
+        JSONObject time11 = new JSONObject();
+        time11.put("value", "2024-6-12 11:02:30");
+        paramJson.put("time11", time11);
+
+        JSONObject const23 = new JSONObject();
+        const23.put("value", "上午考勤");
+        paramJson.put("const23", const23);
+
+        JSONObject character_string18 = new JSONObject();
+        character_string18.put("value", "222");
+        paramJson.put("character_string18", character_string18);
+
+        JSONObject const3 = new JSONObject();
+        const3.put("value", "出勤率 99%");
+        paramJson.put("const3", const3);
+
+        weChatSendMessageDto.setContent(paramJson);
+        weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/teacher/index", commonPropertiesConfig.getDomainApp()));
+
+        List<String> userList = new ArrayList<>();
+        userList.add("oWZy-wec72H78ApagVBFomC5TNyw");
+        userList.add("oWZy-wUTki8Vi7ao3Wn5JGNDauVI");
+        for (String xjrUser : userList) {
+            weChatSendMessageDto.setMsgId(xjrUser);
+            weChatSendMessageDto.setUserId(xjrUser);
+            weChatService.sendTemplateMessage(weChatSendMessageDto);
+        }
+
+
+    }
 
 
     @Test
     @Test
     void test(){
     void test(){
+        doExecute();
+    }
+
+    public void doExecute(){
         LocalDateTime now = LocalDateTime.now();
         LocalDateTime now = LocalDateTime.now();
-        DayOfWeek dayOfWeek = now.getDayOfWeek();
+        HolidayDate holidayDate = holidayDateService.getOne(
+                new QueryWrapper<HolidayDate>().lambda()
+                        .eq(HolidayDate::getDate, now.toLocalDate())
+        );
+        if(holidayDate != null && holidayDate.getWay() != null && holidayDate.getWay() != 0){
+            return;
+        }
+        //查询今天的考勤规则
+        List<AttendanceRuleDetails> ruleDetails = ruleCategoryService.getTodayRules();
+        //获取最近的时间
+        LocalDateTime recentlyTime = getRecentlyTime(ruleDetails, now);
+        String wechatTemplate = weChatUtil.getAttendanceMessageTemplate();
+        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;
+//        }
+
+        WechatMessageLog messageLog = new WechatMessageLog();
+        messageLog.setTemplateId(wechatTemplate);
+        messageLog.setSendTime(recentlyTime);
+
+        List<AttendanceMessageSet> list = messageSetService.list(
+                new QueryWrapper<AttendanceMessageSet>().lambda()
+        );
+        //判断是上午还是下午
+        Integer timePeriod = null;
+        String timePeriodStr = null;
+        if(now.getHour() <= 12){
+            timePeriod = 1;
+            timePeriodStr = "上午考勤";
+        }else if(now.getHour() <= 18){
+            timePeriod = 2;
+            timePeriodStr = "下午考勤";
+        }else{
+            timePeriod = 3;
+            timePeriodStr = "晚上考勤";
+        }
+
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        String format = recentlyTime.format(formatter);
 
 
-        String dayName = dayOfWeek.getDisplayName(TextStyle.FULL, Locale.getDefault());
-        System.out.println("今天是:" + dayOfWeek.name());
+
+
+        for (AttendanceMessageSet messageSet : list) {
+            if(!messageSet.getTimePeriod().contains(timePeriod + "")){
+                continue;
+            }
+            //查询需要通知的人
+            List<XjrUser> userList = userService.list(
+                    new MPJLambdaWrapper<XjrUser>()
+                            .select(XjrUser::getId)
+                            .select(XjrUser.class, x -> VoToColumnUtil.fieldsToColumns(XjrUser.class).contains(x.getProperty()))
+                            .leftJoin(UserRoleRelation.class, UserRoleRelation::getUserId, XjrUser::getId)
+                            .leftJoin(AttendanceMessageUserRelation.class, AttendanceMessageUserRelation::getUserId, XjrUser::getId)
+                            .eq(UserRoleRelation::getRoleId, messageSet.getRoleType())
+                            .eq(AttendanceMessageUserRelation::getAttendanceMessageSetId, messageSet.getId())
+            );
+            //没有需要通知的,直接跳过
+            if(userList.isEmpty()){
+                continue;
+            }
+            if(messageSet.getRoleType() != null && messageSet.getRoleType() == 2){
+                //教师总人数
+                long teacherCout = userService.count(
+                        new MPJLambdaWrapper<XjrUser>()
+                                .leftJoin(BaseTeacher.class, BaseTeacher::getUserId, XjrUser::getId)
+                );
+                //查询进入记录,就是实际到校的人数
+                long outInRecords = teachertOutInRecordService.count(
+                        new MPJLambdaWrapper<TeacherOutInRecord>()
+                                .le(TeacherOutInRecord::getRecordTime, recentlyTime)
+                                .eq(TeacherOutInRecord::getStatus, 1)
+                );
+
+                WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
+                weChatSendMessageDto.setTemplateId(wechatTemplate);
+                JSONObject paramJson = new JSONObject();
+
+                JSONObject thing6 = new JSONObject();
+                thing6.put("value", "教职工");
+                paramJson.put("thing6", thing6);
+
+                JSONObject time11 = new JSONObject();
+                time11.put("value", format);
+                paramJson.put("time11", time11);
+
+                JSONObject const23 = new JSONObject();
+                const23.put("value", timePeriodStr);
+                paramJson.put("const23", const23);
+
+                JSONObject character_string18 = new JSONObject();
+                character_string18.put("value", teacherCout - outInRecords);
+                paramJson.put("character_string18", character_string18);
+
+                JSONObject character_string16 = new JSONObject();
+                character_string16.put("value", teacherCout);
+                paramJson.put("character_string16", character_string16);
+
+                weChatSendMessageDto.setContent(paramJson);
+                weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/teacher/index", commonPropertiesConfig.getDomainApp()));
+
+                for (XjrUser xjrUser : userList) {
+                    weChatSendMessageDto.setMsgId(xjrUser.getId().toString());
+                    weChatSendMessageDto.setUserId(xjrUser.getOpenId());
+                    weChatService.sendTemplateMessage(weChatSendMessageDto);
+                }
+            }else if(messageSet.getRoleType() != null && messageSet.getRoleType() == 3){
+                //教师总人数
+                long teacherCout = userService.count(
+                        new MPJLambdaWrapper<XjrUser>()
+                                .leftJoin(BaseStudent.class, BaseStudent::getUserId, XjrUser::getId)
+                );
+                //查询进入记录,就是实际到校的人数
+                long outInRecords = studentOutInRecordService.count(
+                        new MPJLambdaWrapper<StudentOutInRecord>()
+                                .le(StudentOutInRecord::getRecordTime, recentlyTime)
+                                .eq(StudentOutInRecord::getStatus, 1)
+                );
+
+                WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
+                weChatSendMessageDto.setTemplateId(weChatUtil.getAttendanceMessageTemplate());
+                JSONObject paramJson = new JSONObject();
+
+                JSONObject thing6 = new JSONObject();
+                thing6.put("value", "教职工");
+                paramJson.put("thing6", thing6);
+
+                JSONObject time11 = new JSONObject();
+                time11.put("value", format);
+                paramJson.put("time11", time11);
+
+                JSONObject const23 = new JSONObject();
+                const23.put("value", timePeriodStr);
+                paramJson.put("const23", const23);
+
+                JSONObject character_string18 = new JSONObject();
+                character_string18.put("value", teacherCout - outInRecords);
+                paramJson.put("character_string18", character_string18);
+
+                JSONObject character_string16 = new JSONObject();
+                character_string16.put("value", teacherCout);
+                paramJson.put("const3", character_string16);
+
+                weChatSendMessageDto.setContent(paramJson);
+                weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/class/index", commonPropertiesConfig.getDomainApp()));
+
+                for (XjrUser xjrUser : userList) {
+                    weChatSendMessageDto.setMsgId(xjrUser.getId().toString());
+                    weChatSendMessageDto.setUserId(xjrUser.getOpenId());
+                    weChatService.sendTemplateMessage(weChatSendMessageDto);
+                }
+            }
+        }
+        wechatMessageLogService.save(messageLog);
+    }
+
+
+
+    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());
+                    result.add(amStartTime);
+                }
+                if(ruleDetail.getPmStartTime() != null){
+                    LocalDateTime pmStartTime = now.with(ruleDetail.getPmStartTime());
+                    result.add(pmStartTime);
+                }
+
+                if(ruleDetail.getEveningStartTime() != null){
+                    LocalDateTime eveningStartTime = now.with(ruleDetail.getEveningStartTime());
+                    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));
+    }
+
+
+    @Test
+    void getRid(){
+        String url = "https://api.weixin.qq.com/cgi-bin/openapi/rid/get?access_token=" + weChatUtil.getToken(WeChatType.WEWEB);
+        JSONObject rid = new JSONObject();
+        rid.put("rid", "6667fb56-0c3a8942-466e7d5e");
+        String result = HttpUtil.post(url, JSONObject.toJSONString(rid));
+        System.out.print(result);
     }
     }
 }
 }

+ 2 - 1
src/test/java/com/xjrsoft/module/job/HikvisionBaseDataTaskTest.java

@@ -104,7 +104,8 @@ class HikvisionBaseDataTaskTest {
 //        String carTableName = "car_message_apply";
 //        String carTableName = "car_message_apply";
 //        selectCar(use, carTableName);
 //        selectCar(use, carTableName);
 
 
-        outInRecordUtil.GetVisitRecord(use,faceImportMapper);
+//        outInRecordUtil.GetVehicleRecord(use,faceImportMapper);
+        outInRecordUtil.GetTeacherAndStudentRecords(use,faceImportMapper);
 ////        selecAllPersonById(use);
 ////        selecAllPersonById(use);
 //        selectResource(use);
 //        selectResource(use);
     }
     }

+ 49 - 0
src/test/java/com/xjrsoft/module/liteflow/node/ImportStudentFaceNodeTest.java

@@ -0,0 +1,49 @@
+package com.xjrsoft.module.liteflow.node;
+
+import cn.hutool.core.convert.Convert;
+import com.xjrsoft.XjrSoftApplication;
+import com.xjrsoft.module.hikvision.mapper.HikvisionDataMapper;
+import com.xjrsoft.module.hikvision.util.FaceImportUtil;
+import com.xjrsoft.module.personnel.entity.StundentFaceProcess;
+import com.xjrsoft.module.personnel.service.IStundentFaceProcessService;
+import com.xjrsoft.module.teacher.mapper.FaceImportMapper;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author dzx
+ * @date 2024/6/11
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = XjrSoftApplication.class)
+class ImportStudentFaceNodeTest {
+    @Autowired
+    private IStundentFaceProcessService stundentFaceProcessService;
+
+    @Autowired
+    private HikvisionDataMapper hikvisionDataMapper;
+
+    @Autowired
+    private FaceImportMapper faceImportMapper;
+    @Test
+    void test(){
+        Long formId = 1799211798557667328L;
+        if (formId != null) {
+            String fileUrl = faceImportMapper.GetStudentHikvisionImgById(formId);
+            // 数据处理
+            StundentFaceProcess dataObj = stundentFaceProcessService.getById(formId);
+            dataObj.setStatus(1);
+            dataObj.setExamStatus(1);
+            String result = FaceImportUtil.ImportStudentFace(hikvisionDataMapper.getStudentHikvisionId(dataObj.getUserId()), fileUrl);
+            dataObj.setHikvisionResult(result);
+            stundentFaceProcessService.updateById(dataObj);
+
+
+        }
+    }
+}