短信推送

This commit is contained in:
zhangheng 2024-07-23 18:05:38 +08:00
parent 1eaaf7e1be
commit e53d97a6ac
9 changed files with 349 additions and 1 deletions

View File

@ -6,6 +6,7 @@ import com.xinelu.manage.dto.signpatientmanageroutenode.SignPatientManageRouteNo
import com.xinelu.manage.vo.signpatientmanageroutenode.PatientManageNodeListVo; import com.xinelu.manage.vo.signpatientmanageroutenode.PatientManageNodeListVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.PatientTaskVo; import com.xinelu.manage.vo.signpatientmanageroutenode.PatientTaskVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.SignPatientManageNodeAuditVo; import com.xinelu.manage.vo.signpatientmanageroutenode.SignPatientManageNodeAuditVo;
import com.xinelu.manage.vo.signpatientmanageroutenode.TextMessage;
import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeAuditVo; import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeAuditVo;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
@ -125,4 +126,19 @@ public interface SignPatientManageRouteNodeMapper {
* @return 患者管理任务路径节点 * @return 患者管理任务路径节点
*/ */
List<SignPatientManageRouteNode> getRouteNodeContentList(Long patientId); List<SignPatientManageRouteNode> getRouteNodeContentList(Long patientId);
/**
* 查询需要推送短信数据
*
* @return TextMessage
*/
List<TextMessage> selectMessagePushSign();
/**
* 根据节点id修改状态
*
* @param ids 节点ids
* @return int
*/
int updateMessageStatusByIds(@Param("ids") List<Long> ids);
} }

View File

@ -0,0 +1,66 @@
package com.xinelu.manage.vo.signpatientmanageroutenode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDate;
/**
* @Description 查询短信发送实体类
* @Author zh
* @Date 2024-05-24
*/
@Data
public class TextMessage {
@ApiModelProperty(value = "短信内容")
private String messageNodeContent;
@ApiModelProperty(value = "患者姓名")
private String patientName;
@ApiModelProperty(value = "患者手机号")
private String patientPhone;
@ApiModelProperty(value = "患者身份证号")
private String cardNo;
@ApiModelProperty(value = "患者类型")
private String patientType;
@ApiModelProperty(value = "入院时间")
private LocalDate admissionTime;
@ApiModelProperty(value = "出院时间")
private LocalDate dischargeTime;
@ApiModelProperty(value = "就诊时间")
private LocalDate visitDate;
@ApiModelProperty(value = "就诊方式")
private String visitMethod;
@ApiModelProperty(value = "患者id")
private Long patientId;
@ApiModelProperty(value = "签约患者管理任务表id")
private Long manageRouteId;
@ApiModelProperty(value = "路径名称")
private String manageRouteName;
@ApiModelProperty(value = "管理路径节点名称")
private String routeNodeName;
@ApiModelProperty(value = "管理路径节点时间,时间单位为:天")
private Integer routeNodeDay;
@ApiModelProperty(value = "任务节点类型")
private String taskNodeType;
@ApiModelProperty(value = "短信推送标识0未开启1已开启")
private Integer messagePushSign;
@ApiModelProperty(value = "节点id")
private Long signPatientManageRouteNodeId;
}

View File

@ -823,4 +823,38 @@
LEFT JOIN special_disease_node sdn ON sdn.route_id = sdr.id LEFT JOIN special_disease_node sdn ON sdn.route_id = sdr.id
where spmr.patient_id = #{patientId} where spmr.patient_id = #{patientId}
</select> </select>
<select id="selectMessagePushSign"
resultType="com.xinelu.manage.vo.signpatientmanageroutenode.TextMessage">
select spmrn.id signPatientManageRouteNodeId,
spmrn.manage_route_name,
spmrn.message_push_sign,
spmrn.message_node_content,
spmrn.node_execute_status,
spmrn.route_node_name,
spmrn.route_node_day,
spmrn.task_node_type,
spmr.id manageRouteId,
pi.patient_phone,
pi.patient_type,
pi.admission_time,
pi.discharge_time,
pi.visit_date,
pi.visit_method
from sign_patient_manage_route_node spmrn
LEFT JOIN sign_patient_manage_route spmr ON spmr.id = spmrn.manage_route_id
LEFT JOIN patient_info pi ON pi.id = spmr.patient_id
where spmrn.message_push_sign = 1
and spmrn.del_flag = 0
and spmrn.node_execute_status = 'UNEXECUTED'
</select>
<update id="updateMessageStatusByIds">
update sign_patient_manage_route_node
set message_status = 'EXECUTED'
where id in
<foreach item="ids" collection="ids" open="(" separator="," close=")">
#{ids}
</foreach>
</update>
</mapper> </mapper>

View File

