AttendanceMessageTask.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. package com.xjrsoft.module.job;
  2. import cn.hutool.core.util.StrUtil;
  3. import cn.hutool.extra.spring.SpringUtil;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  6. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  7. import com.xjrsoft.common.utils.VoToColumnUtil;
  8. import com.xjrsoft.common.utils.WeChatUtil;
  9. import com.xjrsoft.config.CommonPropertiesConfig;
  10. import com.xjrsoft.module.attendance.entity.AttendanceMessageSet;
  11. import com.xjrsoft.module.attendance.entity.AttendanceMessageUserRelation;
  12. import com.xjrsoft.module.attendance.entity.AttendanceRuleDetails;
  13. import com.xjrsoft.module.attendance.service.IAttendanceMessageSetService;
  14. import com.xjrsoft.module.attendance.service.IAttendanceRuleCategoryService;
  15. import com.xjrsoft.module.concat.service.IXjrUserService;
  16. import com.xjrsoft.module.holiday.entity.HolidayDate;
  17. import com.xjrsoft.module.holiday.service.IHolidayDateService;
  18. import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
  19. import com.xjrsoft.module.organization.entity.UserRoleRelation;
  20. import com.xjrsoft.module.organization.service.IWeChatService;
  21. import com.xjrsoft.module.outint.entity.StudentOutInRecord;
  22. import com.xjrsoft.module.outint.entity.TeacherOutInRecord;
  23. import com.xjrsoft.module.outint.service.IStudentOutInRecordService;
  24. import com.xjrsoft.module.outint.service.ITeacherOutInRecordService;
  25. import com.xjrsoft.module.student.entity.BaseStudent;
  26. import com.xjrsoft.module.system.entity.WechatMessageLog;
  27. import com.xjrsoft.module.system.service.IWechatMessageLogService;
  28. import com.xjrsoft.module.teacher.entity.BaseTeacher;
  29. import com.xjrsoft.module.teacher.entity.XjrUser;
  30. import com.yomahub.liteflow.util.JsonUtil;
  31. import lombok.extern.slf4j.Slf4j;
  32. import org.springframework.beans.factory.annotation.Autowired;
  33. import org.springframework.scheduling.annotation.Scheduled;
  34. import org.springframework.stereotype.Component;
  35. import java.math.BigDecimal;
  36. import java.math.RoundingMode;
  37. import java.time.LocalDateTime;
  38. import java.time.format.DateTimeFormatter;
  39. import java.time.temporal.ChronoUnit;
  40. import java.util.ArrayList;
  41. import java.util.Collections;
  42. import java.util.Date;
  43. import java.util.HashMap;
  44. import java.util.List;
  45. import java.util.Map;
  46. import java.util.stream.Collectors;
  47. /**
  48. * 考勤消息通知,给领导推送每个时段的考勤情况
  49. * @author dzx
  50. * @date 2024年6月7日
  51. */
  52. @Component
  53. @Slf4j
  54. public class AttendanceMessageTask {
  55. @Autowired
  56. private IAttendanceMessageSetService messageSetService;
  57. @Autowired
  58. private IAttendanceRuleCategoryService ruleCategoryService;
  59. @Autowired
  60. private IHolidayDateService holidayDateService;
  61. @Autowired
  62. private IXjrUserService userService;
  63. @Autowired
  64. private IStudentOutInRecordService studentOutInRecordService;
  65. @Autowired
  66. private ITeacherOutInRecordService teachertOutInRecordService;
  67. @Autowired
  68. private IWeChatService weChatService;
  69. @Autowired
  70. private CommonPropertiesConfig commonPropertiesConfig;
  71. @Autowired
  72. private WeChatUtil weChatUtil;
  73. @Autowired
  74. private IWechatMessageLogService wechatMessageLogService;
  75. @Scheduled(cron = "0 */15 * * * ?")
  76. public void RefreshConnectionPool() {
  77. String active = SpringUtil.getActiveProfile();
  78. if(!"prod".equals(active)){
  79. log.info("非正式环境,无法执行数据推送");
  80. return;
  81. }
  82. doExecute();
  83. }
  84. public void doExecute(){
  85. LocalDateTime now = LocalDateTime.now();
  86. HolidayDate holidayDate = holidayDateService.getOne(
  87. new QueryWrapper<HolidayDate>().lambda()
  88. .eq(HolidayDate::getDate, now.toLocalDate())
  89. );
  90. if(holidayDate != null && holidayDate.getWay() != null && holidayDate.getWay() != 0){
  91. log.info("非工作日,不需要提醒");
  92. return;
  93. }
  94. //查询今天的考勤规则
  95. List<AttendanceRuleDetails> ruleDetails = ruleCategoryService.getTodayRules();
  96. //获取最近的时间
  97. LocalDateTime recentlyTime = getRecentlyTime(ruleDetails, now);
  98. String wechatTemplate = weChatUtil.getAttendanceMessageTemplate();
  99. WechatMessageLog log = wechatMessageLogService.getOne(
  100. new QueryWrapper<WechatMessageLog>().lambda()
  101. .select(WechatMessageLog.class, x -> VoToColumnUtil.fieldsToColumns(WechatMessageLog.class).contains(x.getProperty()))
  102. .eq(WechatMessageLog::getSendTime, recentlyTime)
  103. .eq(WechatMessageLog::getTemplateId, wechatTemplate)
  104. );
  105. if(log != null){//已经推送过,不再进行推送
  106. return;
  107. }
  108. WechatMessageLog messageLog = new WechatMessageLog();
  109. messageLog.setTemplateId(wechatTemplate);
  110. messageLog.setSendTime(recentlyTime);
  111. List<AttendanceMessageSet> list = messageSetService.list(
  112. new QueryWrapper<AttendanceMessageSet>().lambda()
  113. );
  114. //判断是上午还是下午
  115. Integer timePeriod = null;
  116. String timePeriodStr = null;
  117. if(now.getHour() <= 12){
  118. timePeriod = 1;
  119. timePeriodStr = "上午考勤";
  120. }else if(now.getHour() <= 18){
  121. timePeriod = 2;
  122. timePeriodStr = "下午考勤";
  123. }else{
  124. timePeriod = 3;
  125. timePeriodStr = "晚上考勤";
  126. }
  127. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  128. String format = recentlyTime.format(formatter);
  129. int userCount = 0;
  130. for (AttendanceMessageSet messageSet : list) {
  131. if(!messageSet.getTimePeriod().contains(timePeriod + "")){
  132. continue;
  133. }
  134. //查询需要通知的人
  135. List<XjrUser> userList = userService.list(
  136. new MPJLambdaWrapper<XjrUser>()
  137. .select(XjrUser::getId)
  138. .select(XjrUser.class, x -> VoToColumnUtil.fieldsToColumns(XjrUser.class).contains(x.getProperty()))
  139. .leftJoin(UserRoleRelation.class, UserRoleRelation::getUserId, XjrUser::getId)
  140. .leftJoin(AttendanceMessageUserRelation.class, AttendanceMessageUserRelation::getUserId, XjrUser::getId)
  141. .eq(UserRoleRelation::getRoleId, messageSet.getRoleType())
  142. .eq(AttendanceMessageUserRelation::getAttendanceMessageSetId, messageSet.getId())
  143. );
  144. //没有需要通知的,直接跳过
  145. if(userList.isEmpty()){
  146. continue;
  147. }
  148. userCount += userList.size();
  149. if(messageSet.getRoleType() != null && messageSet.getRoleType() == 2){
  150. //教师总人数
  151. long teacherCout = userService.count(
  152. new MPJLambdaWrapper<XjrUser>()
  153. .leftJoin(BaseTeacher.class, BaseTeacher::getUserId, XjrUser::getId)
  154. );
  155. //查询进入记录,就是实际到校的人数
  156. long outInRecords = teachertOutInRecordService.count(
  157. new MPJLambdaWrapper<TeacherOutInRecord>()
  158. .le(TeacherOutInRecord::getRecordTime, recentlyTime)
  159. .eq(TeacherOutInRecord::getStatus, 1)
  160. );
  161. WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
  162. weChatSendMessageDto.setTemplateId(wechatTemplate);
  163. JSONObject paramJson = new JSONObject();
  164. JSONObject thing6 = new JSONObject();
  165. thing6.put("value", "教职工");
  166. paramJson.put("thing6", thing6);
  167. JSONObject time11 = new JSONObject();
  168. time11.put("value", format);
  169. paramJson.put("time11", time11);
  170. JSONObject const23 = new JSONObject();
  171. const23.put("value", timePeriodStr);
  172. paramJson.put("const23", const23);
  173. JSONObject character_string18 = new JSONObject();
  174. character_string18.put("value", teacherCout - outInRecords);
  175. paramJson.put("character_string18", character_string18);
  176. JSONObject character_string16 = new JSONObject();
  177. character_string16.put("value", teacherCout);
  178. paramJson.put("character_string16", character_string16);
  179. weChatSendMessageDto.setContent(paramJson);
  180. weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/teacher/index", commonPropertiesConfig.getDomainApp()));
  181. for (XjrUser xjrUser : userList) {
  182. weChatSendMessageDto.setMsgId(xjrUser.getId().toString());
  183. weChatSendMessageDto.setUserId(xjrUser.getOpenId());
  184. weChatService.sendTemplateMessage(weChatSendMessageDto);
  185. }
  186. }else if(messageSet.getRoleType() != null && messageSet.getRoleType() == 3){
  187. //教师总人数
  188. long teacherCout = userService.count(
  189. new MPJLambdaWrapper<XjrUser>()
  190. .leftJoin(BaseStudent.class, BaseStudent::getUserId, XjrUser::getId)
  191. );
  192. //查询进入记录,就是实际到校的人数
  193. long outInRecords = studentOutInRecordService.count(
  194. new MPJLambdaWrapper<StudentOutInRecord>()
  195. .le(StudentOutInRecord::getRecordTime, recentlyTime)
  196. .eq(StudentOutInRecord::getStatus, 1)
  197. );
  198. WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
  199. weChatSendMessageDto.setTemplateId(weChatUtil.getAttendanceMessageTemplate());
  200. JSONObject paramJson = new JSONObject();
  201. JSONObject thing6 = new JSONObject();
  202. thing6.put("value", "教职工");
  203. paramJson.put("thing6", thing6);
  204. JSONObject time11 = new JSONObject();
  205. time11.put("value", format);
  206. paramJson.put("time11", time11);
  207. JSONObject const23 = new JSONObject();
  208. const23.put("value", timePeriodStr);
  209. paramJson.put("const23", const23);
  210. JSONObject character_string18 = new JSONObject();
  211. character_string18.put("value", teacherCout - outInRecords);
  212. paramJson.put("character_string18", character_string18);
  213. JSONObject character_string16 = new JSONObject();
  214. character_string16.put("value", teacherCout);
  215. paramJson.put("const3", character_string16);
  216. weChatSendMessageDto.setContent(paramJson);
  217. weChatSendMessageDto.setUrl(StrUtil.format("{}pages/attendance/class/index", commonPropertiesConfig.getDomainApp()));
  218. for (XjrUser xjrUser : userList) {
  219. weChatSendMessageDto.setMsgId(xjrUser.getId().toString());
  220. weChatSendMessageDto.setUserId(xjrUser.getOpenId());
  221. weChatService.sendTemplateMessage(weChatSendMessageDto);
  222. }
  223. }
  224. }
  225. messageLog.setCreateDate(new Date());
  226. messageLog.setContent("消息推送人数:" + userCount);
  227. wechatMessageLogService.save(messageLog);
  228. }
  229. LocalDateTime getRecentlyTime(List<AttendanceRuleDetails> ruleDetails, LocalDateTime now){
  230. List<LocalDateTime> result = new ArrayList<>();
  231. for (AttendanceRuleDetails ruleDetail : ruleDetails) {
  232. if(ruleDetail.getIsAllowInOutSchool() != null && ruleDetail.getIsAllowInOutSchool() == 1
  233. && ruleDetail.getIsAttendance() != null && ruleDetail.getIsAttendance() == 1){
  234. if(ruleDetail.getAmStartTime() != null){
  235. LocalDateTime amStartTime = now.with(ruleDetail.getAmStartTime());
  236. result.add(amStartTime);
  237. }
  238. if(ruleDetail.getPmStartTime() != null){
  239. LocalDateTime pmStartTime = now.with(ruleDetail.getPmStartTime());
  240. result.add(pmStartTime);
  241. }
  242. if(ruleDetail.getEveningStartTime() != null){
  243. LocalDateTime eveningStartTime = now.with(ruleDetail.getEveningStartTime());
  244. result.add(eveningStartTime);
  245. }
  246. }
  247. }
  248. if(result.isEmpty()){
  249. return null;
  250. }
  251. Map<Long, LocalDateTime> timeMap = new HashMap<>();
  252. for (LocalDateTime localDateTime : result) {
  253. long between = ChronoUnit.SECONDS.between(now, localDateTime);
  254. timeMap.put(Math.abs(between), localDateTime);
  255. }
  256. List<Long> collect = timeMap.keySet().stream().collect(Collectors.toList());
  257. Collections.sort(collect, Long::compare);
  258. return timeMap.get(collect.get(0));
  259. }
  260. }