feat(device): 新增阿里云语音通知功能并扩展设备查询接口

- 集成阿里云语音服务,实现TTS语音拨号功能
- 添加异步报警拨号机制,支持SOS紧急呼叫
- 新增按设备名称查询设备的接口和SQL
- 扩展设备类型统计和批量查询功能
- 添加租户ID字段支持多租户设备管理
- 配置阿里云语音API依赖和客户端单例模式
This commit is contained in:
2026-01-30 16:03:13 +08:00
parent b280038502
commit cb87871982
7 changed files with 210 additions and 1 deletions

View File

@ -0,0 +1,87 @@
package com.fuyuanshen.web.util;
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.aliyun.teautil.models.RuntimeOptions;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Map;
@Slf4j
@Component
public class AliyunVoiceUtil {
private static final ObjectMapper objectMapper = new ObjectMapper();
@Value("${alibaba.tts.akId}")
private String akId;
@Value("${alibaba.tts.akSecret}")
private String akSecret;
// @Value("${alibaba.tts.calledShowNumber:}")
private String calledShowNumber;
// ========== 核心:单例客户端(类似 OkHttpClient ==========
private volatile Client client;
/**
* 获取客户端(双重检查锁实现单例)
* 只有在第一次调用时才会根据配置实例化,后续直接返回复用
*/
private Client getClient() throws Exception {
if (client == null) {
synchronized (this) {
if (client == null) {
log.info("[AliyunVoice] 正在初始化阿里云语音客户端...");
Config config = new Config()
.setAccessKeyId(akId)
.setAccessKeySecret(akSecret)
.setEndpoint("dyvmsapi.aliyuncs.com");
this.client = new Client(config);
}
}
}
return client;
}
/**
* 同步发送方法:由异步架构调用
*/
public String sendTtsSync(String phone, String templateCode, Map<String, String> params) {
try {
// 1. 获取(或初始化)单例客户端
Client voiceClient = getClient();
SingleCallByTtsRequest request = new SingleCallByTtsRequest()
.setCalledNumber(phone)
.setTtsCode(templateCode)
.setTtsParam(objectMapper.writeValueAsString(params));
if (StringUtils.hasText(calledShowNumber)) {
request.setCalledShowNumber(calledShowNumber);
}
// 生产级超时配置
RuntimeOptions runtime = new RuntimeOptions();
runtime.setConnectTimeout(5000);
runtime.setReadTimeout(10000);
SingleCallByTtsResponse response = voiceClient.singleCallByTtsWithOptions(request, runtime);
if ("OK".equalsIgnoreCase(response.getBody().getCode())) {
return response.getBody().getCallId();
} else {
log.error("[AliyunVoice] 拨号失败: {}", response.getBody().getMessage());
}
} catch (Exception e) {
log.error("[AliyunVoice] 接口异常", e);
}
return null;
}
}