fxkh-txl-service/src/main/java/com/whdc/service/impl/SmsBirthdayServiceImpl.java

273 lines
11 KiB
Java
Raw Normal View History

package com.whdc.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whdc.mapper.SmsBirthdayMapper;
import com.whdc.mapper.SmsLogMapper;
import com.whdc.mapper.SmsSpecialistMapper;
import com.whdc.model.entity.SmsBirthday;
import com.whdc.model.entity.SmsLog;
import com.whdc.model.entity.SmsSpecialist;
import com.whdc.service.ISmsBirthdayService;
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 java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
*
*
* @author lyf
* @since 2025-09-23
*/
@Service
@Slf4j
public class SmsBirthdayServiceImpl extends ServiceImpl<SmsBirthdayMapper, SmsBirthday> implements ISmsBirthdayService {
@Autowired
private SmsSpecialistMapper specialistMapper;
@Autowired
private SmsLogMapper smsLogMapper;
@Autowired
private SmsHelper smsHelper;
// 记录今日是否已发送生日短信 - 使用原子变量保证线程安全
private final AtomicBoolean sending = new AtomicBoolean(false);
@Override
public List<SmsSpecialist> listBirthdayToday() {
try {
// 获取当前日期的月和日
LocalDate today = LocalDate.now();
String monthDay = today.format(DateTimeFormatter.ofPattern("MM-dd"));
// 查询今天过生日的专家(状态为有效的)
LambdaQueryWrapper<SmsSpecialist> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.apply("DATE_FORMAT(BIRTHDAY, '%m-%d') = {0}", monthDay)
.eq(SmsSpecialist::getFlagBirthdaySentToday, 0)
.eq(SmsSpecialist::getStatus, 1); // 1:有效
List<SmsSpecialist> specialists = specialistMapper.selectList(queryWrapper);
return specialists != null ? specialists : Collections.emptyList();
} catch (Exception e) {
// 记录异常并返回空列表
return Collections.emptyList();
}
}
@Override
public void sendBirthdaySms(List<SmsSpecialist> specialists) {
if (specialists == null || specialists.isEmpty()) {
log.info("没有需要发送生日短信的专家");
return;
}
// 获取生日短信模板
SmsBirthday smsBirthday = this.getById(1L); // 使用ID=1的记录
if (smsBirthday == null || smsBirthday.getStatus() != 1) {
log.warn("生日短信模板不存在或未启用");
return; // 模板不存在或未启用
}
String template = smsBirthday.getTemplate();
if (template == null || template.trim().isEmpty()) {
log.warn("生日短信模板内容为空");
return; // 模板内容为空
}
// 逐个发送个性化短信
int totalSpecialists = specialists.size();
log.info("开始向{}位专家发送生日短信", totalSpecialists);
//去重
Set<String> 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());
try {
log.info("正在发送第{}/{}位专家{}的生日短信", i + 1, totalSpecialists, specialist.getName());
// 创建短信日志记录
SmsLog smsLog = new SmsLog();
smsLog.setName(specialist.getName())
.setPhone(specialist.getPhone())
.setContent(content)
.setRemark("生日短信")
.setSendTm(new java.util.Date());
// 使用SmsHelper发送个性化短信
List<String> phoneList = Collections.singletonList(specialist.getPhone());
String sendResult = smsHelper.send(phoneList, content);
// 更新专家的flagBirthdaySentToday
specialist.setFlagBirthdaySentToday(1);
specialistMapper.updateById(specialist);
distinct.add(specialist.getPhone());
log.info("向专家{}发送生日短信结果: {}", specialist.getName(), sendResult);
// 根据发送结果设置备注
if ("发送成功".equals(sendResult)) {
smsLog.setRemark("生日短信-发送成功");
} else {
smsLog.setRemark("生日短信-发送失败: " + 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(), e.getMessage(), e);
// 即使发送失败,也保存短信记录
try {
SmsLog failedSmsLog = new SmsLog();
failedSmsLog.setName(specialist.getName())
.setPhone(specialist.getPhone())
.setContent(content)
.setRemark("生日短信-发送异常: " + e.getMessage())
.setSendTm(new java.util.Date());
smsLogMapper.insert(failedSmsLog);
} catch (Exception logException) {
log.error("保存发送失败的短信日志时发生异常: {}", logException.getMessage(), logException);
}
}
}
log.info("生日短信批量发送任务完成");
}
/**
*
*/
private void carbonCopy(String content) {
List<String> phoneList = new ArrayList<>();
phoneList.add("18154318312"); //唐威
phoneList.add("13247155309"); //陈锋
phoneList.add("15671545233"); //李
smsHelper.send(phoneList, content);
}
/**
* 0flagBirthdaySentToday0
*/
@Scheduled(cron = "0 0 0 * * ?")
public void resetFlagBirthdaySentToday() {
specialistMapper.resetFlagBirthdaySentToday();
}
/**
*
*
*/
@Scheduled(cron = "0 * * * * ?")
public void checkAndSendBirthdaySms() {
try {
// 获取生日短信配置
SmsBirthday smsBirthday = this.getById(1L);
if (smsBirthday == null || smsBirthday.getStatus() != 1) {
log.info("生日短信功能未启用");
return;
}
// 检查执行时间
String executionTime = smsBirthday.getExecutionTmStr();
if (executionTime == null || executionTime.trim().isEmpty()) {
log.warn("生日短信执行时间未配置");
return;
}
// 如果已经发送过,不再重复发送
if (sending.get()) {
log.info("其他线程正在执行生日短信发送任务");
return;
}
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
try {
// 将执行时间字符串与当前日期拼接
String todayWithExecutionTime = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + executionTime;
// 解析为完整的LocalDateTime
LocalDateTime scheduledTime = LocalDateTime.parse(
todayWithExecutionTime,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
);
// 检查当前时间是否大于等于执行时间
if (now.isEqual(scheduledTime) || now.isAfter(scheduledTime)) {
// 原子性检查和设置发送状态
if (sending.compareAndSet(false, true)) {
try {
log.info("到达生日短信发送时间: {}, 开始执行发送任务", executionTime);
// 查询今天过生日的专家
List<SmsSpecialist> birthdaySpecialists = listBirthdayToday();
if (birthdaySpecialists.isEmpty()) {
log.info("今天没有专家过生日,无需发送生日短信");
} else {
log.info("今天有{}位专家过生日,开始发送生日短信", birthdaySpecialists.size());
// 发送生日短信
sendBirthdaySms(birthdaySpecialists);
log.info("生日短信发送任务完成");
}
} finally {
sending.set(false);
}
} else {
log.info("其他线程正在执行生日短信发送任务");
}
} else {
log.info("当前时间{}未到执行时间{}", now.format(DateTimeFormatter.ofPattern("HH:mm:ss")), executionTime);
}
} catch (Exception e) {
log.error("执行时间格式解析失败: {}", executionTime, e);
}
} catch (Exception e) {
log.error("定时检查生日短信任务执行异常: {}", e.getMessage(), e);
}
}
/**
*
* 00:00:01
*/
//todo delete this
// @Scheduled(cron = "1 0 0 * * ?")
// public void resetDailySendStatus() {
// try {
// sending.set(false);
// log.info("生日短信每日发送状态已重置");
// } catch (Exception e) {
// log.error("重置生日短信每日发送状态异常: {}", e.getMessage(), e);
// }
// }
}