package com.ruoyi.system.service.impl; import com.alibaba.fastjson2.JSON; import com.ruoyi.common.config.WechatConfig; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.domain.*; import com.ruoyi.system.mapper.NotifyChannelConfigMapper; import com.ruoyi.system.mapper.SysMessageMapper; import com.ruoyi.system.service.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; /** * 通知分发服务实现类 * 负责根据配置决定发送渠道并执行分发 * * @author ruoyi * @date 2025-12-07 */ @Service public class NotifyDispatchServiceImpl implements INotifyDispatchService { private static final Logger log = LoggerFactory.getLogger(NotifyDispatchServiceImpl.class); @Autowired private NotifyChannelConfigMapper channelConfigMapper; @Autowired private INotifyTaskService notifyTaskService; @Autowired private INotifySendLogService notifySendLogService; @Autowired private SysMessageMapper sysMessageMapper; @Autowired private IWechatTaskNotifyService wechatTaskNotifyService; @Autowired private ISmsService smsService; @Autowired private IQyWechatService qyWechatService; @Autowired private WechatConfig wechatConfig; @Autowired private ISysEmergencyTaskService sysEmergencyTaskService; /** * 获取指定通知类型启用的渠道列表 */ @Override public List getEnabledChannels(String notifyType) { if (StringUtils.isEmpty(notifyType)) { return Collections.emptyList(); } return channelConfigMapper.selectEnabledChannelsByType(notifyType); } /** * 检查指定渠道是否启用 */ @Override public boolean isChannelEnabled(String notifyType, String channel) { NotifyChannelConfig config = channelConfigMapper.selectByTypeAndChannel(notifyType, channel); return config != null && NotifyChannelConfig.ENABLED_YES.equals(config.getEnabled()); } /** * 分发通知任务 */ @Override public int dispatchNotify(NotifyTask notifyTask) { if (notifyTask == null) { return 0; } // log.info("开始分发通知任务,id={}, taskId={}, userId={}, notifyType={}", // notifyTask.getId(), notifyTask.getTaskId(), notifyTask.getUserId(), notifyTask.getNotifyType()); // 更新状态为处理中 notifyTaskService.markProcessing(notifyTask.getId()); // 获取启用的渠道 List channels = getEnabledChannels(notifyTask.getNotifyType()); if (channels.isEmpty()) { log.warn("没有启用的渠道,notifyType={}", notifyTask.getNotifyType()); notifyTaskService.markCompleted(notifyTask.getId()); return 0; } int successCount = 0; StringBuilder errorMsgs = new StringBuilder(); // 按优先级依次发送各渠道 for (NotifyChannelConfig channelConfig : channels) { String channel = channelConfig.getChannel(); boolean success = false; String errorMsg = null; try { switch (channel) { case NotifyChannelConfig.CHANNEL_SITE_MSG: success = sendSiteMessage(notifyTask); break; case NotifyChannelConfig.CHANNEL_WECHAT: success = sendWechatMessage(notifyTask); break; case NotifyChannelConfig.CHANNEL_SMS: success = sendSmsMessage(notifyTask); break; case NotifyChannelConfig.CHANNEL_QY_WECHAT: success = sendQyWechatMessage(notifyTask); break; default: log.warn("不支持的渠道类型:{}", channel); continue; } } catch (Exception e) { errorMsg = e.getMessage(); log.error("发送{}消息失败,notifyTaskId={}", channel, notifyTask.getId(), e); } // 记录发送日志 recordSendLog(notifyTask, channel, success, errorMsg); if (success) { successCount++; log.info("{}渠道发送成功,notifyTaskId={}", channel, notifyTask.getId()); } else { if (errorMsgs.length() > 0) { errorMsgs.append("; "); } errorMsgs.append(channel).append(":").append(errorMsg != null ? errorMsg : "发送失败"); } } // 更新任务状态 if (successCount > 0) { notifyTaskService.markCompleted(notifyTask.getId()); } else { notifyTaskService.incrementRetryCount(notifyTask.getId()); // 检查是否超过最大重试次数 NotifyTask updated = notifyTaskService.selectNotifyTaskById(notifyTask.getId()); if (updated.getRetryCount() >= updated.getMaxRetry()) { notifyTaskService.markFailed(notifyTask.getId(), errorMsgs.toString()); } else { // 重置为待处理状态,等待下次重试 notifyTaskService.updateNotifyTask(createStatusUpdate(notifyTask.getId(), NotifyTask.STATUS_PENDING)); } } log.info("通知任务分发完成,id={}, 成功渠道数={}", notifyTask.getId(), successCount); return successCount; } /** * 创建状态更新对象 */ private NotifyTask createStatusUpdate(Long id, String status) { NotifyTask update = new NotifyTask(); update.setId(id); update.setStatus(status); return update; } /** * 记录发送日志 */ private void recordSendLog(NotifyTask notifyTask, String channel, boolean success, String errorMsg) { try { NotifySendLog sendLog = new NotifySendLog(); sendLog.setNotifyTaskId(notifyTask.getId()); sendLog.setTaskId(notifyTask.getTaskId()); sendLog.setUserId(notifyTask.getUserId()); sendLog.setUserName(notifyTask.getUserName()); sendLog.setNotifyType(notifyTask.getNotifyType()); sendLog.setChannel(channel); sendLog.setSendStatus(success ? NotifySendLog.SEND_STATUS_SUCCESS : NotifySendLog.SEND_STATUS_FAILED); sendLog.setSendTime(DateUtils.getNowDate()); sendLog.setSendContent(notifyTask.getContent()); sendLog.setResponseMsg(errorMsg); notifySendLogService.insertNotifySendLog(sendLog); } catch (Exception e) { log.error("记录发送日志失败", e); } } /** * 批量分发通知任务 */ @Override public int dispatchNotifies(List notifyTasks) { if (notifyTasks == null || notifyTasks.isEmpty()) { return 0; } int successCount = 0; for (NotifyTask notifyTask : notifyTasks) { int channelCount = dispatchNotify(notifyTask); if (channelCount > 0) { successCount++; } } return successCount; } /** * 处理待发送的通知任务 */ @Override public int processPendingNotifies(int limit) { List pendingTasks = notifyTaskService.selectPendingNotifyTasks(limit); if (pendingTasks.isEmpty()) { return 0; } log.info("开始处理待发送通知任务,数量={}", pendingTasks.size()); return dispatchNotifies(pendingTasks); } /** * 发送站内消息 */ @Override public boolean sendSiteMessage(NotifyTask notifyTask) { try { SysMessage message = new SysMessage(); message.setMessageType(getMessageType(notifyTask.getNotifyType())); message.setMessageTitle(notifyTask.getTitle()); message.setMessageContent(notifyTask.getContent()); message.setTaskId(notifyTask.getTaskId()); message.setTaskCode(notifyTask.getTaskCode()); message.setReceiverId(notifyTask.getUserId()); message.setReceiverName(notifyTask.getUserName()); message.setSenderId(0L); message.setSenderName("系统"); message.setIsRead("0"); message.setCreateTime(DateUtils.getNowDate()); message.setDelFlag("0"); sysMessageMapper.insertSysMessage(message); log.info("站内消息发送成功,messageId={}, userId={}", message.getMessageId(), notifyTask.getUserId()); return true; } catch (Exception e) { log.error("站内消息发送失败,userId={}", notifyTask.getUserId(), e); return false; } } /** * 根据通知类型获取消息类型 */ private String getMessageType(String notifyType) { switch (notifyType) { case NotifyTask.NOTIFY_TYPE_TASK_ASSIGN: return "PUSH"; case NotifyTask.NOTIFY_TYPE_STATUS_CHANGE: return "STATUS"; case NotifyTask.NOTIFY_TYPE_TASK_CREATE: return "CREATE"; default: return "SYSTEM"; } } /** * 发送微信订阅消息 */ @Override public boolean sendWechatMessage(NotifyTask notifyTask) { try { // 调用微信通知服务 int result = wechatTaskNotifyService.sendTaskNotifyMessage( notifyTask.getTaskId(), Collections.singletonList(notifyTask.getUserId()), null // 不排除任何用户 ); if (result > 0) { log.info("微信订阅消息发送成功,taskId={}, userId={}", notifyTask.getTaskId(), notifyTask.getUserId()); return true; } else { log.warn("微信订阅消息发送失败,taskId={}, userId={}", notifyTask.getTaskId(), notifyTask.getUserId()); return false; } } catch (Exception e) { log.error("微信订阅消息发送异常,taskId={}, userId={}", notifyTask.getTaskId(), notifyTask.getUserId(), e); return false; } } /** * 发送短信消息 */ @Override public boolean sendSmsMessage(NotifyTask notifyTask) { try { // 检查短信服务是否启用 if (!smsService.isEnabled()) { log.info("短信服务已关闭,跳过发送"); return false; } String phone = notifyTask.getUserPhone(); if (StringUtils.isEmpty(phone)) { log.warn("用户手机号为空,无法发送短信,userId={}", notifyTask.getUserId()); return false; } // 发送短信 boolean success = smsService.sendSms(phone, notifyTask.getContent()); if (success) { log.info("短信发送成功,phone={}, userId={}", phone, notifyTask.getUserId()); } else { log.warn("短信发送失败,phone={}, userId={}", phone, notifyTask.getUserId()); } return success; } catch (Exception e) { log.error("短信发送异常,userId={}", notifyTask.getUserId(), e); return false; } } @Autowired private ISysConfigService sysConfigService; /** * 发送企业微信消息 */ @Override public boolean sendQyWechatMessage(NotifyTask notifyTask) { try { // 检查企业微信服务是否启用 if (!qyWechatService.isEnabled()) { log.info("企业微信服务已关闭,跳过发送"); return false; } Long taskId= notifyTask.getTaskId(); SysTaskEmergency emergency = this.sysEmergencyTaskService.selectSysTaskEmergencyByTaskId(taskId); if(emergency==null){ return false; } // Long dispatchOrderId = emergency.getLegacyDispatchOrdId(); // String oldsiteUrl= sysConfigService.selectConfigByKey("oldsite.url"); // if(oldsiteUrl==null){ // oldsiteUrl="https://sys.966120.com.cn/m_DispatchOrder.gds?DispatchOrdID="; // } String appId=wechatConfig.getAppId(); String pathPage="/pagesTask/detail?id="+taskId; // 发送企业微信消息 boolean success = qyWechatService.sendNotifyMessage( notifyTask.getUserId(), notifyTask.getTitle(), notifyTask.getContent(),appId,pathPage ); if (success) { log.info("企业微信消息发送成功,userId={}", notifyTask.getUserId()); } else { log.warn("企业微信消息发送失败,userId={}", notifyTask.getUserId()); } return success; } catch (Exception e) { log.error("企业微信消息发送异常,taskId={}, userId={}", notifyTask.getTaskId(), notifyTask.getUserId(), e); return false; } } }