Kaynağa Gözat

Merge branch 'pre'

dzx 1 yıl önce
ebeveyn
işleme
12bf4646b7
24 değiştirilmiş dosya ile 776 ekleme ve 163 silme
  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());
                         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){
-                            paramJson.put("const4", "进校");
+                            const4.put("value", "进校");
                         }else{
-                            paramJson.put("const4", "出校");
+                            const4.put("value", "出校");
                         }
 
+                        paramJson.put("const4", const4);
+
                         weChatSendMessageDto.setContent(paramJson);
                         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.JsonElement;
 import com.google.gson.JsonObject;
+import com.microsoft.schemas.office.office.BulletAttribute;
 import com.xjrsoft.module.attendance.entity.AttendanceRuleDetails;
 import com.xjrsoft.module.teacher.mapper.FaceImportMapper;
 import org.slf4j.Logger;
@@ -25,17 +26,20 @@ public class OutInRecordUtil {
     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 {
+        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) " +
                 "VALUES(now(), '"  + userId + "', '" + recordTime + "', '" +
-                facePhoto + "', '" + eventId + "', '" +status + "',0,1,'" + attendanceStatus + "')";
+                photoValue + "', '" + eventId + "', '" +status + "',0,1,'" + attendanceStatus + "')";
         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 {
+        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) " +
                 "VALUES(now(), '" + userId + "', '" + teacherId + "', '" +
-                classId + "', '" + facePhoto + "', '" + recordTime + "', '" + eventId + "', '" + status + "',0,1,'" + attendanceStatus + "')";
+                classId + "', '" + photoValue + "', '" + recordTime + "', '" + eventId + "', '" + status + "',0,1,'" + attendanceStatus + "')";
         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,
                                      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, " +
                 "cross_record_syscode, release_result, release_way, vehicle_type, phone, name, category,delete_mark,enabled_mark) " +
                 "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);
     }
 
@@ -97,7 +105,17 @@ public class OutInRecordUtil {
             }
             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 recordTime = item.get("eventTime").isJsonNull() ? null : item.get("eventTime").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);
                 String attendanceStatus = discernStudentStatus(use, recordTimeDate, status, 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;
     }
 
