diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java index a7b1f8af..6746d867 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java @@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; +import java.util.Map; /** * HBY670设备控制类 @@ -144,4 +145,26 @@ public class AppDeviceXinghanController extends BaseController { return R.ok(); } + @PostMapping(value = "/GetDeviceByName") + @Operation(summary = "通过蓝牙名/设备名称查询设备") + public R GetDeviceByName(@RequestBody DeviceForm deviceForm) { + Object device = appDeviceService.GetDeviceByName(deviceForm); + return R.ok(device); + } + + + @PostMapping(value = "/getEquipCountByType") + @Operation(summary = "查询某个类型下的设备总数量") + public R getEquipCountByType(@RequestBody DeviceForm deviceForm) { + Object device = appDeviceService.getEquipCountByType(deviceForm); + return R.ok(device); + } + + @PostMapping(value = "/getEquipAllByType") + @Operation(summary = "查询某个类型下的设备") + public R>> getEquipAllByType(@RequestBody DeviceForm deviceForm){ + List> list=appDeviceService.getEquipAllByType(deviceForm); + return R.ok(list); + } + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java index d599f4cc..5a4ef3ff 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java @@ -57,9 +57,11 @@ import com.fuyuanshen.web.domain.Dto.DeviceDebugLogoUploadDto; import com.fuyuanshen.web.domain.Dto.DeviceXinghanInstructDto; import com.fuyuanshen.web.domain.vo.DeviceXinghanDetailVo; import com.fuyuanshen.web.enums.AlarmTypeEnum; +import com.fuyuanshen.web.util.AliyunVoiceUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -93,6 +95,7 @@ public class DeviceXinghanBizService { private final DeviceAssignmentsService deviceAssignmentsService; @Autowired private ObjectMapper objectMapper; + private final AliyunVoiceUtil voiceUtil; /** * 所有档位的描述表 @@ -135,7 +138,6 @@ public class DeviceXinghanBizService { public void upSOSGradeSettings(DeviceXinghanInstructDto dto) { if(dto.getIsBluetooth()){ long deviceId = dto.getDeviceId(); - // 1. 使用Optional简化空值检查,使代码更简洁 Device device = Optional.ofNullable(deviceMapper.selectById(deviceId)) .orElseThrow(() -> new ServiceException("设备不存在")); @@ -147,6 +149,24 @@ public class DeviceXinghanBizService { } } + /** + * 触发异步报警 + * Spring 会自动调用 AsyncConfig.getAsyncExecutor() 来执行此方法 + */ + @Async + public void executeSosCall(String phone) { + log.info("[SOS业务] 准备发起语音拨号 -> 目标: {}", phone); + Map params = Map.of("device", "670"); + String callId = voiceUtil.sendTtsSync(phone, "TTS_328730104", params); + + if (callId != null) { + log.info("[SOS业务] 拨号指令下发成功, callId: {}", callId); + // 这里可以记录拨打日志到数据库 + } else { + log.error("[SOS业务] 拨号指令下发失败,请检查配置或余额"); + } + } + /** * 设置强制报警 */ @@ -768,4 +788,23 @@ public class DeviceXinghanBizService { return uuidStr.replaceAll("-", ""); } + public Map GetDeviceByName(DeviceForm deviceForm){ + List> list= deviceMapper.GetDeviceByName(deviceForm); + Map device=null; + if(list!=null && list.size()>0){ + device=list.get(0); + } + return device; + } + + public int getEquipCountByType(DeviceForm form){ + var res=deviceMapper.getEquipCountByType(form); + return res; + } + + public List> getEquipAllByType(DeviceForm deviceForm){ + List> list= deviceMapper.getEquipAllByType(deviceForm); + return list; + } + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/util/AliyunVoiceUtil.java b/fys-admin/src/main/java/com/fuyuanshen/web/util/AliyunVoiceUtil.java new file mode 100644 index 00000000..1aac0670 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/web/util/AliyunVoiceUtil.java @@ -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 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; + } +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/pom.xml b/fys-modules/fys-equipment/pom.xml index 87edeb66..d4e01a3a 100644 --- a/fys-modules/fys-equipment/pom.xml +++ b/fys-modules/fys-equipment/pom.xml @@ -140,6 +140,18 @@ 3.3.1 + + + com.aliyun + dyvmsapi20170525 + 4.2.0 + + + com.aliyun + tea-openapi + 0.3.2 + + com.alibaba.fastjson2 diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java index def13d17..50bcb58c 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java @@ -54,6 +54,9 @@ public class DeviceForm { @Schema(title = "备注") private String remark; + @Schema(title = "商户号") + private Long tenant_id; + // 设备类型相关字段 @Schema(title = "设备类型名称") diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java index 18fc9a26..465b7b28 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.dto.InstructionRecordDto; +import com.fuyuanshen.equipment.domain.form.DeviceForm; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.*; import org.apache.ibatis.annotations.Mapper; @@ -148,4 +149,10 @@ public interface DeviceMapper extends BaseMapper { */ int countByDeviceTypeId(@Param("deviceTypeId") Long deviceTypeId); + List> GetDeviceByName(DeviceForm deviceForm); + + int getEquipCountByType(DeviceForm deviceForm); + + List> getEquipAllByType(DeviceForm deviceForm); + } \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml index cb9b26f3..8e10347d 100644 --- a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml +++ b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml @@ -264,6 +264,44 @@ + + + + + +