Commit be1029d37fda74bd178bf88b4c6a849f165a6433

Authored by chenjunyu_1481036421
1 parent 4be1f8c7

feat:新增:1.阿里云电话通知。2.删除设备时同时删除该设备的告警

@@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; @@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j;
11 import org.apache.commons.lang3.StringUtils; 11 import org.apache.commons.lang3.StringUtils;
12 import org.springframework.http.ResponseEntity; 12 import org.springframework.http.ResponseEntity;
13 import org.springframework.security.access.prepost.PreAuthorize; 13 import org.springframework.security.access.prepost.PreAuthorize;
  14 +import org.springframework.transaction.annotation.Transactional;
14 import org.springframework.validation.annotation.Validated; 15 import org.springframework.validation.annotation.Validated;
15 import org.springframework.web.bind.annotation.*; 16 import org.springframework.web.bind.annotation.*;
16 import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg; 17 import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg;
@@ -39,6 +40,7 @@ import org.thingsboard.server.common.data.yunteng.utils.tools.ResponseResult; @@ -39,6 +40,7 @@ import org.thingsboard.server.common.data.yunteng.utils.tools.ResponseResult;
39 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; 40 import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
40 import org.thingsboard.server.controller.BaseController; 41 import org.thingsboard.server.controller.BaseController;
41 import org.thingsboard.server.dao.yunteng.entities.TkUserCollectEntity; 42 import org.thingsboard.server.dao.yunteng.entities.TkUserCollectEntity;
  43 +import org.thingsboard.server.dao.yunteng.service.TkAlarmInfoService;