-
     String discernStudentStatus(Db use, LocalDateTime recordTime, int status, Long studentUserId) throws SQLException {
         String attendanceStatus = "";
         String dayOfWeek = recordTime.getDayOfWeek().name();
@@ -361,7 +378,7 @@ public class OutInRecordUtil {
             JsonObject item = element.getAsJsonObject();
 
             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;
             int categoryInt = 0;
             if (item.has("carCategory")){
@@ -417,16 +434,7 @@ public class OutInRecordUtil {
             System.out.println(facePicUri + "haha");
 
             String phone = faceImportMapper.GetPhoneNumberByPlanNum(plateNo);
-            if (phone == null){
-                phone = faceImportMapper.GetPhoneNumberByPlanNumView(plateNo);
-                if (phone == null) phone = "";
-            }
-
             String name = faceImportMapper.GetNameByPlanNum(plateNo);
-            if (name == null){
-                name = faceImportMapper.GetNameByPlanNumView(plateNo);
-                if (name == null) name = "";
-            }
 
             if(vehicle_id_list.contains(crossRecordSyscode)) continue;
 
@@ -467,11 +475,23 @@ public class OutInRecordUtil {
 
                 String idNum = null;
                 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 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 recordTimeStr = ChangeTime(happenTime);
 
@@ -517,16 +537,18 @@ public class OutInRecordUtil {
                     String carNum = dataObject.get("plateNo").getAsString().trim();
                     String eventIndex = dataObject.get("eventIndex").getAsString().trim();
                     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());
 
-                    int releaseWayInt = 0;
-                    int releaseReasonInt = 0;
-                    int releaseResultInt = 0;
+                    int releaseWayInt = -1;
+                    int releaseReasonInt = -1;
+                    int releaseResultInt = -1;
                     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();
                             releaseReasonInt = rlsResultObject.get("releaseReason").getAsInt();
                             releaseResultInt = rlsResultObject.get("releaseResult").getAsInt();
@@ -551,28 +573,16 @@ public class OutInRecordUtil {
                         facePicUri = picUrlObject.get("vehiclePicUrl").getAsString();
                     }
 
-                    int status = eventObject.get("status").getAsInt();
+                    String statusStr = dataObject.get("roadwayName").getAsString();
                     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);
-                    if (phone == null){
-                        phone = faceImportMapper.GetPhoneNumberByPlanNumView(carNum);
-                        if (phone == null) phone = "";
-                    }
-
                     String name = faceImportMapper.GetNameByPlanNum(carNum);
-                    if (name == null){
-                        name = faceImportMapper.GetNameByPlanNumView(carNum);
-                        if (name == null) name = "";
-                    }
 
                     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;
 
+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;
@@ -10,6 +11,8 @@ 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 lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -19,13 +22,15 @@ import org.springframework.stereotype.Component;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 /**
- * 考勤预警通知
+ * 考勤预警通知,提醒教师和学生是否该上课等
  * @author dzx
  * @date 2024年5月21日
  */
@@ -47,8 +52,16 @@ public class AttenDanceWarnNoticeTask {
     @Autowired
     private WeChatUtil weChatUtil;
 
+    @Autowired
+    private IWechatMessageLogService wechatMessageLogService;
+
     @Scheduled(cron = "0 */10 * * * ?")
     public void RefreshConnectionPool() {
+        String active = SpringUtil.getActiveProfile();
+        if(!"prod".equals(active)){
+            log.info("非正式环境,无法执行数据推送");
+            return;
+        }
         //获取当前时间
         LocalDateTime now = LocalDateTime.now();
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@@ -78,8 +91,14 @@ public class AttenDanceWarnNoticeTask {
 
         //根据规则中的用户id查询出所有绑定了微信的学生和教师
         if(allTodyRule.isEmpty()){
+            log.info("未能查询出规则,不进行推送");
             return;
         }
+        String wechatTemplate = weChatUtil.getAttenDanceWarnTemplate();
+        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());
@@ -90,23 +109,35 @@ public class AttenDanceWarnNoticeTask {
 
             WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
             weChatSendMessageDto.setUserId(xjrUser.getOpenId());
-            weChatSendMessageDto.setTemplateId(weChatUtil.getAttenDanceWarnTemplate());
+            weChatSendMessageDto.setTemplateId(wechatTemplate);
             weChatSendMessageDto.setMsgId(xjrUser.getId().toString());
             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){
-                paramJson.put("const12", "进校");
+                const12.put("value", "进校");
             }else{
-                paramJson.put("const12", "出校");
+                const12.put("value", "出校");
             }
-
-
+            paramJson.put("const12", const12);
 
             weChatSendMessageDto.setContent(paramJson);
             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.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.common.utils.WeChatUtil;
 import com.xjrsoft.config.CommonPropertiesConfig;
 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.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 com.yomahub.liteflow.util.JsonUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
@@ -37,13 +41,14 @@ 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.stream.Collectors;
 
 /**
- * 考勤消息通知
+ * 考勤消息通知,给领导推送每个时段的考勤情况
  * @author dzx
  * @date 2024年6月7日
  */
@@ -77,6 +82,9 @@ public class AttendanceMessageTask {
     @Autowired
     private WeChatUtil weChatUtil;
 
+    @Autowired
+    private IWechatMessageLogService wechatMessageLogService;
+
     @Scheduled(cron = "0 */15 * * * ?")
     public void RefreshConnectionPool() {
         String active = SpringUtil.getActiveProfile();
@@ -84,12 +92,16 @@ public class AttendanceMessageTask {
             log.info("非正式环境,无法执行数据推送");
             return;
         }
+        doExecute();
+    }
+
+    public void doExecute(){
         LocalDateTime now = LocalDateTime.now();
         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("非工作日,不需要提醒");
             return;
         }
@@ -97,9 +109,23 @@ public class AttendanceMessageTask {
         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()
+                new QueryWrapper<AttendanceMessageSet>().lambda()
         );
         //判断是上午还是下午
         Integer timePeriod = null;
@@ -118,6 +144,8 @@ public class AttendanceMessageTask {
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         String format = recentlyTime.format(formatter);
 
+        int userCount = 0;
+
         for (AttendanceMessageSet messageSet : list) {
             if(!messageSet.getTimePeriod().contains(timePeriod + "")){
                 continue;
@@ -125,6 +153,8 @@ public class AttendanceMessageTask {
             //查询需要通知的人
             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())
@@ -134,34 +164,43 @@ public class AttendanceMessageTask {
             if(userList.isEmpty()){
                 continue;
             }
+            userCount += userList.size();
             if(messageSet.getRoleType() != null && messageSet.getRoleType() == 2){
                 //教师总人数
                 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(
-                    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.setTemplateId(weChatUtil.getAttendanceMessageTemplate());
+                weChatSendMessageDto.setTemplateId(wechatTemplate);
                 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.setUrl(StrUtil.format("{}pages/attendance/teacher/index", commonPropertiesConfig.getDomainApp()));
@@ -174,32 +213,39 @@ public class AttendanceMessageTask {
             }else if(messageSet.getRoleType() != null && messageSet.getRoleType() == 3){
                 //教师总人数
                 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(
-                    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.setTemplateId(weChatUtil.getAttendanceMessageTemplate());
                 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.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){
         List<LocalDateTime> result = new ArrayList<>();
         for (AttendanceRuleDetails ruleDetail : ruleDetails) {
-            if(ruleDetail.getIsAllowInOutSchool() != null && ruleDetail.getIsAllowInOutSchool() != 1
+            if(ruleDetail.getIsAllowInOutSchool() != null && ruleDetail.getIsAllowInOutSchool() == 1
                     && ruleDetail.getIsAttendance() != null && ruleDetail.getIsAttendance() == 1){
                 if(ruleDetail.getAmStartTime() != null){
                     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.utils.TreeUtil;
 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.service.IBaseSemesterService;
 import com.xjrsoft.module.student.dto.AddPbSemesterConfigDto;
@@ -56,7 +57,10 @@ public class PbSemesterConfigController {
     @ApiOperation(value = "年和学期树")
     @SaCheckPermission("pbsemesterconfig:detail")
     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 -> {
             // 处理元素

+ 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 GetNameByPlanNum(@Param("id") String id);
 
-    String GetPhoneNumberByPlanNumView(@Param("id") String id);
-    String GetNameByPlanNumView(@Param("id") String id);
-
     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.PageOutput;
 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.BaseSemester;
 import com.xjrsoft.module.base.service.IBaseSemesterService;
 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.entity.Textbook;
 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.vo.*;
 import io.swagger.annotations.Api;
@@ -84,11 +81,11 @@ public class TextbookController {
                 .selectAs(BaseCourseSubject::getName, TextbookSubscriptionListVo::getCourseSubjectIdCn)
                 .selectSum(BaseClassMajorSet::getTotalStudent, TextbookSubscriptionListVo::getStudentSubscriptionNumber)
                 .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)
-                .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)
         ;
         IPage<TextbookSubscriptionListVo> page = textbookService.selectJoinListPage(ConventPage.getPage(dto),TextbookSubscriptionListVo.class,textbookMPJLambdaWrapper);
@@ -102,8 +99,9 @@ public class TextbookController {
         return RT.ok(pageOutput);
     }
 
+    // TODO 学生确认领取教材列表
     @GetMapping(value = "/page-consumption")
-    @ApiOperation(value="教材管理列表(分页,学生收费用)")
+    @ApiOperation(value="学生确认领取教材列表(分页,学生收费用)")
     @SaCheckPermission("textbook:detail")
     public RT<PageOutput<TextbookConsumptionPageVo>> pageConsumption(@Valid TextbookConsumptionPageDto dto){
         MPJLambdaWrapper<Textbook> textbookMPJLambdaWrapper = new MPJLambdaWrapper<>();
@@ -158,7 +156,7 @@ public class TextbookController {
     @GetMapping(value = "/info-detail")
     @ApiOperation(value="根据id查询教材管理信息")
     @SaCheckPermission("textbook:detail")
-    public RT<TextbookVo> info(@RequestParam Long id){
+    public RT info(@RequestParam Long id){
         Textbook textbook = textbookService.getById(id);
         if (textbook == null) {
            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子表")
     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);
             for (TextbookSubscriptionRecordVo recordVo : recordVos) {
                 if (ObjectUtil.isNull(recordVo) || StrUtil.isEmpty(recordVo.getClassIds())) {
-                    recordVos.remove(recordVo);
-                    if (recordVos.isEmpty()) {
-                        break;
-                    }
+//                    recordVos.remove(recordVo);
+//                    if (recordVos.isEmpty()) {
+//                        break;
+//                    }
                     continue;
                 }
                 String[] split = recordVo.getClassIds().split(",");

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

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

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

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

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

@@ -114,7 +114,7 @@ xjrsoft:
   weChatMessageTemplate:
     commonTemplate: qmpXORPM1Cocqn503Qa4OkNNQ0uxlj2-ed9m6uWO-v4
     assessmentTemplate: ehYfXni7exZUmt6dJX4Ukbm9ETarFfKLfXVYwNnjKMc
-    attendanceMessageTemplate: uPPJkWOSronnB_GJolcnatrQzGjJREIKL7JZzOieoew
+    attendanceMessageTemplate: uPPJkWOSronnB_GJolcnajRSdnIf8GCoCk4c0v1szPA
     outInTemplate: ERkMebHjsziZO6WBrlzsbENiEuRR4vrlhJw5LR4aDr8
     attenDanceWarnTemplate: Fg4AWVQRGernl0PiJQ8gRgCUFHEGZuizlClQNuVhqu4
   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
         WHERE t.delete_mark = 0
         <if test="dto.className != null and dto.className != ''">
-            and t.name = #{dto.className}
+            and t.name = like concat('%', #{dto.className}, '%')
         </if>
         <if test="dto.deptId != null">
             and t4.id = #{dto.deptId}

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

@@ -125,38 +125,18 @@
     </select>
 
     <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">
-            and car_no = #{id}
+            where 车牌号码 = #{id}
         </if>
     </select>
 
     <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">
-            and plate_number = #{id}
+            where 车牌号码 = #{id}
         </if>
     </select>
 

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

@@ -23,9 +23,9 @@
         <if test="dto.textbookType != null and dto.textbookType != ''">
             and t1.textbook_type = #{dto.textbookType}
         </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">
             and t1.subject_group_id = #{dto.subjectGroupId}
         </if>
@@ -121,9 +121,10 @@
     </select>
 
     <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
                  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
           AND t1.textbook_id = #{id}
         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;
 
+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.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.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
  * @date 2024/5/23
  */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = XjrSoftApplication.class)
 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
     void test(){
+        doExecute();
+    }
+
+    public void doExecute(){
         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";
 //        selectCar(use, carTableName);
 
-        outInRecordUtil.GetVisitRecord(use,faceImportMapper);
+//        outInRecordUtil.GetVehicleRecord(use,faceImportMapper);
+        outInRecordUtil.GetTeacherAndStudentRecords(use,faceImportMapper);
 ////        selecAllPersonById(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);
+
+
+        }
+    }
+}