package com.ruoyi.system.service.impl; import java.util.Date; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.system.domain.NotifySendLog; import com.ruoyi.system.mapper.NotifySendLogMapper; import com.ruoyi.system.service.INotifySendLogService; /** * 通知发送记录服务实现类 * * @author ruoyi * @date 2025-12-07 */ @Service public class NotifySendLogServiceImpl implements INotifySendLogService { private static final Logger log = LoggerFactory.getLogger(NotifySendLogServiceImpl.class); @Autowired private NotifySendLogMapper notifySendLogMapper; /** * 查询通知发送记录 * * @param id 通知发送记录主键 * @return 通知发送记录 */ @Override public NotifySendLog selectNotifySendLogById(Long id) { return notifySendLogMapper.selectNotifySendLogById(id); } /** * 查询通知发送记录列表 * * @param notifySendLog 通知发送记录 * @return 通知发送记录 */ @Override public List selectNotifySendLogList(NotifySendLog notifySendLog) { return notifySendLogMapper.selectNotifySendLogList(notifySendLog); } /** * 根据任务ID和用户ID查询发送记录 */ @Override public NotifySendLog selectNotifySendLog(Long taskId, Long userId, String notifyType, String channel) { return notifySendLogMapper.selectNotifySendLog(taskId, userId, notifyType, channel); } /** * 检查是否已发送过通知(防重检查) * * @param taskId 任务ID * @param userId 用户ID * @param notifyType 通知类型 * @param channel 通知渠道 * @return true=已发送过, false=未发送过 */ @Override public boolean hasNotified(Long taskId, Long userId, String notifyType, String channel) { int count = notifySendLogMapper.checkNotifySendLogExists(taskId, userId, notifyType, channel); return count > 0; } /** * 尝试创建发送记录(防重,如果已存在则返回null) * 使用数据库唯一索引保证防重 * * @param taskId 任务ID * @param userId 用户ID * @param userName 用户姓名 * @param notifyType 通知类型 * @param channel 通知渠道 * @return 创建的记录,如果已存在则返回null */ @Override @Transactional public NotifySendLog tryCreateSendLog(Long taskId, Long userId, String userName, String notifyType, String channel) { // 先检查是否已存在 if (hasNotified(taskId, userId, notifyType, channel)) { log.debug("通知记录已存在,跳过创建,taskId={}, userId={}, notifyType={}, channel={}", taskId, userId, notifyType, channel); return null; } try { // 创建新记录 NotifySendLog sendLog = new NotifySendLog(); sendLog.setTaskId(taskId); sendLog.setUserId(userId); sendLog.setUserName(userName); sendLog.setNotifyType(notifyType); sendLog.setChannel(channel); sendLog.setSendStatus(NotifySendLog.SEND_STATUS_PENDING); sendLog.setRetryCount(0); sendLog.setCreateTime(DateUtils.getNowDate()); sendLog.setCreateBy("system"); int result = notifySendLogMapper.insertNotifySendLog(sendLog); if (result > 0) { log.info("创建通知发送记录成功,id={}, taskId={}, userId={}, notifyType={}, channel={}", sendLog.getId(), taskId, userId, notifyType, channel); return sendLog; } } catch (Exception e) { // 可能是并发插入导致的唯一索引冲突,视为已存在 log.warn("创建通知发送记录失败(可能是并发重复),taskId={}, userId={}, notifyType={}, channel={}, error={}", taskId, userId, notifyType, channel, e.getMessage()); } return null; } /** * 更新发送状态为成功(向后兼容) * * @param id 记录ID * @param result 发送结果信息 */ public void markSendSuccess(Long id, String result) { markSendSuccess(id, result, null); } /** * 更新发送状态为成功 * * @param id 记录ID * @param result 发送结果信息 * @param content 发送内容 */ @Override public void markSendSuccess(Long id, String result, String content) { if (id == null) { return; } try { notifySendLogMapper.updateSendStatus(id, NotifySendLog.SEND_STATUS_SUCCESS, result, content); log.debug("更新通知发送状态为成功,id={}", id); } catch (Exception e) { log.error("更新通知发送状态失败,id={}", id, e); } } /** * 更新发送状态为失败(向后兼容) * * @param id 记录ID * @param errorMsg 错误信息 */ public void markSendFailed(Long id, String errorMsg) { markSendFailed(id, errorMsg, null); } /** * 更新发送状态为失败 * * @param id 记录ID * @param errorMsg 错误信息 * @param content 发送内容 */ @Override public void markSendFailed(Long id, String errorMsg, String content) { if (id == null) { return; } try { // 限制错误信息长度 if (errorMsg != null && errorMsg.length() > 500) { errorMsg = errorMsg.substring(0, 500); } notifySendLogMapper.updateSendStatus(id, NotifySendLog.SEND_STATUS_FAILED, errorMsg, content); log.debug("更新通知发送状态为失败,id={}, error={}", id, errorMsg); } catch (Exception e) { log.error("更新通知发送状态失败,id={}", id, e); } } /** * 新增通知发送记录 * * @param notifySendLog 通知发送记录 * @return 结果 */ @Override public int insertNotifySendLog(NotifySendLog notifySendLog) { notifySendLog.setCreateTime(DateUtils.getNowDate()); return notifySendLogMapper.insertNotifySendLog(notifySendLog); } /** * 修改通知发送记录 * * @param notifySendLog 通知发送记录 * @return 结果 */ @Override public int updateNotifySendLog(NotifySendLog notifySendLog) { notifySendLog.setUpdateTime(DateUtils.getNowDate()); return notifySendLogMapper.updateNotifySendLog(notifySendLog); } /** * 批量删除通知发送记录 * * @param ids 需要删除的通知发送记录主键 * @return 结果 */ @Override public int deleteNotifySendLogByIds(Long[] ids) { return notifySendLogMapper.deleteNotifySendLogByIds(ids); } /** * 删除通知发送记录信息 * * @param id 通知发送记录主键 * @return 结果 */ @Override public int deleteNotifySendLogById(Long id) { return notifySendLogMapper.deleteNotifySendLogById(id); } /** * 查询待重试的失败记录 * * @param maxRetryCount 最大重试次数 * @return 失败记录列表 */ public List selectFailedNotifySendLogs(Integer maxRetryCount) { return notifySendLogMapper.selectFailedNotifySendLogs(maxRetryCount); } }