@ -8,6 +8,7 @@ import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile; import com.aliyuncs.profile.IClientProfile;
import com.xinelu.common.config.AliYunSmsConfig; import com.xinelu.common.config.AliYunSmsConfig;
import com.xinelu.common.config.AliYunSmsTwoConfig;
import com.xinelu.common.enums.SmsErrorCodeEnum; import com.xinelu.common.enums.SmsErrorCodeEnum;
import com.xinelu.common.exception.ServiceException; import com.xinelu.common.exception.ServiceException;
import com.xinelu.manage.dto.smssend.SmsInfoDTO; import com.xinelu.manage.dto.smssend.SmsInfoDTO;
@ -33,6 +34,9 @@ public class SmsSendUtils {
@Resource @Resource
private AliYunSmsConfig aliyunSmsConfig; private AliYunSmsConfig aliyunSmsConfig;
@Resource
private AliYunSmsTwoConfig aliYunSmsTwoConfig;
/** /**
* 发送短信 * 发送短信
*/ */
@ -82,5 +86,53 @@ public class SmsSendUtils {
throw e; throw e;
} }
} }
/**
* 无替换模版发送短信
*/
public Boolean sendTextMessage(SmsInfoDTO smsInfoDTO) throws ClientException, ServiceException {
try {
// 短信发送参数非空性判断
if (ObjectUtils.isEmpty(smsInfoDTO)) {
throw new ServiceException("短信发送参数不能为空!");
}
if (StringUtils.isBlank(smsInfoDTO.getPhoneNumbers())) {
throw new ServiceException("待发送手机号不能为空!");
}
if (StringUtils.isBlank(smsInfoDTO.getSignName())) {
throw new ServiceException("短信签名不能为空!");
}
if (StringUtils.isBlank(smsInfoDTO.getTemplateCode())) {
throw new ServiceException("短信模板Code不能为空!");
}
// 设置系统的默认连接超时时间和读取超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
// 初始化acsClient暂不支持region化
IClientProfile profile = DefaultProfile.getProfile(aliYunSmsTwoConfig.getRegionId(), aliYunSmsTwoConfig.getAccessKeyId(), aliYunSmsTwoConfig.getAccessKeySecret());
DefaultProfile.addEndpoint(aliYunSmsTwoConfig.getRegionId(), aliYunSmsTwoConfig.getProduct(), aliYunSmsTwoConfig.getDomain());
IAcsClient acsClient = new DefaultAcsClient(profile);
// 组装请求对象
SendSmsRequest request = new SendSmsRequest();
request.setPhoneNumbers(smsInfoDTO.getPhoneNumbers());
request.setSignName(smsInfoDTO.getSignName());
request.setTemplateCode(smsInfoDTO.getTemplateCode());
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
// 判断响应的结果
if (!SUCCESS.equals(sendSmsResponse.getCode())) {
SmsErrorCodeEnum errorCode = SmsErrorCodeEnum.getMsgByCode(sendSmsResponse.getCode());
log.error("短信发送失败,错误码:{},错误信息:{}", sendSmsResponse.getCode(), errorCode.getMessage());
return false;
}
log.info("短信发送成功code{}", sendSmsResponse.getCode());
return true;
} catch (ClientException e) {
log.error("发送短信出现异常,异常信息:{}", e.getMessage());
throw e;
}
}
} }

View File

