package com.whdc.service.impl; 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.whdc.mapper.SmsLogMapper; import com.whdc.mapper.SmsHolidayMapper; import com.whdc.mapper.SmsSpecialistMapper; import com.whdc.model.dto.SmsHolidayPageDto; import com.whdc.model.entity.SmsLog; import com.whdc.model.entity.SmsHoliday; import com.whdc.model.entity.SmsSpecialist; import com.whdc.service.ISmsHolidayService; import com.whdc.utils.SmsHelper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.HashSet; import java.util.concurrent.atomic.AtomicBoolean; /** * 主题日短信服务实现类 * * @author lyf * @since 2025-09-23 */ @Service @Slf4j public class SmsHolidayServiceImpl extends ServiceImpl implements ISmsHolidayService { public Page page(SmsHolidayPageDto dto) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); // 添加查询条件 if (StringUtils.hasText(dto.getSubjectName())) { queryWrapper.like(SmsHoliday::getSubjectName, dto.getSubjectName()); } // 默认按创建时间降序排列 queryWrapper.orderByDesc(SmsHoliday::getCreateTm); return page(dto.getPage(), queryWrapper); } @Autowired private SmsSpecialistMapper specialistMapper; @Autowired private SmsLogMapper smsLogMapper; @Autowired private SmsHelper smsHelper; // 记录任务发送状态 - 使用原子变量保证线程安全 private final AtomicBoolean sending = new AtomicBoolean(false); @Override public List listActiveTasks() { try { LocalDate today = LocalDate.now(); // 查询当前活动中的主题日短信任务 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper .eq(SmsHoliday::getStatus, 1) // 1:有效 .le(SmsHoliday::getStartDate, today) // 开始日期小于等于今天 .ge(SmsHoliday::getEndDate, today); // 结束日期大于等于今天 List tasks = this.list(queryWrapper); return tasks != null ? tasks : Collections.emptyList(); } catch (Exception e) { log.error("查询活动中的主题日短信任务失败: {}", e.getMessage(), e); return Collections.emptyList(); } } @Override public List listTodayTasks() { try { // 获取当前活动中的任务 List activeTasks = listActiveTasks(); if (activeTasks.isEmpty()) { return Collections.emptyList(); } LocalDate today = LocalDate.now(); List todayTasks = new java.util.ArrayList<>(); // 筛选今天需要执行的任务 for (SmsHoliday task : activeTasks) { // 检查执行时间 String executionTime = task.getExecutionTmStr(); if (executionTime == null || executionTime.trim().isEmpty()) { log.warn("主题日任务{}执行时间未配置", task.getSubjectName()); continue; } // 检查当前时间是否达到执行时间 LocalDateTime now = LocalDateTime.now(); try { String todayWithExecutionTime = today.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + executionTime; LocalDateTime scheduledTime = LocalDateTime.parse( todayWithExecutionTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") ); if (now.isEqual(scheduledTime) || now.isAfter(scheduledTime)) { todayTasks.add(task); } } catch (Exception e) { log.error("主题日任务{}执行时间格式解析失败: {}", task.getSubjectName(), executionTime, e); } } return todayTasks; } catch (Exception e) { log.error("查询今日主题日任务失败: {}", e.getMessage(), e); return Collections.emptyList(); } } @Override public void sendThemeSms(SmsHoliday smsTask) { if (smsTask == null) { log.warn("主题日短信任务为空"); return; } // 获取所有有效专家(节日短信专用) List specialists = getValidSpecialistsForHoliday(); if (specialists.isEmpty()) { log.info("没有有效专家,跳过主题日短信发送"); return; } String template = smsTask.getTemplate(); if (template == null || template.trim().isEmpty()) { log.warn("主题日任务{}模板内容为空", smsTask.getSubjectName()); return; } // 逐个发送个性化短信 int totalSpecialists = specialists.size(); log.info("开始向{}位专家发送主题日短信[{}]", totalSpecialists, smsTask.getSubjectName()); // 去重 Set distinct = new HashSet<>(); for (int i = 0; i < specialists.size(); i++) { SmsSpecialist specialist = specialists.get(i); if (distinct.contains(specialist.getPhone())) { continue; } // 替换模板中的占位符 String content = template.replace("{姓名}", specialist.getName()) .replace("{主题}", smsTask.getSubjectName()); try { log.info("正在发送第{}/{}位专家{}的主题日短信", i + 1, totalSpecialists, specialist.getName()); // 创建短信日志记录 SmsLog smsLog = new SmsLog(); smsLog.setName(specialist.getName()) .setPhone(specialist.getPhone()) .setContent(content) .setRemark("主题日短信-" + smsTask.getSubjectName()) .setSendTm(new java.util.Date()); // 使用SmsHelper发送个性化短信 List phoneList = Collections.singletonList(specialist.getPhone()); String sendResult = smsHelper.send(phoneList, content); // 更新专家的flagHolidaySentToday specialist.setFlagHolidaySentToday(1); specialistMapper.updateById(specialist); distinct.add(specialist.getPhone()); log.info("向专家{}发送主题日短信[{}]结果: {}", specialist.getName(), smsTask.getSubjectName(), sendResult); // 根据发送结果设置备注 if ("发送成功".equals(sendResult)) { smsLog.setRemark("主题日短信-" + smsTask.getSubjectName() + "-发送成功"); } else { smsLog.setRemark("主题日短信-" + smsTask.getSubjectName() + "-发送失败: " + sendResult); } // 应唐科要求,每次发送短讯要抄送给唐威,陈锋 carbonCopy(content); // 保存短信日志记录 smsLogMapper.insert(smsLog); // 如果不是最后一位专家,等待3秒再发送下一条 if (i < specialists.size() - 1) { try { log.info("等待3秒后发送下一条短信..."); Thread.sleep(3000); // 3秒间隔 } catch (InterruptedException ie) { Thread.currentThread().interrupt(); log.warn("短信发送间隔被中断"); break; } } } catch (Exception e) { log.error("向专家{}发送主题日短信[{}]时发生异常: {}", specialist.getName(), smsTask.getSubjectName(), e.getMessage(), e); // 即使发送失败,也保存短信记录 try { SmsLog failedSmsLog = new SmsLog(); failedSmsLog.setName(specialist.getName()) .setPhone(specialist.getPhone()) .setContent(content) .setRemark("主题日短信-" + smsTask.getSubjectName() + "-发送异常: " + e.getMessage()) .setSendTm(new java.util.Date()); smsLogMapper.insert(failedSmsLog); } catch (Exception logException) { log.error("保存发送失败的短信日志时发生异常: {}", logException.getMessage(), logException); } } } log.info("主题日短信任务[{}]发送完成", smsTask.getSubjectName()); } @Override public void sendBatchThemeSms(List smsTasks) { if (smsTasks == null || smsTasks.isEmpty()) { log.info("没有需要发送的主题日短信任务"); return; } log.info("开始批量发送{}个主题日短信任务", smsTasks.size()); for (SmsHoliday task : smsTasks) { try { sendThemeSms(task); } catch (Exception e) { log.error("发送主题日短信任务[{}]失败: {}", task.getSubjectName(), e.getMessage(), e); } } log.info("批量主题日短信任务发送完成"); } /** * 抄送 */ private void carbonCopy(String content) { // 检查当前日期是否超过10月5号 LocalDate today = LocalDate.now(); LocalDate limitDate = LocalDate.of(2025, 10, 5); if (today.isAfter(limitDate)) { log.info("当前日期{}已超过10月5日,跳过抄送", today); return; } List phoneList = new ArrayList<>(); phoneList.add("18154318312"); //唐威 phoneList.add("13247155309"); //陈锋 phoneList.add("15671545233"); //李 smsHelper.send(phoneList, content); } /** * 每天0点1分重置所有专家的flagHolidaySentToday为0 */ @Scheduled(cron = "1 0 0 * * ?") public void resetFlagHolidaySentToday() { specialistMapper.resetFlagHolidaySentToday(); } /** * 获取所有有效专家(节日短信专用) */ private List getValidSpecialistsForHoliday() { try { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SmsSpecialist::getStatus, 1); // 1:有效 queryWrapper.eq(SmsSpecialist::getFlagHolidaySentToday, 0); // 未发送节日短信 queryWrapper.isNotNull(SmsSpecialist::getPhone); // 手机号不为空 List specialists = specialistMapper.selectList(queryWrapper); return specialists != null ? specialists : Collections.emptyList(); } catch (Exception e) { log.error("查询有效专家失败: {}", e.getMessage(), e); return Collections.emptyList(); } } /** * 定时检查并发送主题日短信 * 每分钟执行一次 */ @Scheduled(cron = "0 * * * * ?") public void checkAndSendThemeSms() { try { // 如果其他线程正在执行,跳过 if (sending.get()) { log.debug("其他线程正在执行主题日短信发送任务"); return; } // 查询今日需要执行的主题日任务 List todayTasks = listTodayTasks(); if (todayTasks.isEmpty()) { log.info("今日没有需要执行的主题日短信任务"); return; } log.info("检测到{}个主题日短信任务需要执行", todayTasks.size()); // 批量发送主题日短信 try { sendBatchThemeSms(todayTasks); } finally { sending.set(false); } } catch (Exception e) { log.error("定时检查主题日短信任务执行异常: {}", e.getMessage(), e); sending.set(false); } } }