diff --git a/cs-device/cs-device-boot/src/main/java/com/njcn/csdevice/service/impl/CsDeviceUserPOServiceImpl.java b/cs-device/cs-device-boot/src/main/java/com/njcn/csdevice/service/impl/CsDeviceUserPOServiceImpl.java index e774baf..efe7d9d 100644 --- a/cs-device/cs-device-boot/src/main/java/com/njcn/csdevice/service/impl/CsDeviceUserPOServiceImpl.java +++ b/cs-device/cs-device-boot/src/main/java/com/njcn/csdevice/service/impl/CsDeviceUserPOServiceImpl.java @@ -462,16 +462,16 @@ public class CsDeviceUserPOServiceImpl extends ServiceImpl list = this.lambdaQuery().eq(CsDeviceUserPO::getDeviceId, devId).eq(CsDeviceUserPO::getStatus, "1").list(); if (CollectionUtils.isEmpty(list)) { - throw new BusinessException(AlgorithmResponseEnum.DATA_ARRAY_MISSING); + return devUser; } List collect = list.stream().map(CsDeviceUserPO::getSubUserId).distinct().collect(Collectors.toList()); List data = userFeignClient.appuserByIdList(collect).getData(); String primaryUserId = list.get(0).getPrimaryUserId(); List subUser = data.stream().filter(temp -> !Objects.equals(temp.getId(), primaryUserId)).collect(Collectors.toList()); List primaryUser = data.stream().filter(temp -> Objects.equals(temp.getId(), primaryUserId)).collect(Collectors.toList()); - DevUserVO devUser = new DevUserVO(); devUser.setDevId(devId); devUser.setSubUsers(subUser); devUser.setMasterUser(primaryUser.get(0)); diff --git a/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/CsHarmonicBootApplication.java b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/CsHarmonicBootApplication.java index 874165a..3967855 100644 --- a/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/CsHarmonicBootApplication.java +++ b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/CsHarmonicBootApplication.java @@ -6,6 +6,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.DependsOn; +import org.springframework.scheduling.annotation.EnableAsync; /** @@ -18,6 +19,7 @@ import org.springframework.context.annotation.DependsOn; @EnableFeignClients(basePackages = "com.njcn") @SpringBootApplication(scanBasePackages = "com.njcn") @DependsOn("proxyMapperRegister") +@EnableAsync public class CsHarmonicBootApplication { public static void main(String[] args) { diff --git a/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/config/AsyncConfig.java b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/config/AsyncConfig.java new file mode 100644 index 0000000..e071d4c --- /dev/null +++ b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/config/AsyncConfig.java @@ -0,0 +1,42 @@ +package com.njcn.csharmonic.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * @author xy + */ +@Configuration +@Slf4j +public class AsyncConfig implements AsyncConfigurer { + + @Bean("eventNotificationExecutor") + public Executor eventNotificationExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(10); + executor.setMaxPoolSize(20); + executor.setQueueCapacity(200); + executor.setThreadNamePrefix("event-notify-"); + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + executor.initialize(); + return executor; + } + + @Bean("smsNotificationExecutor") + public Executor smsNotificationExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(5); + executor.setMaxPoolSize(10); + executor.setQueueCapacity(100); + executor.setThreadNamePrefix("sms-notify-"); + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + executor.initialize(); + return executor; + } +} \ No newline at end of file diff --git a/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/AppNotificationService.java b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/AppNotificationService.java new file mode 100644 index 0000000..3a64c5d --- /dev/null +++ b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/AppNotificationService.java @@ -0,0 +1,113 @@ +package com.njcn.csharmonic.service; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DatePattern; +import com.njcn.access.pojo.dto.NoticeUserDto; +import com.njcn.access.utils.SendMessageUtil; +import com.njcn.csdevice.api.DeviceMessageFeignClient; +import com.njcn.csdevice.param.DeviceMessageParam; +import com.njcn.csdevice.pojo.dto.DevDetailDTO; +import com.njcn.csharmonic.pojo.po.CsEventUserPO; +import com.njcn.system.api.EpdFeignClient; +import com.njcn.user.pojo.po.User; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author xy + */ +@Service +@Slf4j +@RequiredArgsConstructor +public class AppNotificationService { + + private final EpdFeignClient epdFeignClient; + private final SendMessageUtil sendMessageUtil; + private final DeviceMessageFeignClient deviceMessageClient; + private final CsEventUserPOService csEventUserPOService; + + @Async("eventNotificationExecutor") + public void asyncSaveEventUserAndNotify(String eventId + , List eventUser + , DevDetailDTO devDetailDto + , LocalDateTime time + , Integer eventType + , Double amplitude + , Double persistTime) { + NoticeUserDto noticeUserDto = new NoticeUserDto(); + NoticeUserDto.Payload payload = new NoticeUserDto.Payload(); + List result = new ArrayList<>(); + + eventUser.forEach(item -> { + CsEventUserPO csEventUser = new CsEventUserPO(); + csEventUser.setUserId(item); + csEventUser.setStatus(0); + csEventUser.setEventId(eventId); + result.add(csEventUser); + }); + + DeviceMessageParam param = new DeviceMessageParam(); + param.setUserList(eventUser); + param.setEventType(0); + List users = deviceMessageClient.getSendUserByType(param).getData(); + if (CollectionUtil.isNotEmpty(users)) { + List devCodeList = users.stream().map(User::getDevCode).distinct().collect(Collectors.toList()); + noticeUserDto.setPushClientId(devCodeList); + noticeUserDto.setTitle("暂态事件"); + } + + String eventName = epdFeignClient.findByName(getTag(eventType)).getData().getShowName(); + String content = devDetailDto.getEngineeringName() + "-" + devDetailDto.getProjectName() + "-" + devDetailDto.getEquipmentName() + + "于" + time.format(DatePattern.NORM_DATETIME_MS_FORMATTER) + "发生暂态事件,事件类型:" + + eventName + + ",特征幅值:" + amplitude + "%" + + ",持续时间:" + persistTime + "s"; + noticeUserDto.setContent(content); + payload.setType(0); + payload.setPath("/pages/index/message1?type=" + payload.getType()); + noticeUserDto.setPayload(payload); + + if (CollectionUtil.isNotEmpty(noticeUserDto.getPushClientId())) { + List filteredList = noticeUserDto.getPushClientId().stream() + .filter(s -> s != null && !s.isEmpty()) + .distinct() + .collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(filteredList)) { + noticeUserDto.setPushClientId(filteredList); + sendMessageUtil.sendEventToUser(noticeUserDto); + } + } + if (CollectionUtil.isNotEmpty(result)) { + csEventUserPOService.saveBatch(result); + } + } + + public String getTag(Integer type) { + String tag; + switch (type) { + case 1: + tag = "Evt_Sys_DipStr"; + break; + case 2: + tag = "Evt_Sys_SwlStr"; + break; + case 3: + tag = "Evt_Sys_IntrStr"; + break; + case 4: + tag = "Transient"; + break; + default: + tag = "Un_Know"; + break; + } + return tag; + } +} diff --git a/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/SmsNotificationService.java b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/SmsNotificationService.java new file mode 100644 index 0000000..f633999 --- /dev/null +++ b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/SmsNotificationService.java @@ -0,0 +1,60 @@ +package com.njcn.csharmonic.service; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.util.StrUtil; +import com.njcn.csdevice.api.SmsSendFeignClient; +import com.njcn.csdevice.pojo.dto.DevDetailDTO; +import com.njcn.cssystem.api.AppMsgSetFeignClient; +import com.njcn.user.api.UserFeignClient; +import com.njcn.user.pojo.po.User; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author xy + */ +@Service +@Slf4j +@RequiredArgsConstructor +public class SmsNotificationService { + private final AppMsgSetFeignClient appMsgSetFeignClient; + private final UserFeignClient userFeignClient; + private final SmsSendFeignClient smsSendFeignClient; + @Value("${msg.msg_sign:南京灿能电力}") + private String msgSign; + + @Async("smsNotificationExecutor") + public void asyncSendSmsNotification(String deviceId + , DevDetailDTO devDetailDto + , LocalDateTime eventTime + , Double amplitude + , Double persistTime) { + List userIdList = appMsgSetFeignClient.queryUserIdsByDeviceId(deviceId).getData(); + if (CollectionUtil.isNotEmpty(userIdList)) { + List userList = userFeignClient.getUserListByIds(userIdList).getData(); + if (CollectionUtil.isNotEmpty(userList)) { + List userList1 = userList.stream() + .filter(item -> StrUtil.isNotBlank(item.getPhone()) && Objects.equals(item.getSmsNotice(), 1)) + .collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(userList1)) { + String msgContent = "【" + msgSign + "】" + devDetailDto.getEngineeringName() + "-" + devDetailDto.getProjectName() + "-" + devDetailDto.getEquipmentName() + + "于" + eventTime.format(DatePattern.NORM_DATETIME_MS_FORMATTER) + "发生暂降事件" + + ",特征幅值:" + amplitude + "%" + + ",持续时间:" + persistTime + "s"; + userList1.forEach(item -> { + smsSendFeignClient.sendSmsSimple(item.getPhone(), msgContent, "verify_code"); + }); + } + } + } + } +} diff --git a/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/impl/CsEventPOServiceImpl.java b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/impl/CsEventPOServiceImpl.java index fd7f9df..a5fd0d8 100644 --- a/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/impl/CsEventPOServiceImpl.java +++ b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/impl/CsEventPOServiceImpl.java @@ -13,15 +13,11 @@ import com.baomidou.dynamic.datasource.annotation.DSTransactional; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.njcn.access.pojo.dto.NoticeUserDto; -import com.njcn.access.utils.SendMessageUtil; import com.njcn.common.pojo.exception.BusinessException; import com.njcn.csdevice.api.CsLedgerFeignClient; import com.njcn.csdevice.api.CsLineFeignClient; import com.njcn.csdevice.api.DeviceMessageFeignClient; -import com.njcn.csdevice.api.SmsSendFeignClient; import com.njcn.csdevice.enums.AlgorithmResponseEnum; -import com.njcn.csdevice.param.DeviceMessageParam; import com.njcn.csdevice.pojo.dto.DevDetailDTO; import com.njcn.csdevice.pojo.po.CsLinePO; import com.njcn.csdevice.pojo.vo.DataGroupEventVO; @@ -34,13 +30,13 @@ import com.njcn.csharmonic.param.CsEventUserQueryParam; import com.njcn.csharmonic.param.DataParam; import com.njcn.csharmonic.pojo.param.EventStatisticParam; import com.njcn.csharmonic.pojo.po.CsEventPO; -import com.njcn.csharmonic.pojo.po.CsEventUserPO; import com.njcn.csharmonic.pojo.vo.CsEventVO; import com.njcn.csharmonic.pojo.vo.CsWarnDescVO; import com.njcn.csharmonic.pojo.vo.EventDetailVO; +import com.njcn.csharmonic.service.AppNotificationService; import com.njcn.csharmonic.service.CsEventPOService; import com.njcn.csharmonic.service.CsEventUserPOService; -import com.njcn.cssystem.api.AppMsgSetFeignClient; +import com.njcn.csharmonic.service.SmsNotificationService; import com.njcn.event.common.mapper.WlRmpEventDetailMapper; import com.njcn.event.file.component.WaveFileComponent; import com.njcn.event.file.component.WavePicComponent; @@ -64,8 +60,6 @@ import com.njcn.system.enums.DicDataEnum; import com.njcn.system.pojo.po.DictData; import com.njcn.system.pojo.po.EleEpdPqd; import com.njcn.system.pojo.po.EleEvtParm; -import com.njcn.user.api.UserFeignClient; -import com.njcn.user.pojo.po.User; import com.njcn.web.factory.PageFactory; import com.njcn.web.utils.RequestUtil; import lombok.RequiredArgsConstructor; @@ -126,11 +120,11 @@ public class CsEventPOServiceImpl extends ServiceImpl result = new ArrayList<>(); + //根据设备获取主用户、子用户 List eventUser = deviceMessageClient.getEventUserByDeviceId(po.getDeviceId(),true).getData(); - //针对用户记录未读信息和推送告警 - eventUser.forEach(item->{ - CsEventUserPO csEventUser = new CsEventUserPO(); - csEventUser.setUserId(item); - csEventUser.setStatus(0); - csEventUser.setEventId(uuid); - result.add(csEventUser); - }); - //获取打开推送的用户 - DeviceMessageParam param1 = new DeviceMessageParam(); - param1.setUserList(eventUser); - param1.setEventType(0); - List users = deviceMessageClient.getSendUserByType(param1).getData(); - if (CollectionUtil.isNotEmpty(users)){ - List devCodeList = users.stream().map(User::getDevCode).distinct().collect(Collectors.toList()); - noticeUserDto.setPushClientId(devCodeList); - noticeUserDto.setTitle("暂态事件"); - } - //获取台账信息 - String eventName = epdFeignClient.findByName(getTag(param.getEventType())).getData().getShowName(); DevDetailDTO devDetailDto = csLedgerFeignclient.queryDevDetail(po.getDeviceId()).getData(); - String content = devDetailDto.getEngineeringName() + "-" + devDetailDto.getProjectName() + "-" + devDetailDto.getEquipmentName() - + "于" + time.format(DatePattern.NORM_DATETIME_MS_FORMATTER) + "发生暂态事件,事件类型:" + eventName; - noticeUserDto.setContent(content); - payload.setType(0); - payload.setPath("/pages/index/message1?type="+payload.getType()); - noticeUserDto.setPayload(payload); + LocalDateTime eventTime = LocalDateTime.parse(param.getStartTime(), DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_MS_PATTERN)); - if (CollectionUtil.isNotEmpty(noticeUserDto.getPushClientId())) { - List filteredList = noticeUserDto.getPushClientId().stream() - .filter(s -> s != null && !s.isEmpty()) - .distinct() - .collect(Collectors.toList()); - if (CollectionUtil.isNotEmpty(filteredList)) { - noticeUserDto.setPushClientId(filteredList); - sendMessageUtil.sendEventToUser(noticeUserDto); - } + Double amplitudePercent = BigDecimal.valueOf(param.getAmplitude() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue(); + Double durationSeconds = BigDecimal.valueOf(param.getDuration()).setScale(2, RoundingMode.HALF_UP).doubleValue(); + + //异步处理事件用户关系和App消息推送 + try { + appNotificationService.asyncSaveEventUserAndNotify(uuid, eventUser, devDetailDto, time, param.getEventType(), amplitudePercent, durationSeconds); + } catch (Exception e) { + log.error("异步保存事件用户和通知失败,事件ID: {}", uuid, e); } - //事件用户关系入库 - if (CollectionUtil.isNotEmpty(result)){ - csEventUserPOService.saveBatch(result); - } - //如果事件是暂降事件,则推送短信给用户 + + //如果是暂降事件,异步发送短信通知 if (param.getEventType() == 1) { - //根据设备获取需要推送的用户列表 - List userIdList = appMsgSetFeignClient.queryUserIdsByDeviceId(po.getDeviceId()).getData(); - if (CollectionUtil.isNotEmpty(userIdList)) { - //获取用户详细信息 - List userList = userFeignClient.getUserListByIds(userIdList).getData(); - if (CollectionUtil.isNotEmpty(userList)) { - //筛选出有手机号码的;打开短信推送的 - List userList1 = userList.stream().filter(item-> StrUtil.isNotBlank(item.getPhone()) && Objects.equals(item.getSmsNotice(),1)).collect(Collectors.toList()); - if (CollectionUtil.isNotEmpty(userList1)) { - String msgContent = "【"+msgSign+"】" +devDetailDto.getEngineeringName() + "-" + devDetailDto.getProjectName() + "-" + devDetailDto.getEquipmentName() - + "于" + time.format(DatePattern.NORM_DATETIME_MS_FORMATTER) + "发生暂降事件"; - userList1.forEach(item->{ - smsSendFeignClient.sendSmsSimple(item.getPhone(),msgContent, "verify_code"); - }); - } - } + try { + smsNotificationService.asyncSendSmsNotification(po.getDeviceId(), devDetailDto, eventTime, amplitudePercent, durationSeconds); + } catch (Exception e) { + log.error("异步发送短信通知失败,事件ID: {}", uuid, e); } } } else { diff --git a/cs-system/cs-system-boot/src/main/java/com/njcn/cssystem/service/impl/WlUserServiceImpl.java b/cs-system/cs-system-boot/src/main/java/com/njcn/cssystem/service/impl/WlUserServiceImpl.java index e5799ae..c2b1750 100644 --- a/cs-system/cs-system-boot/src/main/java/com/njcn/cssystem/service/impl/WlUserServiceImpl.java +++ b/cs-system/cs-system-boot/src/main/java/com/njcn/cssystem/service/impl/WlUserServiceImpl.java @@ -89,7 +89,7 @@ public class WlUserServiceImpl implements IWlUserService { //现根据设备获取主用户 DevUserVO vo = csDeviceUserFeignClient.queryUserById(item).getData(); CsDeviceUserPO po = new CsDeviceUserPO(); - if (!Objects.isNull(vo)) { + if (!Objects.isNull(vo) && !Objects.isNull(vo.getMasterUser())) { po.setPrimaryUserId(vo.getMasterUser().getId()); } else { po.setPrimaryUserId(param.getUserId());