package com.ruoyi.system.service.impl;
|
|
import com.alibaba.fastjson2.JSONObject;
|
import com.ruoyi.common.config.SmsConfig;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.utils.SmsUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.system.domain.SysTask;
|
import com.ruoyi.system.domain.SysTaskEmergency;
|
import com.ruoyi.system.mapper.SysTaskEmergencyMapper;
|
import com.ruoyi.system.mapper.SysTaskMapper;
|
import com.ruoyi.system.mapper.SysUserMapper;
|
import com.ruoyi.system.service.ISmsService;
|
import com.ruoyi.system.service.ISysConfigService;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import java.util.List;
|
|
/**
|
* 短信发送服务实现类
|
*
|
* @author ruoyi
|
* @date 2025-12-07
|
*/
|
@Service
|
public class SmsServiceImpl implements ISmsService {
|
|
private static final Logger log = LoggerFactory.getLogger(SmsServiceImpl.class);
|
|
/** 系统配置键:短信开关 */
|
private static final String CONFIG_KEY_SMS_ENABLED = "sms.enabled";
|
|
@Autowired
|
private SmsConfig smsConfig;
|
|
@Autowired
|
private ISysConfigService configService;
|
|
@Autowired
|
private SysUserMapper sysUserMapper;
|
|
@Autowired
|
private SysTaskMapper sysTaskMapper;
|
|
@Autowired
|
private SysTaskEmergencyMapper sysTaskEmergencyMapper;
|
|
/**
|
* 检查短信服务是否启用
|
* 优先从数据库配置读取,其次从配置文件读取
|
*
|
* @return true=启用, false=禁用
|
*/
|
@Override
|
public boolean isEnabled() {
|
try {
|
// 优先从数据库配置读取
|
String enabled = configService.selectConfigByKey(CONFIG_KEY_SMS_ENABLED);
|
if (StringUtils.isNotEmpty(enabled)) {
|
return "true".equalsIgnoreCase(enabled);
|
}
|
} catch (Exception e) {
|
log.warn("获取短信开关配置失败,使用配置文件配置", e);
|
}
|
// 从配置文件读取
|
return smsConfig.isEnabled();
|
}
|
|
/**
|
* 发送短信
|
*
|
* @param phone 手机号
|
* @param content 短信内容
|
* @return 是否发送成功
|
*/
|
@Override
|
public boolean sendSms(String phone, String content) {
|
if (!isEnabled()) {
|
log.info("短信服务已关闭,跳过发送,phone={}", phone);
|
return false;
|
}
|
|
if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(content)) {
|
log.warn("短信发送参数不完整,phone={}, content={}", phone, content);
|
return false;
|
}
|
|
try {
|
// 添加签名
|
String fullContent = smsConfig.getSignName() + content;
|
|
JSONObject result = SmsUtils.sendSms(
|
smsConfig.getAddress(),
|
smsConfig.getUserName(),
|
smsConfig.getPassword(),
|
phone,
|
fullContent
|
);
|
|
if (result != null) {
|
int code = result.getIntValue("code", -1);
|
if (code == 0) {
|
log.info("短信发送成功,phone={}", phone);
|
return true;
|
} else {
|
log.error("短信发送失败,phone={},code={},msg={}",
|
phone, code, result.getString("msg"));
|
}
|
}
|
} catch (Exception e) {
|
log.error("短信发送异常,phone={}", phone, e);
|
}
|
|
return false;
|
}
|
|
/**
|
* 批量发送短信
|
*
|
* @param phones 手机号列表
|
* @param content 短信内容
|
* @return 成功发送的数量
|
*/
|
@Override
|
public int sendSmsBatch(List<String> phones, String content) {
|
if (!isEnabled()) {
|
log.info("短信服务已关闭,跳过批量发送");
|
return 0;
|
}
|
|
if (phones == null || phones.isEmpty() || StringUtils.isEmpty(content)) {
|
log.warn("批量短信发送参数不完整");
|
return 0;
|
}
|
|
int successCount = 0;
|
for (String phone : phones) {
|
if (sendSms(phone, content)) {
|
successCount++;
|
}
|
}
|
|
log.info("批量短信发送完成,总数={},成功={}", phones.size(), successCount);
|
return successCount;
|
}
|
|
/**
|
* 发送任务分配通知短信
|
*
|
* @param taskId 任务ID
|
* @param userIds 用户ID列表
|
* @param excludeUserId 排除的用户ID(可选,如创建人)
|
* @return 成功发送的数量
|
*/
|
@Override
|
public int sendTaskAssignSms(Long taskId, List<Long> userIds, Long excludeUserId) {
|
if (!isEnabled()) {
|
log.info("短信服务已关闭,跳过任务分配短信发送,taskId={}", taskId);
|
return 0;
|
}
|
|
if (taskId == null || userIds == null || userIds.isEmpty()) {
|
log.warn("任务分配短信发送参数不完整,taskId={}, userIds={}", taskId, userIds);
|
return 0;
|
}
|
|
// 查询任务信息
|
SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
|
if (task == null) {
|
log.warn("任务不存在,无法发送短信,taskId={}", taskId);
|
return 0;
|
}
|
|
// 查询急救扩展信息
|
SysTaskEmergency emergency = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
|
|
// 构建短信内容
|
String content = buildTaskAssignSmsContent(task, emergency);
|
|
int successCount = 0;
|
for (Long userId : userIds) {
|
// 排除指定用户
|
if (excludeUserId != null && excludeUserId.equals(userId)) {
|
log.debug("跳过排除用户,userId={}", userId);
|
continue;
|
}
|
|
// 查询用户信息
|
SysUser user = sysUserMapper.selectUserById(userId);
|
if (user == null) {
|
log.warn("用户不存在,跳过发送,userId={}", userId);
|
continue;
|
}
|
|
String phone = user.getPhonenumber();
|
if (StringUtils.isEmpty(phone)) {
|
log.warn("用户手机号为空,跳过发送,userId={}, userName={}", userId, user.getNickName());
|
continue;
|
}
|
|
// 发送短信
|
if (sendSms(phone, content)) {
|
successCount++;
|
log.info("任务分配短信发送成功,taskId={},userId={},phone={}", taskId, userId, phone);
|
}
|
}
|
|
log.info("任务分配短信发送完成,taskId={},总数={},成功={}", taskId, userIds.size(), successCount);
|
return successCount;
|
}
|
|
/**
|
* 发送任务分配通知短信(不排除任何用户)
|
*
|
* @param taskId 任务ID
|
* @param userIds 用户ID列表
|
* @return 成功发送的数量
|
*/
|
@Override
|
public int sendTaskAssignSms(Long taskId, List<Long> userIds) {
|
return sendTaskAssignSms(taskId, userIds, null);
|
}
|
|
/**
|
* 构建任务分配短信内容
|
*
|
* @param task 任务信息
|
* @param emergency 急救扩展信息(可选)
|
* @return 短信内容
|
*/
|
private String buildTaskAssignSmsContent(SysTask task, SysTaskEmergency emergency) {
|
String template = smsConfig.getTaskAssignTemplate();
|
|
// 任务编号
|
String taskCode = StringUtils.isNotEmpty(task.getTaskCode())
|
? task.getTaskCode() : String.valueOf(task.getTaskId());
|
|
// 出发地
|
String departure;
|
if (emergency != null && StringUtils.isNotEmpty(emergency.getHospitalOutName())) {
|
departure = emergency.getHospitalOutName();
|
} else if (StringUtils.isNotEmpty(task.getDepartureAddress())) {
|
departure = task.getDepartureAddress();
|
} else {
|
departure = "待确认";
|
}
|
|
// 目的地
|
String destination;
|
if (emergency != null && StringUtils.isNotEmpty(emergency.getHospitalInName())) {
|
destination = emergency.getHospitalInName();
|
} else if (StringUtils.isNotEmpty(task.getDestinationAddress())) {
|
destination = task.getDestinationAddress();
|
} else {
|
destination = "待确认";
|
}
|
|
// 限制地址长度,避免短信过长
|
if (departure.length() > 20) {
|
departure = departure.substring(0, 17) + "...";
|
}
|
if (destination.length() > 20) {
|
destination = destination.substring(0, 17) + "...";
|
}
|
|
// 替换模板变量
|
return template
|
.replace("{taskCode}", taskCode)
|
.replace("{departure}", departure)
|
.replace("{destination}", destination);
|
}
|
|
/**
|
* 查询短信余额
|
*
|
* @return 余额信息
|
*/
|
@Override
|
public String getBalance() {
|
try {
|
JSONObject result = SmsUtils.getBalance(
|
smsConfig.getAddress(),
|
smsConfig.getUserName(),
|
smsConfig.getPassword()
|
);
|
|
if (result != null) {
|
return result.toJSONString();
|
}
|
} catch (Exception e) {
|
log.error("查询短信余额失败", e);
|
}
|
return "查询失败";
|
}
|
}
|