package com.kym.admin.jobs; import cn.hutool.extra.mail.MailUtil; import com.kym.common.utils.CommUtil; import com.kym.entity.common.RedisKeys; import com.kym.service.cache.KymCache; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Comparator; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** * @author skyline * @description 设备离线通知 * @date 2023-09-30 16:15 */ @Component @Slf4j public class OfflineNotifyJob { private final StringRedisTemplate redisTemplate; @Value("${kym.notify-email}") private String notifyEmail; public OfflineNotifyJob(StringRedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } // 每小时的第30分钟执行一次 // @Scheduled(cron = "0 30 0/1 * * ? ") public void execute() { // 查询redis离线设备消息队列,存在且超过1小时的消息则发送邮件提醒 Set offlineList = redisTemplate.opsForZSet().rangeByScore(RedisKeys.OFFLINE, System.currentTimeMillis() - 60 * 60 * 1000, System.currentTimeMillis() + 60 * 60 * 1000); if (!CommUtil.isEmptyOrNull(offlineList)) { /* * 格式: * 【设备离线通知】 * 【阳光科创中心】:001001,001002,001003 * 【阳光粤海家园】:002001,002002,002003 */ var temp = "【%s】:%s\n"; var map = new ArrayList(offlineList).stream() .collect(Collectors.toMap(KymCache.INSTANCE::getShortIdByEquipmentIdOrConnectorId, KymCache.INSTANCE::getStationNameByConnectorId)); // 以站点名称分组 var list = map.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue)); StringBuilder sb = new StringBuilder(); list.forEach((k, v) -> sb.append(temp.formatted(k, StringUtils.join(v.stream().map(Map.Entry::getKey).sorted(Comparator.comparingInt(Integer::parseInt)).toList(), ",")))); log.warn(sb.toString()); // 格式化信息,发送邮件 MailUtil.send(notifyEmail, "【设备离线通知】", sb.toString(), false); redisTemplate.opsForZSet().remove(RedisKeys.OFFLINE, offlineList.toArray(Object[]::new)); redisTemplate.opsForSet().add(RedisKeys.OFFLINE_EXPIRED, offlineList.toArray(String[]::new)); } } }