From e53d97a6aca0594686743f046b0697daac36aad0 Mon Sep 17 00:00:00 2001 From: zhangheng <3226558941@qq.com> Date: Tue, 23 Jul 2024 18:05:38 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SignPatientManageRouteNodeMapper.java | 16 +++ .../TextMessage.java | 66 +++++++++++ .../SignPatientManageRouteNodeMapper.xml | 34 ++++++ .../com/xinelu/mobile/utils/SmsSendUtils.java | 52 +++++++++ .../PatientVO.java | 2 +- .../controller/SendTextMessageController.java | 30 +++++ .../service/SendTextMessageService.java | 16 +++ .../impl/SendTextMessageServiceImpl.java | 103 ++++++++++++++++++ .../quartz/task/SendTextMessageTask.java | 31 ++++++ 9 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/vo/signpatientmanageroutenode/TextMessage.java create mode 100644 postdischarge-quartz/src/main/java/com/xinelu/quartz/controller/SendTextMessageController.java create mode 100644 postdischarge-quartz/src/main/java/com/xinelu/quartz/service/SendTextMessageService.java create mode 100644 postdischarge-quartz/src/main/java/com/xinelu/quartz/service/impl/SendTextMessageServiceImpl.java create mode 100644 postdischarge-quartz/src/main/java/com/xinelu/quartz/task/SendTextMessageTask.java diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/signpatientmanageroutenode/SignPatientManageRouteNodeMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/signpatientmanageroutenode/SignPatientManageRouteNodeMapper.java index 1b244cc5..d7c0d26c 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/signpatientmanageroutenode/SignPatientManageRouteNodeMapper.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/signpatientmanageroutenode/SignPatientManageRouteNodeMapper.java @@ -6,6 +6,7 @@ import com.xinelu.manage.dto.signpatientmanageroutenode.SignPatientManageRouteNo import com.xinelu.manage.vo.signpatientmanageroutenode.PatientManageNodeListVo; import com.xinelu.manage.vo.signpatientmanageroutenode.PatientTaskVo; import com.xinelu.manage.vo.signpatientmanageroutenode.SignPatientManageNodeAuditVo; +import com.xinelu.manage.vo.signpatientmanageroutenode.TextMessage; import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeAuditVo; import org.apache.ibatis.annotations.Param; @@ -125,4 +126,19 @@ public interface SignPatientManageRouteNodeMapper { * @return 患者管理任务路径节点 */ List getRouteNodeContentList(Long patientId); + + /** + * 查询需要推送短信数据 + * + * @return TextMessage + */ + List selectMessagePushSign(); + + /** + * 根据节点id修改状态 + * + * @param ids 节点ids + * @return int + */ + int updateMessageStatusByIds(@Param("ids") List ids); } diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/vo/signpatientmanageroutenode/TextMessage.java b/postdischarge-manage/src/main/java/com/xinelu/manage/vo/signpatientmanageroutenode/TextMessage.java new file mode 100644 index 00000000..389f9b5c --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/vo/signpatientmanageroutenode/TextMessage.java @@ -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; +} diff --git a/postdischarge-manage/src/main/resources/mapper/manage/signpatientmanageroutenode/SignPatientManageRouteNodeMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/signpatientmanageroutenode/SignPatientManageRouteNodeMapper.xml index 1f767dc7..f2993ff9 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/signpatientmanageroutenode/SignPatientManageRouteNodeMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/signpatientmanageroutenode/SignPatientManageRouteNodeMapper.xml @@ -823,4 +823,38 @@ LEFT JOIN special_disease_node sdn ON sdn.route_id = sdr.id where spmr.patient_id = #{patientId} + + + + + update sign_patient_manage_route_node + set message_status = 'EXECUTED' + where id in + + #{ids} + + \ No newline at end of file diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/SmsSendUtils.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/SmsSendUtils.java index eaaa6249..7cdae33b 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/SmsSendUtils.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/SmsSendUtils.java @@ -8,6 +8,7 @@ import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile; import com.xinelu.common.config.AliYunSmsConfig; +import com.xinelu.common.config.AliYunSmsTwoConfig; import com.xinelu.common.enums.SmsErrorCodeEnum; import com.xinelu.common.exception.ServiceException; import com.xinelu.manage.dto.smssend.SmsInfoDTO; @@ -33,6 +34,9 @@ public class SmsSendUtils { @Resource private AliYunSmsConfig aliyunSmsConfig; + @Resource + private AliYunSmsTwoConfig aliYunSmsTwoConfig; + /** * 发送短信 */ @@ -82,5 +86,53 @@ public class SmsSendUtils { 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; + } + } } diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatofficialaccountcallback/PatientVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatofficialaccountcallback/PatientVO.java index b5df079a..63c42ab0 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatofficialaccountcallback/PatientVO.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatofficialaccountcallback/PatientVO.java @@ -42,7 +42,7 @@ public class PatientVO { @ApiModelProperty(value = "就诊时间") private LocalDate visitDate; - @ApiModelProperty(value = "签约患者管理任务表id") + @ApiModelProperty(value = "患者id") private Long patientId; @ApiModelProperty(value = "签约患者管理任务表id") diff --git a/postdischarge-quartz/src/main/java/com/xinelu/quartz/controller/SendTextMessageController.java b/postdischarge-quartz/src/main/java/com/xinelu/quartz/controller/SendTextMessageController.java new file mode 100644 index 00000000..71243b88 --- /dev/null +++ b/postdischarge-quartz/src/main/java/com/xinelu/quartz/controller/SendTextMessageController.java @@ -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(); + } +} diff --git a/postdischarge-quartz/src/main/java/com/xinelu/quartz/service/SendTextMessageService.java b/postdischarge-quartz/src/main/java/com/xinelu/quartz/service/SendTextMessageService.java new file mode 100644 index 00000000..47a839e4 --- /dev/null +++ b/postdischarge-quartz/src/main/java/com/xinelu/quartz/service/SendTextMessageService.java @@ -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; +} diff --git a/postdischarge-quartz/src/main/java/com/xinelu/quartz/service/impl/SendTextMessageServiceImpl.java b/postdischarge-quartz/src/main/java/com/xinelu/quartz/service/impl/SendTextMessageServiceImpl.java new file mode 100644 index 00000000..b8383404 --- /dev/null +++ b/postdischarge-quartz/src/main/java/com/xinelu/quartz/service/impl/SendTextMessageServiceImpl.java @@ -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 textMessages = signPatientManageRouteNodeMapper.selectMessagePushSign(); + List 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 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); + } + } + } +} diff --git a/postdischarge-quartz/src/main/java/com/xinelu/quartz/task/SendTextMessageTask.java b/postdischarge-quartz/src/main/java/com/xinelu/quartz/task/SendTextMessageTask.java new file mode 100644 index 00000000..2696bcff --- /dev/null +++ b/postdischarge-quartz/src/main/java/com/xinelu/quartz/task/SendTextMessageTask.java @@ -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("完成订阅签约患者管理任务路径节点推送定时任务......"); + } +}