feat(medication): 实现用药提醒短信和电话提醒功能
- 新增 intc-common-message 消息服务模块 - 阿里云短信服务 SmsService(用药提醒、漏服提醒、家属通知) - 阿里云语音服务 VoiceService(用药提醒、漏服提醒电话) - HealthPerson 添加 phone 手机号字段 - MedicationPlan 添加 remind_type 提醒方式字段(1-短信 2-电话 3-短信+电话) - MedicationRemindJob 完善提醒逻辑: - 定时扫描待服药任务发送提醒 - 超时30分钟未服药发送加强提醒 - 配置家属通知功能 - 新增数据库更新SQL和Nacos配置示例文件
This commit is contained in:
65
intc-common/intc-common-message/pom.xml
Normal file
65
intc-common/intc-common-message/pom.xml
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<groupId>com.intc</groupId>
|
||||||
|
<artifactId>intc-common</artifactId>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>intc-common-message</artifactId>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
intc-common-message 消息通知服务(短信、语音等)
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- 阿里云短信 SDK -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>dysmsapi20170525</artifactId>
|
||||||
|
<version>2.0.24</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 阿里云语音 SDK -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>dyvmsapi20170525</artifactId>
|
||||||
|
<version>2.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 阿里云核心 SDK -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>tea-openapi</artifactId>
|
||||||
|
<version>0.3.4</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Boot Starter -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Fastjson -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- intc-common-core -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.intc</groupId>
|
||||||
|
<artifactId>intc-common-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.intc.common.message.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云消息服务自动配置
|
||||||
|
*
|
||||||
|
* @author bot5
|
||||||
|
* @date 2026-03-29
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableConfigurationProperties(AliyunMessageProperties.class)
|
||||||
|
@ComponentScan(basePackages = "com.intc.common.message")
|
||||||
|
public class AliyunMessageAutoConfiguration {
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package com.intc.common.message.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云消息服务配置
|
||||||
|
*
|
||||||
|
* @author bot5
|
||||||
|
* @date 2026-03-29
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "aliyun.message")
|
||||||
|
public class AliyunMessageProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云 AccessKey ID
|
||||||
|
*/
|
||||||
|
private String accessKeyId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云 AccessKey Secret
|
||||||
|
*/
|
||||||
|
private String accessKeySecret;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信服务配置
|
||||||
|
*/
|
||||||
|
private SmsConfig sms = new SmsConfig();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 语音服务配置
|
||||||
|
*/
|
||||||
|
private VoiceConfig voice = new VoiceConfig();
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class SmsConfig {
|
||||||
|
/**
|
||||||
|
* 短信签名名称
|
||||||
|
*/
|
||||||
|
private String signName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信模板CODE(用药提醒)
|
||||||
|
*/
|
||||||
|
private String medicationRemindTemplateCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信模板CODE(漏服提醒)
|
||||||
|
*/
|
||||||
|
private String missedRemindTemplateCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信模板CODE(家属通知)
|
||||||
|
*/
|
||||||
|
private String familyNotifyTemplateCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class VoiceConfig {
|
||||||
|
/**
|
||||||
|
* 语音通知模板CODE(用药提醒)
|
||||||
|
*/
|
||||||
|
private String medicationRemindTtsCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 语音通知模板CODE(漏服提醒)
|
||||||
|
*/
|
||||||
|
private String missedRemindTtsCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 被叫号码显示的呼入号码
|
||||||
|
*/
|
||||||
|
private String calledShowNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package com.intc.common.message.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.aliyun.dysmsapi20170525.Client;
|
||||||
|
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
||||||
|
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
|
||||||
|
import com.aliyun.teaopenapi.models.Config;
|
||||||
|
import com.intc.common.message.config.AliyunMessageProperties;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云短信服务
|
||||||
|
*
|
||||||
|
* @author bot5
|
||||||
|
* @date 2026-03-29
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class SmsService {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(SmsService.class);
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AliyunMessageProperties properties;
|
||||||
|
|
||||||
|
private Client smsClient;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() throws Exception {
|
||||||
|
Config config = new Config()
|
||||||
|
.setAccessKeyId(properties.getAccessKeyId())
|
||||||
|
.setAccessKeySecret(properties.getAccessKeySecret())
|
||||||
|
.setEndpoint("dysmsapi.aliyuncs.com");
|
||||||
|
this.smsClient = new Client(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送用药提醒短信
|
||||||
|
*
|
||||||
|
* @param phoneNumber 手机号
|
||||||
|
* @param personName 成员姓名
|
||||||
|
* @param medicineName 药品名称
|
||||||
|
* @param plannedTime 计划服药时间
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
public boolean sendMedicationRemind(String phoneNumber, String personName, String medicineName, String plannedTime) {
|
||||||
|
Map<String, String> templateParams = new HashMap<>();
|
||||||
|
templateParams.put("name", personName);
|
||||||
|
templateParams.put("medicine", medicineName);
|
||||||
|
templateParams.put("time", plannedTime);
|
||||||
|
|
||||||
|
return sendSms(phoneNumber, properties.getSms().getMedicationRemindTemplateCode(), templateParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送漏服提醒短信
|
||||||
|
*
|
||||||
|
* @param phoneNumber 手机号
|
||||||
|
* @param personName 成员姓名
|
||||||
|
* @param medicineName 药品名称
|
||||||
|
* @param plannedTime 计划服药时间
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
public boolean sendMissedRemind(String phoneNumber, String personName, String medicineName, String plannedTime) {
|
||||||
|
Map<String, String> templateParams = new HashMap<>();
|
||||||
|
templateParams.put("name", personName);
|
||||||
|
templateParams.put("medicine", medicineName);
|
||||||
|
templateParams.put("time", plannedTime);
|
||||||
|
|
||||||
|
return sendSms(phoneNumber, properties.getSms().getMissedRemindTemplateCode(), templateParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送家属通知短信
|
||||||
|
*
|
||||||
|
* @param phoneNumber 手机号
|
||||||
|
* @param personName 成员姓名
|
||||||
|
* @param medicineName 药品名称
|
||||||
|
* @param plannedTime 计划服药时间
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
public boolean sendFamilyNotify(String phoneNumber, String personName, String medicineName, String plannedTime) {
|
||||||
|
Map<String, String> templateParams = new HashMap<>();
|
||||||
|
templateParams.put("name", personName);
|
||||||
|
templateParams.put("medicine", medicineName);
|
||||||
|
templateParams.put("time", plannedTime);
|
||||||
|
|
||||||
|
return sendSms(phoneNumber, properties.getSms().getFamilyNotifyTemplateCode(), templateParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
*
|
||||||
|
* @param phoneNumber 手机号
|
||||||
|
* @param templateCode 模板CODE
|
||||||
|
* @param templateParams 模板参数
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
public boolean sendSms(String phoneNumber, String templateCode, Map<String, String> templateParams) {
|
||||||
|
try {
|
||||||
|
SendSmsRequest request = new SendSmsRequest()
|
||||||
|
.setPhoneNumbers(phoneNumber)
|
||||||
|
.setSignName(properties.getSms().getSignName())
|
||||||
|
.setTemplateCode(templateCode)
|
||||||
|
.setTemplateParam(JSON.toJSONString(templateParams));
|
||||||
|
|
||||||
|
SendSmsResponse response = smsClient.sendSms(request);
|
||||||
|
|
||||||
|
if ("OK".equals(response.getBody().getCode())) {
|
||||||
|
log.info("短信发送成功: phone={}, templateCode={}, bizId={}",
|
||||||
|
phoneNumber, templateCode, response.getBody().getBizId());
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
log.error("短信发送失败: phone={}, code={}, message={}",
|
||||||
|
phoneNumber, response.getBody().getCode(), response.getBody().getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("短信发送异常: phone={}, templateCode={}", phoneNumber, templateCode, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package com.intc.common.message.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.aliyun.dyvmsapi20170525.Client;
|
||||||
|
import com.aliyun.dyvmsapi20170525.models.SingleCallByTtsRequest;
|
||||||
|
import com.aliyun.dyvmsapi20170525.models.SingleCallByTtsResponse;
|
||||||
|
import com.aliyun.teaopenapi.models.Config;
|
||||||
|
import com.intc.common.message.config.AliyunMessageProperties;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里云语音通知服务
|
||||||
|
*
|
||||||
|
* @author bot5
|
||||||
|
* @date 2026-03-29
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class VoiceService {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(VoiceService.class);
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AliyunMessageProperties properties;
|
||||||
|
|
||||||
|
private Client voiceClient;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() throws Exception {
|
||||||
|
Config config = new Config()
|
||||||
|
.setAccessKeyId(properties.getAccessKeyId())
|
||||||
|
.setAccessKeySecret(properties.getAccessKeySecret())
|
||||||
|
.setEndpoint("dyvmsapi.aliyuncs.com");
|
||||||
|
this.voiceClient = new Client(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送用药提醒语音电话
|
||||||
|
*
|
||||||
|
* @param phoneNumber 手机号
|
||||||
|
* @param personName 成员姓名
|
||||||
|
* @param medicineName 药品名称
|
||||||
|
* @param plannedTime 计划服药时间
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
public boolean callMedicationRemind(String phoneNumber, String personName, String medicineName, String plannedTime) {
|
||||||
|
Map<String, String> ttsParams = new HashMap<>();
|
||||||
|
ttsParams.put("name", personName);
|
||||||
|
ttsParams.put("medicine", medicineName);
|
||||||
|
ttsParams.put("time", plannedTime);
|
||||||
|
|
||||||
|
return callByTts(phoneNumber, properties.getVoice().getMedicationRemindTtsCode(), ttsParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送漏服提醒语音电话
|
||||||
|
*
|
||||||
|
* @param phoneNumber 手机号
|
||||||
|
* @param personName 成员姓名
|
||||||
|
* @param medicineName 药品名称
|
||||||
|
* @param plannedTime 计划服药时间
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
public boolean callMissedRemind(String phoneNumber, String personName, String medicineName, String plannedTime) {
|
||||||
|
Map<String, String> ttsParams = new HashMap<>();
|
||||||
|
ttsParams.put("name", personName);
|
||||||
|
ttsParams.put("medicine", medicineName);
|
||||||
|
ttsParams.put("time", plannedTime);
|
||||||
|
|
||||||
|
return callByTts(phoneNumber, properties.getVoice().getMissedRemindTtsCode(), ttsParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送语音通知电话
|
||||||
|
*
|
||||||
|
* @param phoneNumber 手机号
|
||||||
|
* @param ttsCode 语音模板CODE
|
||||||
|
* @param ttsParams 模板参数
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
public boolean callByTts(String phoneNumber, String ttsCode, Map<String, String> ttsParams) {
|
||||||
|
try {
|
||||||
|
SingleCallByTtsRequest request = new SingleCallByTtsRequest()
|
||||||
|
.setCalledNumber(phoneNumber)
|
||||||
|
.setCalledShowNumber(properties.getVoice().getCalledShowNumber())
|
||||||
|
.setTtsCode(ttsCode)
|
||||||
|
.setTtsParam(JSON.toJSONString(ttsParams));
|
||||||
|
|
||||||
|
SingleCallByTtsResponse response = voiceClient.singleCallByTts(request);
|
||||||
|
|
||||||
|
if ("OK".equals(response.getBody().getCode())) {
|
||||||
|
log.info("语音电话发送成功: phone={}, ttsCode={}, callId={}",
|
||||||
|
phoneNumber, ttsCode, response.getBody().getCallId());
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
log.error("语音电话发送失败: phone={}, code={}, message={}",
|
||||||
|
phoneNumber, response.getBody().getCode(), response.getBody().getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("语音电话发送异常: phone={}, ttsCode={}", phoneNumber, ttsCode, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
|
||||||
|
com.intc.common.message.config.AliyunMessageAutoConfiguration
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
<module>intc-common-security</module>
|
<module>intc-common-security</module>
|
||||||
<module>intc-common-datascope</module>
|
<module>intc-common-datascope</module>
|
||||||
<module>intc-common-datasource</module>
|
<module>intc-common-datasource</module>
|
||||||
|
<module>intc-common-message</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<artifactId>intc-common</artifactId>
|
<artifactId>intc-common</artifactId>
|
||||||
|
|||||||
@@ -100,6 +100,13 @@
|
|||||||
<groupId>com.intc</groupId>
|
<groupId>com.intc</groupId>
|
||||||
<artifactId>intc-common-swagger</artifactId>
|
<artifactId>intc-common-swagger</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- intc-common-message 消息服务 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.intc</groupId>
|
||||||
|
<artifactId>intc-common-message</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ws.schild</groupId>
|
<groupId>ws.schild</groupId>
|
||||||
<artifactId>jave-core</artifactId>
|
<artifactId>jave-core</artifactId>
|
||||||
|
|||||||
@@ -81,6 +81,11 @@ public class HealthPerson extends BaseEntity
|
|||||||
@Excel(name = "身份证")
|
@Excel(name = "身份证")
|
||||||
private String identityCard;
|
private String identityCard;
|
||||||
|
|
||||||
|
/** 手机号 */
|
||||||
|
@ApiModelProperty(value="手机号")
|
||||||
|
@Excel(name = "手机号")
|
||||||
|
private String phone;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
@@ -100,6 +105,7 @@ public class HealthPerson extends BaseEntity
|
|||||||
.append("ranking", getRanking())
|
.append("ranking", getRanking())
|
||||||
.append("sex", getSex())
|
.append("sex", getSex())
|
||||||
.append("identityCard", getIdentityCard())
|
.append("identityCard", getIdentityCard())
|
||||||
|
.append("phone", getPhone())
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ public class MedicationPlan extends BaseEntity {
|
|||||||
@ApiModelProperty("是否开启提醒:1-是 0-否")
|
@ApiModelProperty("是否开启提醒:1-是 0-否")
|
||||||
private Integer remindEnabled;
|
private Integer remindEnabled;
|
||||||
|
|
||||||
|
@ApiModelProperty("提醒方式:1-短信 2-电话 3-短信+电话")
|
||||||
|
private Integer remindType;
|
||||||
|
|
||||||
@ApiModelProperty("提前提醒分钟数")
|
@ApiModelProperty("提前提醒分钟数")
|
||||||
private Integer remindAdvanceMin;
|
private Integer remindAdvanceMin;
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ public class MedicationPlanVo {
|
|||||||
@ApiModelProperty("是否开启提醒:1-是 0-否")
|
@ApiModelProperty("是否开启提醒:1-是 0-否")
|
||||||
private Integer remindEnabled;
|
private Integer remindEnabled;
|
||||||
|
|
||||||
|
@ApiModelProperty("提醒方式:1-短信 2-电话 3-短信+电话")
|
||||||
|
private Integer remindType;
|
||||||
|
|
||||||
@ApiModelProperty("提前提醒分钟数")
|
@ApiModelProperty("提前提醒分钟数")
|
||||||
private Integer remindAdvanceMin;
|
private Integer remindAdvanceMin;
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ public class MedicationTaskVo {
|
|||||||
@ApiModelProperty("成员名称")
|
@ApiModelProperty("成员名称")
|
||||||
private String personName;
|
private String personName;
|
||||||
|
|
||||||
|
@ApiModelProperty("成员手机号")
|
||||||
|
private String personPhone;
|
||||||
|
|
||||||
@ApiModelProperty("药品名称")
|
@ApiModelProperty("药品名称")
|
||||||
private String medicineName;
|
private String medicineName;
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
package com.intc.health.task;
|
package com.intc.health.task;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.intc.common.message.service.SmsService;
|
||||||
|
import com.intc.common.message.service.VoiceService;
|
||||||
|
import com.intc.health.domain.MedicationTask;
|
||||||
|
import com.intc.health.domain.vo.HealthPersonVo;
|
||||||
|
import com.intc.health.domain.vo.MedicationPlanVo;
|
||||||
import com.intc.health.domain.vo.MedicationTaskVo;
|
import com.intc.health.domain.vo.MedicationTaskVo;
|
||||||
|
import com.intc.health.mapper.HealthPersonMapper;
|
||||||
|
import com.intc.health.mapper.MedicationPlanMapper;
|
||||||
import com.intc.health.mapper.MedicationTaskMapper;
|
import com.intc.health.mapper.MedicationTaskMapper;
|
||||||
|
import com.intc.health.service.IHealthPersonService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,6 +35,20 @@ public class MedicationRemindJob {
|
|||||||
@Resource
|
@Resource
|
||||||
private MedicationTaskMapper taskMapper;
|
private MedicationTaskMapper taskMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MedicationPlanMapper planMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private HealthPersonMapper personMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SmsService smsService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private VoiceService voiceService;
|
||||||
|
|
||||||
|
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫描并发送提醒
|
* 扫描并发送提醒
|
||||||
* 定时任务配置:每分钟执行
|
* 定时任务配置:每分钟执行
|
||||||
@@ -63,11 +86,59 @@ public class MedicationRemindJob {
|
|||||||
task.getPersonName(), task.getMedicineName(),
|
task.getPersonName(), task.getMedicineName(),
|
||||||
task.getPlannedDate(), task.getPlannedTime());
|
task.getPlannedDate(), task.getPlannedTime());
|
||||||
|
|
||||||
// TODO: 实现消息推送
|
// 获取用药计划配置
|
||||||
// 1. 查询用户的提醒设置
|
MedicationPlanVo plan = planMapper.selectById(task.getPlanId());
|
||||||
// 2. 根据设置选择推送渠道
|
if (plan == null) {
|
||||||
// 3. 发送推送消息
|
log.warn("用药计划不存在: planId={}", task.getPlanId());
|
||||||
// 4. 记录提醒日志
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否开启提醒
|
||||||
|
if (plan.getRemindEnabled() == null || plan.getRemindEnabled() == 0) {
|
||||||
|
log.debug("用药计划未开启提醒: planId={}", task.getPlanId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取成员手机号
|
||||||
|
String phone = task.getPersonPhone();
|
||||||
|
if (phone == null || phone.isEmpty()) {
|
||||||
|
log.warn("成员手机号为空: personId={}", task.getPersonId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化计划时间
|
||||||
|
String plannedTimeStr = formatPlannedTime(task);
|
||||||
|
|
||||||
|
// 提醒方式:1-短信 2-电话 3-短信+电话
|
||||||
|
Integer remindType = plan.getRemindType();
|
||||||
|
if (remindType == null) {
|
||||||
|
remindType = 1; // 默认短信
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean smsSuccess = false;
|
||||||
|
boolean voiceSuccess = false;
|
||||||
|
|
||||||
|
// 发送短信提醒
|
||||||
|
if (remindType == 1 || remindType == 3) {
|
||||||
|
smsSuccess = smsService.sendMedicationRemind(phone, task.getPersonName(), task.getMedicineName(), plannedTimeStr);
|
||||||
|
log.info("短信提醒发送结果: phone={}, success={}", phone, smsSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送电话提醒
|
||||||
|
if (remindType == 2 || remindType == 3) {
|
||||||
|
voiceSuccess = voiceService.callMedicationRemind(phone, task.getPersonName(), task.getMedicineName(), plannedTimeStr);
|
||||||
|
log.info("电话提醒发送结果: phone={}, success={}", phone, voiceSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新任务提醒状态
|
||||||
|
MedicationTask updateTask = new MedicationTask();
|
||||||
|
updateTask.setId(task.getId());
|
||||||
|
updateTask.setRemindStatus(1); // 已提醒
|
||||||
|
updateTask.setRemindTime(LocalDateTime.now());
|
||||||
|
taskMapper.update(updateTask);
|
||||||
|
|
||||||
|
log.info("提醒发送完成: taskId={}, person={}, sms={}, voice={}",
|
||||||
|
task.getId(), task.getPersonName(), smsSuccess, voiceSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -109,8 +180,98 @@ public class MedicationRemindJob {
|
|||||||
task.getPersonName(), task.getMedicineName(),
|
task.getPersonName(), task.getMedicineName(),
|
||||||
task.getPlannedDate(), task.getPlannedTime());
|
task.getPlannedDate(), task.getPlannedTime());
|
||||||
|
|
||||||
// TODO: 实现超时提醒逻辑
|
// 获取用药计划配置
|
||||||
// 1. 发送二次提醒
|
MedicationPlanVo plan = planMapper.selectById(task.getPlanId());
|
||||||
// 2. 如果配置了家属通知,通知家属
|
if (plan == null) {
|
||||||
|
log.warn("用药计划不存在: planId={}", task.getPlanId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取成员手机号
|
||||||
|
String phone = task.getPersonPhone();
|
||||||
|
if (phone == null || phone.isEmpty()) {
|
||||||
|
log.warn("成员手机号为空: personId={}", task.getPersonId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化计划时间
|
||||||
|
String plannedTimeStr = formatPlannedTime(task);
|
||||||
|
|
||||||
|
// 提醒方式:超时提醒默认短信+电话
|
||||||
|
Integer remindType = plan.getRemindType();
|
||||||
|
if (remindType == null) {
|
||||||
|
remindType = 3; // 默认短信+电话
|
||||||
|
} else if (remindType == 1) {
|
||||||
|
remindType = 3; // 短信改为短信+电话加强提醒
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送超时短信提醒
|
||||||
|
boolean smsSuccess = smsService.sendMissedRemind(phone, task.getPersonName(), task.getMedicineName(), plannedTimeStr);
|
||||||
|
log.info("超时短信提醒发送结果: phone={}, success={}", phone, smsSuccess);
|
||||||
|
|
||||||
|
// 发送超时电话提醒
|
||||||
|
if (remindType == 2 || remindType == 3) {
|
||||||
|
boolean voiceSuccess = voiceService.callMissedRemind(phone, task.getPersonName(), task.getMedicineName(), plannedTimeStr);
|
||||||
|
log.info("超时电话提醒发送结果: phone={}, success={}", phone, voiceSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新任务提醒状态为已超时提醒
|
||||||
|
MedicationTask updateTask = new MedicationTask();
|
||||||
|
updateTask.setId(task.getId());
|
||||||
|
updateTask.setRemindStatus(2); // 已超时提醒
|
||||||
|
updateTask.setRemindTime(LocalDateTime.now());
|
||||||
|
taskMapper.update(updateTask);
|
||||||
|
|
||||||
|
// 如果配置了家属通知,通知家属
|
||||||
|
if (plan.getNotifyFamily() != null && plan.getNotifyFamily() == 1) {
|
||||||
|
notifyFamily(task, plan);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("超时提醒发送完成: taskId={}, person={}", task.getId(), task.getPersonName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知家属
|
||||||
|
*/
|
||||||
|
private void notifyFamily(MedicationTaskVo task, MedicationPlanVo plan) {
|
||||||
|
JsonNode familyMemberIds = plan.getFamilyMemberIds();
|
||||||
|
if (familyMemberIds == null || !familyMemberIds.isArray()) {
|
||||||
|
log.debug("未配置家属成员");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String plannedTimeStr = formatPlannedTime(task);
|
||||||
|
|
||||||
|
for (JsonNode memberIdNode : familyMemberIds) {
|
||||||
|
Long memberId = memberIdNode.asLong();
|
||||||
|
HealthPersonVo familyMember = personMapper.selectHealthPersonById(memberId);
|
||||||
|
if (familyMember == null) {
|
||||||
|
log.warn("家属成员不存在: memberId={}", memberId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取家属手机号(需要在HealthPersonVo中添加phone字段)
|
||||||
|
String familyPhone = familyMember.getPhone();
|
||||||
|
if (familyPhone == null || familyPhone.isEmpty()) {
|
||||||
|
log.warn("家属手机号为空: memberId={}", memberId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送家属通知短信
|
||||||
|
boolean success = smsService.sendFamilyNotify(familyPhone, task.getPersonName(), task.getMedicineName(), plannedTimeStr);
|
||||||
|
log.info("家属通知发送结果: familyPhone={}, familyMember={}, success={}",
|
||||||
|
familyPhone, familyMember.getName(), success);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化计划时间
|
||||||
|
*/
|
||||||
|
private String formatPlannedTime(MedicationTaskVo task) {
|
||||||
|
if (task.getPlannedTime() != null) {
|
||||||
|
// plannedTime是Date类型,需要转换
|
||||||
|
return new java.text.SimpleDateFormat("HH:mm").format(task.getPlannedTime());
|
||||||
|
}
|
||||||
|
return "未知时间";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,10 +21,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="ranking" column="ranking" />
|
<result property="ranking" column="ranking" />
|
||||||
<result property="sex" column="sex" />
|
<result property="sex" column="sex" />
|
||||||
<result property="identityCard" column="identity_card" />
|
<result property="identityCard" column="identity_card" />
|
||||||
|
<result property="phone" column="phone" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectHealthPersonVo">
|
<sql id="selectHealthPersonVo">
|
||||||
select a.id, a.name,a.sex,a.identity_card, a.type, a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, a.remark, a.birthday, a.nick_name, a.height, a.weight, a.ranking from health_person a
|
select a.id, a.name,a.sex,a.identity_card, a.phone, a.type, a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, a.remark, a.birthday, a.nick_name, a.height, a.weight, a.ranking from health_person a
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectHealthPersonList" parameterType="HealthPersonDto" resultMap="HealthPersonResult">
|
<select id="selectHealthPersonList" parameterType="HealthPersonDto" resultMap="HealthPersonResult">
|
||||||
@@ -64,6 +65,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="ranking != null">ranking,</if>
|
<if test="ranking != null">ranking,</if>
|
||||||
<if test="sex != null and sex != ''">sex,</if>
|
<if test="sex != null and sex != ''">sex,</if>
|
||||||
<if test="identityCard != null and identityCard != ''">identity_card,</if>
|
<if test="identityCard != null and identityCard != ''">identity_card,</if>
|
||||||
|
<if test="phone != null and phone != ''">phone,</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="id != null">#{id},</if>
|
<if test="id != null">#{id},</if>
|
||||||
@@ -82,6 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="ranking != null">#{ranking},</if>
|
<if test="ranking != null">#{ranking},</if>
|
||||||
<if test="sex != null and sex != ''">#{sex},</if>
|
<if test="sex != null and sex != ''">#{sex},</if>
|
||||||
<if test="identityCard != null and identityCard != ''">#{identityCard},</if>
|
<if test="identityCard != null and identityCard != ''">#{identityCard},</if>
|
||||||
|
<if test="phone != null and phone != ''">#{phone},</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
@@ -103,6 +106,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="ranking != null">ranking = #{ranking},</if>
|
<if test="ranking != null">ranking = #{ranking},</if>
|
||||||
<if test="sex != null and sex != ''">sex = #{sex},</if>
|
<if test="sex != null and sex != ''">sex = #{sex},</if>
|
||||||
<if test="identityCard != null and identityCard != ''">identity_card = #{identityCard},</if>
|
<if test="identityCard != null and identityCard != ''">identity_card = #{identityCard},</if>
|
||||||
|
<if test="phone != null and phone != ''">phone = #{phone},</if>
|
||||||
</trim>
|
</trim>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
<result property="startDate" column="start_date"/>
|
<result property="startDate" column="start_date"/>
|
||||||
<result property="endDate" column="end_date"/>
|
<result property="endDate" column="end_date"/>
|
||||||
<result property="remindEnabled" column="remind_enabled"/>
|
<result property="remindEnabled" column="remind_enabled"/>
|
||||||
|
<result property="remindType" column="remind_type"/>
|
||||||
<result property="remindAdvanceMin" column="remind_advance_min"/>
|
<result property="remindAdvanceMin" column="remind_advance_min"/>
|
||||||
<result property="notifyFamily" column="notify_family"/>
|
<result property="notifyFamily" column="notify_family"/>
|
||||||
<result property="familyMemberIds" column="family_member_ids" typeHandler="com.intc.common.core.handler.JsonNodeTypeHandler"/>
|
<result property="familyMemberIds" column="family_member_ids" typeHandler="com.intc.common.core.handler.JsonNodeTypeHandler"/>
|
||||||
@@ -35,7 +36,7 @@
|
|||||||
c.disease_name as chronic_disease_name, a.plan_name, a.medicine_id,
|
c.disease_name as chronic_disease_name, a.plan_name, a.medicine_id,
|
||||||
a.medicine_name, a.specification, a.dosage_per_time, a.dosage_unit,
|
a.medicine_name, a.specification, a.dosage_per_time, a.dosage_unit,
|
||||||
a.frequency_type, a.frequency_config, a.time_slots, a.start_date, a.end_date,
|
a.frequency_type, a.frequency_config, a.time_slots, a.start_date, a.end_date,
|
||||||
a.remind_enabled, a.remind_advance_min, a.notify_family, a.family_member_ids,
|
a.remind_enabled, a.remind_type, a.remind_advance_min, a.notify_family, a.family_member_ids,
|
||||||
a.status, a.create_by, a.create_time,
|
a.status, a.create_by, a.create_time,
|
||||||
(select count(1) from medication_task t where t.plan_id = a.id and t.del_flag = 0 and t.planned_date = current_date) as today_total,
|
(select count(1) from medication_task t where t.plan_id = a.id and t.del_flag = 0 and t.planned_date = current_date) as today_total,
|
||||||
(select count(1) from medication_task t where t.plan_id = a.id and t.del_flag = 0 and t.planned_date = current_date and t.status = 1) as today_completed
|
(select count(1) from medication_task t where t.plan_id = a.id and t.del_flag = 0 and t.planned_date = current_date and t.status = 1) as today_completed
|
||||||
@@ -94,6 +95,7 @@
|
|||||||
<if test="startDate != null">start_date,</if>
|
<if test="startDate != null">start_date,</if>
|
||||||
<if test="endDate != null">end_date,</if>
|
<if test="endDate != null">end_date,</if>
|
||||||
<if test="remindEnabled != null">remind_enabled,</if>
|
<if test="remindEnabled != null">remind_enabled,</if>
|
||||||
|
<if test="remindType != null">remind_type,</if>
|
||||||
<if test="remindAdvanceMin != null">remind_advance_min,</if>
|
<if test="remindAdvanceMin != null">remind_advance_min,</if>
|
||||||
<if test="notifyFamily != null">notify_family,</if>
|
<if test="notifyFamily != null">notify_family,</if>
|
||||||
<if test="familyMemberIds != null">family_member_ids,</if>
|
<if test="familyMemberIds != null">family_member_ids,</if>
|
||||||
@@ -118,6 +120,7 @@
|
|||||||
<if test="startDate != null">#{startDate},</if>
|
<if test="startDate != null">#{startDate},</if>
|
||||||
<if test="endDate != null">#{endDate},</if>
|
<if test="endDate != null">#{endDate},</if>
|
||||||
<if test="remindEnabled != null">#{remindEnabled},</if>
|
<if test="remindEnabled != null">#{remindEnabled},</if>
|
||||||
|
<if test="remindType != null">#{remindType},</if>
|
||||||
<if test="remindAdvanceMin != null">#{remindAdvanceMin},</if>
|
<if test="remindAdvanceMin != null">#{remindAdvanceMin},</if>
|
||||||
<if test="notifyFamily != null">#{notifyFamily},</if>
|
<if test="notifyFamily != null">#{notifyFamily},</if>
|
||||||
<if test="familyMemberIds != null">#{familyMemberIds, typeHandler=com.intc.common.core.handler.JsonNodeTypeHandler},</if>
|
<if test="familyMemberIds != null">#{familyMemberIds, typeHandler=com.intc.common.core.handler.JsonNodeTypeHandler},</if>
|
||||||
@@ -146,6 +149,7 @@
|
|||||||
<if test="startDate != null">start_date = #{startDate},</if>
|
<if test="startDate != null">start_date = #{startDate},</if>
|
||||||
<if test="endDate != null">end_date = #{endDate},</if>
|
<if test="endDate != null">end_date = #{endDate},</if>
|
||||||
<if test="remindEnabled != null">remind_enabled = #{remindEnabled},</if>
|
<if test="remindEnabled != null">remind_enabled = #{remindEnabled},</if>
|
||||||
|
<if test="remindType != null">remind_type = #{remindType},</if>
|
||||||
<if test="remindAdvanceMin != null">remind_advance_min = #{remindAdvanceMin},</if>
|
<if test="remindAdvanceMin != null">remind_advance_min = #{remindAdvanceMin},</if>
|
||||||
<if test="notifyFamily != null">notify_family = #{notifyFamily},</if>
|
<if test="notifyFamily != null">notify_family = #{notifyFamily},</if>
|
||||||
<if test="familyMemberIds != null">family_member_ids = #{familyMemberIds, typeHandler=com.intc.common.core.handler.JsonNodeTypeHandler},</if>
|
<if test="familyMemberIds != null">family_member_ids = #{familyMemberIds, typeHandler=com.intc.common.core.handler.JsonNodeTypeHandler},</if>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<result property="planName" column="plan_name"/>
|
<result property="planName" column="plan_name"/>
|
||||||
<result property="personId" column="person_id"/>
|
<result property="personId" column="person_id"/>
|
||||||
<result property="personName" column="person_name"/>
|
<result property="personName" column="person_name"/>
|
||||||
|
<result property="personPhone" column="person_phone"/>
|
||||||
<result property="medicineName" column="medicine_name"/>
|
<result property="medicineName" column="medicine_name"/>
|
||||||
<result property="plannedDate" column="planned_date"/>
|
<result property="plannedDate" column="planned_date"/>
|
||||||
<result property="plannedTime" column="planned_time"/>
|
<result property="plannedTime" column="planned_time"/>
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectVo">
|
<sql id="selectVo">
|
||||||
select a.id, a.plan_id, p.plan_name, a.person_id, m.name as person_name,
|
select a.id, a.plan_id, p.plan_name, a.person_id, m.name as person_name, m.phone as person_phone,
|
||||||
a.medicine_name, a.planned_date, a.planned_time, a.planned_dosage,
|
a.medicine_name, a.planned_date, a.planned_time, a.planned_dosage,
|
||||||
a.actual_time, a.actual_dosage, a.status, a.confirm_type, a.notes,
|
a.actual_time, a.actual_dosage, a.status, a.confirm_type, a.notes,
|
||||||
a.remind_status, a.remind_time, a.create_time
|
a.remind_status, a.remind_time, a.create_time
|
||||||
|
|||||||
7
pom.xml
7
pom.xml
@@ -216,6 +216,13 @@
|
|||||||
<artifactId>intc-api-system</artifactId>
|
<artifactId>intc-api-system</artifactId>
|
||||||
<version>${intc.version}</version>
|
<version>${intc.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 消息服务 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.intc</groupId>
|
||||||
|
<artifactId>intc-common-message</artifactId>
|
||||||
|
<version>${intc.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|||||||
32
sql/aliyun-message-config-example.yml
Normal file
32
sql/aliyun-message-config-example.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# 阿里云消息服务配置示例(在Nacos配置中心添加)
|
||||||
|
# 配置项:intc-health-dev.yml 或独立配置文件
|
||||||
|
|
||||||
|
aliyun:
|
||||||
|
message:
|
||||||
|
# 阿里云 AccessKey(请替换为实际值)
|
||||||
|
accessKeyId: ${ALIYUN_ACCESS_KEY_ID:your-access-key-id}
|
||||||
|
accessKeySecret: ${ALIYUN_ACCESS_KEY_SECRET:your-access-key-secret}
|
||||||
|
|
||||||
|
# 短信配置
|
||||||
|
sms:
|
||||||
|
signName: 智聪健康
|
||||||
|
# 用药提醒短信模板CODE(需要在阿里云短信服务中申请)
|
||||||
|
medicationRemindTemplateCode: SMS_123456789
|
||||||
|
# 漏服提醒短信模板CODE
|
||||||
|
missedRemindTemplateCode: SMS_123456790
|
||||||
|
# 家属通知短信模板CODE
|
||||||
|
familyNotifyTemplateCode: SMS_123456791
|
||||||
|
|
||||||
|
# 语音配置
|
||||||
|
voice:
|
||||||
|
# 用药提醒语音模板CODE(需要在阿里云语音服务中申请)
|
||||||
|
medicationRemindTtsCode: TTS_123456789
|
||||||
|
# 漏服提醒语音模板CODE
|
||||||
|
missedRemindTtsCode: TTS_123456790
|
||||||
|
# 被叫号码显示的呼入号码(需要在阿里云购买号码)
|
||||||
|
calledShowNumber: 4001234567
|
||||||
|
|
||||||
|
# 短信模板示例(在阿里云申请时使用):
|
||||||
|
# 用药提醒模板:您好,${name}请在${time}服用${medicine},请按时服药保持健康。
|
||||||
|
# 漏服提醒模板:您好,${name}未在${time}服用${medicine},请尽快补服或咨询医生。
|
||||||
|
# 家属通知模板:您好,${name}超时未服用${medicine}(计划时间${time}),请关注提醒。
|
||||||
16
sql/update_medication_remind.sql
Normal file
16
sql/update_medication_remind.sql
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
-- 用药提醒功能更新SQL
|
||||||
|
-- 1. 给health_person添加phone字段
|
||||||
|
-- 2. 给medication_plan添加remind_type字段
|
||||||
|
|
||||||
|
-- 1. health_person表添加phone字段
|
||||||
|
ALTER TABLE health_person ADD COLUMN IF NOT EXISTS phone VARCHAR(20);
|
||||||
|
|
||||||
|
COMMENT ON COLUMN health_person.phone IS '手机号';
|
||||||
|
|
||||||
|
-- 2. medication_plan表添加remind_type字段
|
||||||
|
ALTER TABLE medication_plan ADD COLUMN IF NOT EXISTS remind_type INTEGER DEFAULT 1;
|
||||||
|
|
||||||
|
COMMENT ON COLUMN medication_plan.remind_type IS '提醒方式:1-短信 2-电话 3-短信+电话';
|
||||||
|
|
||||||
|
-- 更新已有数据,默认提醒方式为短信
|
||||||
|
UPDATE medication_plan SET remind_type = 1 WHERE remind_type IS NULL AND remind_enabled = 1;
|
||||||
Reference in New Issue
Block a user