@ -42,7 +42,7 @@ public class PatientVO {
@ApiModelProperty(value = "就诊时间") @ApiModelProperty(value = "就诊时间")
private LocalDate visitDate; private LocalDate visitDate;
@ApiModelProperty(value = "签约患者管理任务表id") @ApiModelProperty(value = "患者id")
private Long patientId; private Long patientId;
@ApiModelProperty(value = "签约患者管理任务表id") @ApiModelProperty(value = "签约患者管理任务表id")

View File

@ -0,0 +1,30 @@
package com.xinelu.quartz.controller;
import com.aliyuncs.exceptions.ClientException;
import com.xinelu.quartz.task.SendTextMessageTask;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @Description 短信相关定时任务
* @Author zh
* @Date 2024-07-22
*/
@RestController
@RequestMapping("/monitor/sendTextMessage")
public class SendTextMessageController {
@Resource
private SendTextMessageTask textMessageTask;
/**
* 手动执行短信发送定时任务
*/
@GetMapping("/textMessageSend")
public void textMessageSend() throws ClientException {
textMessageTask.automaticSendTextMessageTask();
}
}

View File

@ -0,0 +1,16 @@
package com.xinelu.quartz.service;
import com.aliyuncs.exceptions.ClientException;
/**
* @Description 短信发送定时任务业务层
* @Author zh
* @Date 2024-05-24
*/
public interface SendTextMessageService {
/**
* 签约患者管理任务路径节点短信发送定时任务
*/
void sendTextMessageSendTask() throws ClientException;
}

View File

@ -0,0 +1,103 @@
package com.xinelu.quartz.service.impl;
import com.aliyuncs.exceptions.ClientException;
import com.xinelu.common.config.AliYunSmsTwoConfig;
import com.xinelu.common.enums.PatientTypeEnum;
import com.xinelu.common.enums.RouteNodeNameEnum;
import com.xinelu.manage.dto.smssend.SmsInfoDTO;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.vo.signpatientmanageroutenode.TextMessage;
import com.xinelu.mobile.utils.SmsSendUtils;
import com.xinelu.quartz.service.SendTextMessageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @Description 短信发送定时任务业务层
* @Author zh
* @Date 2024-07-22
*/
@Service
@Slf4j
public class SendTextMessageServiceImpl implements SendTextMessageService {
@Resource
private SignPatientManageRouteNodeMapper signPatientManageRouteNodeMapper;
@Resource
private SmsSendUtils smsSendUtils;
@Resource
private AliYunSmsTwoConfig aliYunSmsTwoConfig;
@Override
public void sendTextMessageSendTask() throws ClientException {
//查询短信发送数据
List<TextMessage> textMessages = signPatientManageRouteNodeMapper.selectMessagePushSign();
List<TextMessage> messages = new ArrayList<>();
for (TextMessage textMessage : textMessages) {
//判断推送状态
if (Objects.isNull(textMessage.getMessagePushSign()) || textMessage.getMessagePushSign() != 1) {
continue;
}
//过滤脏数据
if (StringUtils.isBlank(textMessage.getPatientType()) || Objects.isNull(textMessage.getRouteNodeDay())) {
continue;
}
//判断路径节点组装数据
if (textMessage.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_DISCHARGE.getInfo()) || textMessage.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_VISIT_DISCHARGE.getInfo())) {
if (textMessage.getPatientType().equals(PatientTypeEnum.DISCHARGED_PATIENT.getInfo()) && Objects.nonNull(textMessage.getDischargeTime())) {
LocalDate localDate = textMessage.getDischargeTime().plusDays(textMessage.getRouteNodeDay());
boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
if (before) {
textMessage.setRouteNodeName(RouteNodeNameEnum.AFTER_DISCHARGE.getName());
messages.add(textMessage);
}
}
}
if (textMessage.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_ADMISSION.getInfo())) {
if (textMessage.getPatientType().equals(PatientTypeEnum.IN_HOSPITAL_PATIENT.getInfo()) && Objects.nonNull(textMessage.getAdmissionTime())) {
LocalDate localDate = textMessage.getAdmissionTime().plusDays(textMessage.getRouteNodeDay());
boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
if (before) {
textMessage.setRouteNodeName(RouteNodeNameEnum.AFTER_ADMISSION.getName());
messages.add(textMessage);
}
}
}
if (textMessage.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_CONSULTATION.getInfo()) || textMessage.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_VISIT_DISCHARGE.getInfo())) {
if (textMessage.getPatientType().equals(PatientTypeEnum.OUTPATIENT.getInfo()) && textMessage.getAdmissionTime() == null && Objects.nonNull(textMessage.getVisitDate())) {
LocalDate localDate = textMessage.getVisitDate().plusDays(textMessage.getRouteNodeDay());
boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
if (before) {
textMessage.setRouteNodeName(RouteNodeNameEnum.AFTER_CONSULTATION.getName());
messages.add(textMessage);
}
}
}
}
//发送
if (CollectionUtils.isNotEmpty(messages)) {
List<Long> ids = new ArrayList<>();
for (TextMessage message : messages) {
SmsInfoDTO smsInfoDTO = new SmsInfoDTO();
smsInfoDTO.setPhoneNumbers(message.getPatientPhone());
smsInfoDTO.setSignName(aliYunSmsTwoConfig.getSignName());
smsInfoDTO.setTemplateCode(aliYunSmsTwoConfig.getTemplateCode());
Boolean aBoolean = smsSendUtils.sendTextMessage(smsInfoDTO);
if (aBoolean) {
ids.add(message.getSignPatientManageRouteNodeId());
}
}
if (CollectionUtils.isNotEmpty(ids)) {
signPatientManageRouteNodeMapper.updateMessageStatusByIds(ids);
}
}
}
}

View File

@ -0,0 +1,31 @@
package com.xinelu.quartz.task;
import com.aliyuncs.exceptions.ClientException;
import com.xinelu.quartz.service.SendTextMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @Description 短信相关定时任务
* @Author zh
* @Date 2024-05-24
*/
@Slf4j
@Component("sendTextMessageTask")
public class SendTextMessageTask {
@Resource
private SendTextMessageService sendTextMessageService;
/**
* 签约患者管理任务路径节点短信发送定时任务每10分钟执行一次
*/
public void automaticSendTextMessageTask() throws ClientException {
log.info("开始执行签约患者管理任务短信推送定时任务......");
sendTextMessageService.sendTextMessageSendTask();
log.info("完成订阅签约患者管理任务路径节点推送定时任务......");
}
}