42 import org.thingsboard.server.dao.yunteng.service.TkDeviceProfileService; 44 import org.thingsboard.server.dao.yunteng.service.TkDeviceProfileService;
43 import org.thingsboard.server.dao.yunteng.service.TkDeviceService; 45 import org.thingsboard.server.dao.yunteng.service.TkDeviceService;
44 import org.thingsboard.server.dao.yunteng.service.TkUserCollectService; 46 import org.thingsboard.server.dao.yunteng.service.TkUserCollectService;
@@ -63,6 +65,7 @@ public class TkDeviceController extends BaseController { @@ -63,6 +65,7 @@ public class TkDeviceController extends BaseController {
63 private final ObjectMapper objectMapper; 65 private final ObjectMapper objectMapper;
64 private final TkDeviceProfileService ytDeviceProfileService; 66 private final TkDeviceProfileService ytDeviceProfileService;
65 private final GatewayNotificationsService gatewayNotificationsService; 67 private final GatewayNotificationsService gatewayNotificationsService;
  68 + private final TkAlarmInfoService tkAlarmInfoService ;
66 69
67 70
68 @PostMapping 71 @PostMapping
@@ -314,6 +317,7 @@ public class TkDeviceController extends BaseController { @@ -314,6 +317,7 @@ public class TkDeviceController extends BaseController {
314 317
315 @DeleteMapping 318 @DeleteMapping
316 @ApiOperation("删除") 319 @ApiOperation("删除")
  320 + @Transactional
317 @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:device:delete'})") 321 @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{'api:yt:device:delete'})")
318 public void deleteDevices(@Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO) 322 public void deleteDevices(@Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO)
319 throws ThingsboardException { 323 throws ThingsboardException {
@@ -322,6 +326,7 @@ public class TkDeviceController extends BaseController { @@ -322,6 +326,7 @@ public class TkDeviceController extends BaseController {
322 if(null !=tdIds){ 326 if(null !=tdIds){
323 for (String id : tdIds) { 327 for (String id : tdIds) {
324 deleteTbDevice(id); 328 deleteTbDevice(id);
  329 + tkAlarmInfoService.deleteByDeviceId(currentTenantId,id);
325 } 330 }
326 tkdeviceService.deleteDevices(currentTenantId, deleteDTO.getIds()); 331 tkdeviceService.deleteDevices(currentTenantId, deleteDTO.getIds());
327 } 332 }
@@ -132,6 +132,11 @@ @@ -132,6 +132,11 @@
132 <artifactId>alibaba-dingtalk-service-sdk</artifactId> 132 <artifactId>alibaba-dingtalk-service-sdk</artifactId>
133 <version>2.0.0</version> 133 <version>2.0.0</version>
134 </dependency> 134 </dependency>
  135 + <dependency>
  136 + <groupId>com.aliyun</groupId>
  137 + <artifactId>dyvmsapi20170525</artifactId>
  138 + <version>2.1.4</version>
  139 + </dependency>
135 <!-- 腾讯云短信 --> 140 <!-- 腾讯云短信 -->
136 <dependency> 141 <dependency>
137 <groupId>com.tencentcloudapi</groupId> 142 <groupId>com.tencentcloudapi</groupId>
@@ -5,13 +5,15 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; @@ -5,13 +5,15 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
5 import org.thingsboard.server.common.data.yunteng.config.dingtalk.DingTalkSmsProviderConfiguration; 5 import org.thingsboard.server.common.data.yunteng.config.dingtalk.DingTalkSmsProviderConfiguration;
6 import org.thingsboard.server.common.data.yunteng.config.message.ali.AliSmsProviderConfiguration; 6 import org.thingsboard.server.common.data.yunteng.config.message.ali.AliSmsProviderConfiguration;
7 import org.thingsboard.server.common.data.yunteng.config.message.tencent.TencentSmsProviderConfiguration; 7 import org.thingsboard.server.common.data.yunteng.config.message.tencent.TencentSmsProviderConfiguration;
  8 +import org.thingsboard.server.common.data.yunteng.config.voice.AliVoiceSmsProviderConfiguration;
8 import org.thingsboard.server.common.data.yunteng.enums.MessageProviderTypeEnum; 9 import org.thingsboard.server.common.data.yunteng.enums.MessageProviderTypeEnum;
9 10
10 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") 11 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
11 @JsonSubTypes({ 12 @JsonSubTypes({
12 - @JsonSubTypes.Type(value = AliSmsProviderConfiguration.class, name = "ALI_CLOUD"),  
13 - @JsonSubTypes.Type(value = TencentSmsProviderConfiguration.class, name = "TENCENT_CLOUD"),  
14 - @JsonSubTypes.Type(value = DingTalkSmsProviderConfiguration.class, name = "DING_TALK") 13 + @JsonSubTypes.Type(value = AliSmsProviderConfiguration.class, name = "ALI_CLOUD"),
  14 + @JsonSubTypes.Type(value = TencentSmsProviderConfiguration.class, name = "TENCENT_CLOUD"),
  15 + @JsonSubTypes.Type(value = DingTalkSmsProviderConfiguration.class, name = "DING_TALK"),
  16 + @JsonSubTypes.Type(value = AliVoiceSmsProviderConfiguration.class, name = "ALI_VOICE")
15 }) 17 })
16 public interface MessageProviderConfiguration { 18 public interface MessageProviderConfiguration {
17 19
@@ -7,6 +7,8 @@ import org.thingsboard.server.common.data.yunteng.config.message.ali.AliSmsProvi @@ -7,6 +7,8 @@ import org.thingsboard.server.common.data.yunteng.config.message.ali.AliSmsProvi
7 import org.thingsboard.server.common.data.yunteng.config.message.ali.AliSmsSender; 7 import org.thingsboard.server.common.data.yunteng.config.message.ali.AliSmsSender;
8 import org.thingsboard.server.common.data.yunteng.config.message.tencent.TencentSmsProviderConfiguration; 8 import org.thingsboard.server.common.data.yunteng.config.message.tencent.TencentSmsProviderConfiguration;
9 import org.thingsboard.server.common.data.yunteng.config.message.tencent.TencentSmsSender; 9 import org.thingsboard.server.common.data.yunteng.config.message.tencent.TencentSmsSender;
  10 +import org.thingsboard.server.common.data.yunteng.config.voice.AliVoiceSmsProviderConfiguration;
  11 +import org.thingsboard.server.common.data.yunteng.config.voice.AliVoiceSmsSender;
10 12
11 import java.util.HashMap; 13 import java.util.HashMap;
12 import java.util.List; 14 import java.util.List;
@@ -40,6 +42,9 @@ public class TkDefaultMessageSenderFactory implements MessageSenderFactory { @@ -40,6 +42,9 @@ public class TkDefaultMessageSenderFactory implements MessageSenderFactory {
40 (DingTalkSmsProviderConfiguration) config); 42 (DingTalkSmsProviderConfiguration) config);
41 smsSenderMap.put(key,dingTalkSmsSender); 43 smsSenderMap.put(key,dingTalkSmsSender);
42 return dingTalkSmsSender; 44 return dingTalkSmsSender;
  45 + case ALI_VOICE:
  46 + return new AliVoiceSmsSender(
  47 + (AliVoiceSmsProviderConfiguration) config);
43 default: 48 default:
44 throw new RuntimeException("Unknown SMS provider type " + config.getType()); 49 throw new RuntimeException("Unknown SMS provider type " + config.getType());
45 } 50 }
  1 +package org.thingsboard.server.common.data.yunteng.config.voice;
  2 +
  3 +import lombok.Data;
  4 +import org.thingsboard.server.common.data.yunteng.config.message.MessageProviderConfiguration;
  5 +import org.thingsboard.server.common.data.yunteng.enums.MessageProviderTypeEnum;
  6 +
  7 +@Data
  8 +public class AliVoiceSmsProviderConfiguration implements MessageProviderConfiguration {
  9 +
  10 + /** 阿里云AccessKeyId */
  11 + private String accessKeyId;
  12 +
  13 + /** 阿里云AccessKeySecret */
  14 + private String accessKeySecret;
  15 +
  16 + @Override
  17 + public MessageProviderTypeEnum getType() {
  18 + return MessageProviderTypeEnum.ALI_VOICE;
  19 + }
  20 +}
  1 +package org.thingsboard.server.common.data.yunteng.config.voice;
  2 +
  3 +
  4 +
  5 +import com.aliyun.dyvmsapi20170525.Client;
  6 +import com.aliyun.dyvmsapi20170525.models.SingleCallByTtsRequest;
  7 +import com.aliyun.dyvmsapi20170525.models.SingleCallByTtsResponse;
  8 +import com.aliyun.teaopenapi.models.Config;
  9 +import com.aliyun.teautil.models.RuntimeOptions;
  10 +import lombok.extern.slf4j.Slf4j;
  11 +import org.apache.commons.lang3.StringUtils;
  12 +import org.thingsboard.server.common.data.yunteng.config.message.AbstractMessageSender;
  13 +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException;
  14 +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
  15 +import org.thingsboard.server.common.data.yunteng.enums.ResponseCodeEnum;
  16 +
  17 +import java.util.LinkedHashMap;
  18 +
  19 +@Slf4j
  20 +public class AliVoiceSmsSender extends AbstractMessageSender {
  21 +
  22 + /** 阿里云短信参数配置 */
  23 + private final AliVoiceSmsProviderConfiguration config;
  24 +
  25 + private Config profile;
  26 +
  27 + public AliVoiceSmsSender(AliVoiceSmsProviderConfiguration config) {
  28 + if (StringUtils.isEmpty(config.getAccessKeyId())
  29 + || StringUtils.isEmpty(config.getAccessKeyId())) {
  30 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  31 + }
  32 + this.config = config;
  33 + initProfile();
  34 + }
  35 +
  36 + /** 使用AK&SK初始化账号Client */
  37 + private void initProfile() {
  38 + String endpoint = "dyvmsapi.aliyuncs.com";
  39 + profile = new Config();
  40 + profile.setAccessKeyId(config.getAccessKeyId());
  41 + profile.setAccessKeySecret(config.getAccessKeySecret());
  42 + profile.setEndpoint(endpoint);
  43 + }
  44 +
  45 + @Override
  46 + public String sendSms(
  47 + String phone, String templateCode, LinkedHashMap<String, Object> param, String signName) {
  48 + validatePhoneNumber(phone);
  49 + if (null == param || param.isEmpty()) {
  50 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  51 + }
  52 + try {
  53 + Client client = new Client(profile);
  54 + SingleCallByTtsRequest singleCallByTtsRequest = new SingleCallByTtsRequest();
  55 + singleCallByTtsRequest.setCalledShowNumber(StringUtils.isEmpty(signName)?null:signName);
  56 + singleCallByTtsRequest.setCalledNumber(phone);
  57 + singleCallByTtsRequest.setTtsCode(templateCode);
  58 + String TtsCodeParam = "{\"deviceName\":\""+param.get("deviceName")+"\",\"severity\":\""+param.get("severity")+"\"}";
  59 + singleCallByTtsRequest.setTtsParam(TtsCodeParam);
  60 + singleCallByTtsRequest.setSpeed(-100);
  61 + RuntimeOptions runtimeOptions = new RuntimeOptions();
  62 + SingleCallByTtsResponse response = client.singleCallByTtsWithOptions(singleCallByTtsRequest,runtimeOptions);
  63 + return response.getBody().getCode().equalsIgnoreCase(ResponseCodeEnum.OK.name())
  64 + ? ResponseCodeEnum.SUCCESS.name()
  65 + : response.getBody().getMessage();
  66 + } catch (Exception e) {
  67 + e.printStackTrace();
  68 + return e.getMessage();
  69 + }
  70 + }
  71 +}
@@ -4,5 +4,6 @@ package org.thingsboard.server.common.data.yunteng.enums; @@ -4,5 +4,6 @@ package org.thingsboard.server.common.data.yunteng.enums;
4 public enum MessageProviderTypeEnum { 4 public enum MessageProviderTypeEnum {
5 ALI_CLOUD, 5 ALI_CLOUD,
6 TENCENT_CLOUD, 6 TENCENT_CLOUD,
7 - DING_TALK 7 + DING_TALK,
  8 + ALI_VOICE
8 } 9 }
@@ -5,5 +5,6 @@ public enum MessageTypeEnum { @@ -5,5 +5,6 @@ public enum MessageTypeEnum {
5 EMAIL_MESSAGE, 5 EMAIL_MESSAGE,
6 PHONE_MESSAGE, 6 PHONE_MESSAGE,
7 DING_TALK_MESSAGE, 7 DING_TALK_MESSAGE,
8 - WECHAT_MESSAGE 8 + WECHAT_MESSAGE,
  9 + VOICE_MESSAGE
9 } 10 }
@@ -122,4 +122,10 @@ public class TkAlarmInfoServiceImpl implements TkAlarmInfoService { @@ -122,4 +122,10 @@ public class TkAlarmInfoServiceImpl implements TkAlarmInfoService {
122 public List<SysDictDTO> alarmType(TenantId tenantId) { 122 public List<SysDictDTO> alarmType(TenantId tenantId) {
123 return ReflectUtils.sourceToTarget(tkJpaAarmDao.alarmType(tenantId.getId()), SysDictDTO.class); 123 return ReflectUtils.sourceToTarget(tkJpaAarmDao.alarmType(tenantId.getId()), SysDictDTO.class);
124 } 124 }
  125 +
  126 + @Override
  127 + public void deleteByDeviceId(String tenantId, String tbDeviceId) {
  128 + tkJpaAarmDao.deleteByDeviceId(tenantId,tbDeviceId);
  129 + }
  130 +
125 } 131 }
@@ -66,13 +66,13 @@ public class TkMessageServiceImpl implements TkMessageService { @@ -66,13 +66,13 @@ public class TkMessageServiceImpl implements TkMessageService {
66 } 66 }
67 /** 消息模板是否可用 */ 67 /** 消息模板是否可用 */
68 QueryWrapper<TkMessageTemplateEntity> messageTemplateQueryWrapper = 68 QueryWrapper<TkMessageTemplateEntity> messageTemplateQueryWrapper =
69 - new QueryWrapper<TkMessageTemplateEntity>(); 69 + new QueryWrapper<TkMessageTemplateEntity>();
70 messageTemplateQueryWrapper 70 messageTemplateQueryWrapper
71 - .lambda()  
72 - .eq(TkMessageTemplateEntity::getId, templateId)  
73 - .eq(TkMessageTemplateEntity::getStatus, AssetStatusEnum.ENABLE.ordinal()); 71 + .lambda()
  72 + .eq(TkMessageTemplateEntity::getId, templateId)
  73 + .eq(TkMessageTemplateEntity::getStatus, AssetStatusEnum.ENABLE.ordinal());
74 TkMessageTemplateEntity messageTemplate = 74 TkMessageTemplateEntity messageTemplate =
75 - messageTemplateMapper.selectOne(messageTemplateQueryWrapper); 75 + messageTemplateMapper.selectOne(messageTemplateQueryWrapper);
76 if (null == messageTemplate) { 76 if (null == messageTemplate) {
77 throw new TkDataValidationException(ErrorMessage.MESSAGE_TEMPLATE_NOT_EXISTS.getMessage()); 77 throw new TkDataValidationException(ErrorMessage.MESSAGE_TEMPLATE_NOT_EXISTS.getMessage());
78 } 78 }
@@ -87,12 +87,12 @@ public class TkMessageServiceImpl implements TkMessageService { @@ -87,12 +87,12 @@ public class TkMessageServiceImpl implements TkMessageService {
87 87
88 boolean isMatch = true; 88 boolean isMatch = true;
89 if (platForm.equals(MessageProviderTypeEnum.TENCENT_CLOUD.name()) 89 if (platForm.equals(MessageProviderTypeEnum.TENCENT_CLOUD.name())
90 - && (null == configJsonNode.get("appId") 90 + && (null == configJsonNode.get("appId")
91 || null == configJsonNode.get("secretId") 91 || null == configJsonNode.get("secretId")
92 || null == configJsonNode.get("secretKey"))) { 92 || null == configJsonNode.get("secretKey"))) {
93 isMatch = false; 93 isMatch = false;
94 } else if (platForm.equals(MessageProviderTypeEnum.ALI_CLOUD.name()) 94 } else if (platForm.equals(MessageProviderTypeEnum.ALI_CLOUD.name())
95 - && (null == configJsonNode.get("accessKeyId") 95 + && (null == configJsonNode.get("accessKeyId")
96 || null == configJsonNode.get("accessKeySecret"))) { 96 || null == configJsonNode.get("accessKeySecret"))) {
97 isMatch = false; 97 isMatch = false;
98 } 98 }
@@ -102,6 +102,11 @@ public class TkMessageServiceImpl implements TkMessageService { @@ -102,6 +102,11 @@ public class TkMessageServiceImpl implements TkMessageService {
102 || null == configJsonNode.get("clientSecret"))) { 102 || null == configJsonNode.get("clientSecret"))) {
103 isMatch = false; 103 isMatch = false;
104 } 104 }
  105 + else if (platForm.equals(MessageProviderTypeEnum.ALI_VOICE.name())
  106 + && (null == configJsonNode.get("accessKeyId")
  107 + || null == configJsonNode.get("accessKeySecret"))) {
  108 + isMatch = false;
  109 + }
105 if (!isMatch) { 110 if (!isMatch) {
106 throw new TkDataValidationException(ErrorMessage.SMS_CONFIG_ERROR.getMessage()); 111 throw new TkDataValidationException(ErrorMessage.SMS_CONFIG_ERROR.getMessage());
107 } 112 }
@@ -113,16 +118,16 @@ public class TkMessageServiceImpl implements TkMessageService { @@ -113,16 +118,16 @@ public class TkMessageServiceImpl implements TkMessageService {
113 keyList.add(messageConfig.getTenantId()); 118 keyList.add(messageConfig.getTenantId());
114 } 119 }
115 MessageProviderConfiguration smsProviderConfiguration = 120 MessageProviderConfiguration smsProviderConfiguration =
116 - JacksonUtil.convertValue(configObjectNode, MessageProviderConfiguration.class); 121 + JacksonUtil.convertValue(configObjectNode, MessageProviderConfiguration.class);
117 if (null != smsProviderConfiguration) { 122 if (null != smsProviderConfiguration) {
118 MessageSender smsSender = tkDefaultSmsSenderFactory.createSmsSender(smsProviderConfiguration 123 MessageSender smsSender = tkDefaultSmsSenderFactory.createSmsSender(smsProviderConfiguration
119 ,keyList); 124 ,keyList);
120 String result = 125 String result =
121 - smsSender.sendSms(  
122 - phoneNumbers,  
123 - messageTemplate.getTemplateCode(),  
124 - templateParam,  
125 - messageTemplate.getSignName()); 126 + smsSender.sendSms(
  127 + phoneNumbers,
  128 + messageTemplate.getTemplateCode(),
  129 + templateParam,
  130 + messageTemplate.getSignName());
126 // 记录短信日志 131 // 记录短信日志
127 String status = ResponseCodeEnum.SUCCESS.name(); 132 String status = ResponseCodeEnum.SUCCESS.name();
128 String remark = smsReqDTO.getRemark() == null ? "" : smsReqDTO.getRemark(); 133 String remark = smsReqDTO.getRemark() == null ? "" : smsReqDTO.getRemark();
@@ -151,34 +156,34 @@ public class TkMessageServiceImpl implements TkMessageService { @@ -151,34 +156,34 @@ public class TkMessageServiceImpl implements TkMessageService {
151 public boolean sendSmsCode(String phoneNumber, MsgTemplatePurposeEnum purpose) { 156 public boolean sendSmsCode(String phoneNumber, MsgTemplatePurposeEnum purpose) {
152 // 检查手机号码是否存在系统,以免乱发消息 157 // 检查手机号码是否存在系统,以免乱发消息
153 List<SysUserEntity> users = 158 List<SysUserEntity> users =
154 - userMapper.selectList(  
155 - new QueryWrapper<SysUserEntity>()  
156 - .lambda()  
157 - .eq(SysUserEntity::getPhoneNumber, phoneNumber)); 159 + userMapper.selectList(
  160 + new QueryWrapper<SysUserEntity>()
  161 + .lambda()
  162 + .eq(SysUserEntity::getPhoneNumber, phoneNumber));
158 if (users.isEmpty()) { 163 if (users.isEmpty()) {
159 throw new TkDataValidationException("电话号码未在系统注册,请联系你的管理员"); 164 throw new TkDataValidationException("电话号码未在系统注册,请联系你的管理员");
160 } 165 }
161 if (users.get(0).getAccountExpireTime() != null 166 if (users.get(0).getAccountExpireTime() != null
162 - && users.get(0).getAccountExpireTime().isBefore(LocalDateTime.now())) { 167 + && users.get(0).getAccountExpireTime().isBefore(LocalDateTime.now())) {
163 throw new TkDataValidationException(ErrorMessage.ACCOUNT_HAS_EXPIRED.getMessage()); 168 throw new TkDataValidationException(ErrorMessage.ACCOUNT_HAS_EXPIRED.getMessage());
164 } 169 }
165 // 获取是否有验证码存在,防止发送数量过多 170 // 获取是否有验证码存在,防止发送数量过多
166 String key = 171 String key =
167 - purpose.name()  
168 - + DEFAULT_DELIMITER  
169 - + MessageTypeEnum.PHONE_MESSAGE.name()  
170 - + DEFAULT_DELIMITER  
171 - + phoneNumber; 172 + purpose.name()
  173 + + DEFAULT_DELIMITER
  174 + + MessageTypeEnum.PHONE_MESSAGE.name()
  175 + + DEFAULT_DELIMITER
  176 + + phoneNumber;
172 boolean canSend = 177 boolean canSend =
173 - cacheUtils  
174 - .get(MOBILE_LOGIN_SMS_CODE, key)  
175 - .map(  
176 - o -> {  
177 - CodeTTL codeTTL = (CodeTTL) o;  
178 - return System.currentTimeMillis() - codeTTL.getSendTs()  
179 - >= 60 * 1000; // 大于1分钟才允许下次再发送短信  
180 - })  
181 - .orElse(true); 178 + cacheUtils
  179 + .get(MOBILE_LOGIN_SMS_CODE, key)
  180 + .map(
  181 + o -> {
  182 + CodeTTL codeTTL = (CodeTTL) o;
  183 + return System.currentTimeMillis() - codeTTL.getSendTs()
  184 + >= 60 * 1000; // 大于1分钟才允许下次再发送短信
  185 + })
  186 + .orElse(true);
182 if (!canSend) { 187 if (!canSend) {
183 throw new TkDataValidationException(ErrorMessage.MESSAGE_SEND_TOO_FAST.getMessage()); 188 throw new TkDataValidationException(ErrorMessage.MESSAGE_SEND_TOO_FAST.getMessage());
184 } 189 }
@@ -186,15 +191,15 @@ public class TkMessageServiceImpl implements TkMessageService { @@ -186,15 +191,15 @@ public class TkMessageServiceImpl implements TkMessageService {
186 /** 消息模板是否可用 */ 191 /** 消息模板是否可用 */
187 SysUserEntity entity = users.get(0); 192 SysUserEntity entity = users.get(0);
188 List<TkMessageTemplateEntity> messageTemplates = 193 List<TkMessageTemplateEntity> messageTemplates =
189 - messageTemplateMapper.selectList(  
190 - new QueryWrapper<TkMessageTemplateEntity>()  
191 - .lambda()  
192 - .eq(  
193 - TkMessageTemplateEntity::getTenantId,  
194 - entity.getLevel() == 3 ? entity.getTenantId() : EntityId.NULL_UUID.toString())  
195 - .eq(TkMessageTemplateEntity::getStatus, 1)  
196 - .eq(TkMessageTemplateEntity::getTemplatePurpose, purpose.name())  
197 - .eq(TkMessageTemplateEntity::getMessageType, MessageTypeEnum.PHONE_MESSAGE.name())); 194 + messageTemplateMapper.selectList(
  195 + new QueryWrapper<TkMessageTemplateEntity>()
  196 + .lambda()
  197 + .eq(
  198 + TkMessageTemplateEntity::getTenantId,
  199 + entity.getLevel() == 3 ? entity.getTenantId() : EntityId.NULL_UUID.toString())
  200 + .eq(TkMessageTemplateEntity::getStatus, 1)
  201 + .eq(TkMessageTemplateEntity::getTemplatePurpose, purpose.name())
  202 + .eq(TkMessageTemplateEntity::getMessageType, MessageTypeEnum.PHONE_MESSAGE.name()));
198 if (messageTemplates.isEmpty()) { 203 if (messageTemplates.isEmpty()) {
199 throw new TkDataValidationException(ErrorMessage.MESSAGE_TEMPLATE_NOT_EXISTS.getMessage()); 204 throw new TkDataValidationException(ErrorMessage.MESSAGE_TEMPLATE_NOT_EXISTS.getMessage());
200 } 205 }
@@ -153,6 +153,14 @@ public class TkNoticeServiceImpl implements TkNoticeService { @@ -153,6 +153,14 @@ public class TkNoticeServiceImpl implements TkNoticeService {
153 organization, 153 organization,
154 contacts); 154 contacts);
155 } 155 }
  156 + if (messageCode.contains(MessageTypeEnum.VOICE_MESSAGE.name())
  157 + && templatesMap.containsKey(MessageTypeEnum.VOICE_MESSAGE.name())) {
  158 + aLiVoice4Alarm(
  159 + alarmInfo,
  160 + templatesMap.get(MessageTypeEnum.VOICE_MESSAGE.name()),
  161 + organization,
  162 + contacts);
  163 + }
156 }); 164 });
157 } 165 }
158 166
@@ -289,6 +297,35 @@ public class TkNoticeServiceImpl implements TkNoticeService { @@ -289,6 +297,35 @@ public class TkNoticeServiceImpl implements TkNoticeService {
289 }); 297 });
290 } 298 }
291 299
  300 + /**
  301 + * 电话通知设备告警信息
  302 + *
  303 + * @param alarmInfo 告警信息
  304 + * @param templateId 告警模板主键
  305 + * @param organization 设备所属组织
  306 + * @param contacts 设备告警联系人
  307 + */
  308 + private void aLiVoice4Alarm(
  309 + AlarmInfoDTO alarmInfo,
  310 + String templateId,
  311 + TkOrganizationEntity organization,
  312 + List<TkAlarmContactEntity> contacts) {
  313 + // TODO 电话通知
  314 + SmsReqDTO info = new SmsReqDTO();
  315 + info.setId(templateId);
  316 + info.setParams(setAliAlarmParams(alarmInfo, organization));
  317 + info.setTemplatePurpose(MsgTemplatePurposeEnum.FOR_ALARM_NOTICE.name());
  318 + contacts.stream()
  319 + .parallel()
  320 + .forEach(
  321 + item -> {
  322 + if (!item.getPhone().isEmpty()) {
  323 + info.setPhoneNumbers(item.getPhone());
  324 + smsService.sendSms(info);
  325 + }
  326 + });
  327 + }
  328 +
292 private LinkedHashMap<String, Object> setAliAlarmParams( 329 private LinkedHashMap<String, Object> setAliAlarmParams(
293 AlarmInfoDTO alarmInfo, TkOrganizationEntity organization) { 330 AlarmInfoDTO alarmInfo, TkOrganizationEntity organization) {
294 LinkedHashMap<String, Object> params = new LinkedHashMap<>(); 331 LinkedHashMap<String, Object> params = new LinkedHashMap<>();
@@ -35,4 +35,5 @@ public interface TkAlarmMapper extends BaseMapper<TkAlarmEntity> { @@ -35,4 +35,5 @@ public interface TkAlarmMapper extends BaseMapper<TkAlarmEntity> {
35 35
36 List<SysDictEntity> alarmType(@Param("tenantId") UUID tenantId); 36 List<SysDictEntity> alarmType(@Param("tenantId") UUID tenantId);
37 List<AggregationDTO> countAlarms(@Param("queryMap") Map<String, Object> queryMap); 37 List<AggregationDTO> countAlarms(@Param("queryMap") Map<String, Object> queryMap);
  38 + void deleteByDeviceId(@Param("tenantId") String tenantId, @Param("tbDeviceId") String tbDeviceId);
38 } 39 }
@@ -53,4 +53,6 @@ public interface TkAlarmInfoService { @@ -53,4 +53,6 @@ public interface TkAlarmInfoService {
53 * @return 53 * @return
54 */ 54 */
55 List<SysDictDTO> alarmType(TenantId tenantId); 55 List<SysDictDTO> alarmType(TenantId tenantId);
  56 +
  57 + void deleteByDeviceId(String tenantId, String tbDeviceId);
56 } 58 }
@@ -119,4 +119,14 @@ @@ -119,4 +119,14 @@
119 </where> 119 </where>
120 GROUP BY status; 120 GROUP BY status;
121 </select> 121 </select>
  122 +
  123 + <delete id="deleteByDeviceId">
  124 + delete from alarm where 1=1
  125 + <if test="tenantId !=null">
  126 + AND tenant_id= #{tenantId}::uuid
  127 + </if>
  128 + <if test="tbDeviceId !=null">
  129 + AND originator_id= #{tbDeviceId}::uuid
  130 + </if>
  131 + </delete>
122 </mapper> 132 </mapper>