11 Commits

Author SHA1 Message Date
9d84265f57 Merge remote-tracking branch 'origin/6170' into 6170 2026-03-02 16:38:01 +08:00
fa5dfab939 2.4G设备上报技术方案 2026-03-02 16:37:50 +08:00
5fb71dd092 提交代码5 2026-03-02 15:35:19 +08:00
1ce87aaec5 Merge branch '6170' of http://47.107.152.87:3000/dyf/fys-Multi-tenant into 6170 2026-03-02 14:31:46 +08:00
4f3e7b0ed0 regis 2026-03-02 14:31:40 +08:00
b75b7ef431 提交代码4 2026-03-02 13:55:21 +08:00
c9cad751f0 提交代码3 2026-03-02 13:45:30 +08:00
34841c8704 提交代码2 2026-03-02 11:17:46 +08:00
20ac6b0baa bug修改4 2026-02-27 18:34:21 +08:00
4d5292cebc bug修改3 2026-02-27 18:31:03 +08:00
7a35baa8f0 bug修改2 2026-02-27 17:42:23 +08:00
28 changed files with 832 additions and 449 deletions

View File

@ -1,17 +1,16 @@
package com.fuyuanshen.app.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import com.fuyuanshen.app.domain.bo.AppBusinessFileBo;
import com.fuyuanshen.app.domain.dto.AppAudioFileDto;
import com.fuyuanshen.app.domain.dto.AppFileDto;
import com.fuyuanshen.app.domain.dto.AppFileRenameDto;
import com.fuyuanshen.app.domain.dto.TextToSpeechRequest;
import com.fuyuanshen.app.domain.vo.AppFileVo;
import com.fuyuanshen.app.service.AudioProcessService;
import com.fuyuanshen.app.service.VideoProcessService;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.equipment.domain.vo.AppFileVo;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

View File

@ -3,15 +3,13 @@ package com.fuyuanshen.app.controller.device.bjq;
import com.fuyuanshen.app.domain.vo.AppDeviceHBY100JDetailVo;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.web.controller.device.domain.dto.*;
import com.fuyuanshen.web.service.device.DeviceHBY100JBizService;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* HBY100J设备控制类
*/
@ -66,20 +64,6 @@ public class AppDeviceHBY100JController extends BaseController {
}
@Data
public static class HBY100JVoiceBroadcastDto {
/**
* 设备ID
*/
Long deviceId;
/**
* 0 关闭, 1开启
*/
private Integer voiceBroadcast;
}
/**
* 爆闪模式
*/
@ -117,100 +101,4 @@ public class AppDeviceHBY100JController extends BaseController {
deviceHBY100JBizService.updateVolume(params);
return R.ok();
}
@Data
public static class HBY100JUpdateVoiceDto {
private Long id;
}
@Data
public static class HBY100JForceAlarmActivationDto {
/**
* 设备ID
*/
List<Long> deviceIds;
/**
* 0 关闭, 1开启
*/
private Integer voiceStrobeAlarm;
/**
* 0 公安,1消防,2应急,3交警4 市政5 铁路6 医疗7语音
*/
private Integer mode;
}
@Data
public static class HBY100JUpdateVolumeDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* "volume": 1-100(app端可根据需求把40作为低音量, 70作为中音量100作为高音量)
*/
private Integer volume;
}
@Data
public static class HBY100JStrobeFrequencyDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* "frequency": 1-12
*/
private Integer frequency;
}
@Data
public static class HBY100JLightAdjustmentDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* 亮度值0-100
*/
private Integer brightness;
// /**
// * 红色LED亮度值0-100
// */
// private Integer red;
//
// /**
// * 蓝色LED亮度值0-100
// */
// private Integer blue;
//
// /**
// * 黄色LED亮度值0-100
// */
// private Integer yellow;
}
@Data
public static class HBY100JStrobeModeDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* 0 关闭 1 开启
*/
private Integer enable;
/**
* 0 红色爆闪1 蓝色爆闪2 黄色爆闪3红色顺时针旋转爆闪4黄色顺时针旋转爆闪5红蓝顺时针旋转爆闪6 红蓝交替爆闪
*/
private Integer mode;
}
}

View File

@ -1,16 +1,17 @@
package com.fuyuanshen.app.service;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fuyuanshen.app.domain.AppBusinessFile;
import com.fuyuanshen.app.domain.bo.AppBusinessFileBo;
import com.fuyuanshen.app.domain.dto.AppAudioFileDto;
import com.fuyuanshen.app.domain.dto.AppFileRenameDto;
import com.fuyuanshen.app.domain.vo.AppFileVo;
import com.fuyuanshen.app.http.HttpTtsClient;
import com.fuyuanshen.app.mapper.AppBusinessFileMapper;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.equipment.domain.AppBusinessFile;
import com.fuyuanshen.equipment.domain.bo.AppBusinessFileBo;
import com.fuyuanshen.equipment.domain.vo.AppFileVo;
import com.fuyuanshen.equipment.mapper.AppBusinessFileMapper;
import com.fuyuanshen.equipment.service.IAppBusinessFileService;
import com.fuyuanshen.equipment.utils.AlibabaTTSUtil;
import com.fuyuanshen.equipment.utils.AudioProcessUtil;
import com.fuyuanshen.equipment.utils.FileHashUtil;

View File

@ -1,68 +1,68 @@
package com.fuyuanshen.global.mqtt.config;
import cn.hutool.core.lang.UUID;
import com.fuyuanshen.global.mqtt.receiver.NewReceiverMessageHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@Configuration
@Slf4j
public class NewMqttInboundConfiguration {
@Autowired
private MqttPropertiesConfig mqttPropertiesConfig;
@Autowired
private MqttPahoClientFactory mqttPahoClientFactory;
@Autowired
private NewReceiverMessageHandler receiverMessageHandler2;
//消息通道
@Bean
public MessageChannel messageInboundChannel2(){
return new DirectChannel();
}
/**
* 配置入站适配器
* 作用: 设置订阅主题,以及指定消息的通道 等相关属性
* */
@Bean
public MessageProducer messageProducer2(){
// 生成一个不重复的随机数
String clientId = mqttPropertiesConfig.getSubClientId() + "_" + UUID.fastUUID();
String subTopic = mqttPropertiesConfig.getSubTopic2();
log.info("订阅主题:{}", subTopic);
MqttPahoMessageDrivenChannelAdapter mqttPahoMessageDrivenChannelAdapter = new MqttPahoMessageDrivenChannelAdapter(
mqttPropertiesConfig.getUrl(),
clientId,
mqttPahoClientFactory,
subTopic.split(",")
);
mqttPahoMessageDrivenChannelAdapter.setQos(1);
mqttPahoMessageDrivenChannelAdapter.setConverter(new DefaultPahoMessageConverter());
mqttPahoMessageDrivenChannelAdapter.setOutputChannel(messageInboundChannel2());
return mqttPahoMessageDrivenChannelAdapter;
}
/** 指定处理消息来自哪个通道 */
@Bean
@ServiceActivator(inputChannel = "messageInboundChannel2")
public MessageHandler messageHandler2(){
return receiverMessageHandler2;
}
// @Bean
// @ServiceActivator(inputChannel = "messageInboundChannel") // 确保通道名称正确
// public MessageHandler deviceAlarmMessageHandler() {
// return new DeviceAlrmMessageHandler();
// }
}
//package com.fuyuanshen.global.mqtt.config;
//
//
//import cn.hutool.core.lang.UUID;
//import com.fuyuanshen.global.mqtt.receiver.NewReceiverMessageHandler;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.integration.annotation.ServiceActivator;
//import org.springframework.integration.channel.DirectChannel;
//import org.springframework.integration.core.MessageProducer;
//import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
//import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
//import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
//import org.springframework.messaging.MessageChannel;
//import org.springframework.messaging.MessageHandler;
//
//
//@Configuration
//@Slf4j
//public class NewMqttInboundConfiguration {
// @Autowired
// private MqttPropertiesConfig mqttPropertiesConfig;
// @Autowired
// private MqttPahoClientFactory mqttPahoClientFactory;
// @Autowired
// private NewReceiverMessageHandler receiverMessageHandler2;
// //消息通道
// @Bean
// public MessageChannel messageInboundChannel2(){
// return new DirectChannel();
// }
//
// /**
// * 配置入站适配器
// * 作用: 设置订阅主题,以及指定消息的通道 等相关属性
// * */
// @Bean
// public MessageProducer messageProducer2(){
// // 生成一个不重复的随机数
// String clientId = mqttPropertiesConfig.getSubClientId() + "_" + UUID.fastUUID();
// String subTopic = mqttPropertiesConfig.getSubTopic2();
// log.info("订阅主题:{}", subTopic);
// MqttPahoMessageDrivenChannelAdapter mqttPahoMessageDrivenChannelAdapter = new MqttPahoMessageDrivenChannelAdapter(
// mqttPropertiesConfig.getUrl(),
// clientId,
// mqttPahoClientFactory,
// subTopic.split(",")
// );
// mqttPahoMessageDrivenChannelAdapter.setQos(1);
// mqttPahoMessageDrivenChannelAdapter.setConverter(new DefaultPahoMessageConverter());
// mqttPahoMessageDrivenChannelAdapter.setOutputChannel(messageInboundChannel2());
// return mqttPahoMessageDrivenChannelAdapter;
// }
// /** 指定处理消息来自哪个通道 */
// @Bean
// @ServiceActivator(inputChannel = "messageInboundChannel2")
// public MessageHandler messageHandler2(){
// return receiverMessageHandler2;
// }
//
// // @Bean
// // @ServiceActivator(inputChannel = "messageInboundChannel") // 确保通道名称正确
// // public MessageHandler deviceAlarmMessageHandler() {
// // return new DeviceAlrmMessageHandler();
// // }
//}

View File

@ -1,46 +1,46 @@
package com.fuyuanshen.global.mqtt.config;
import cn.hutool.core.lang.UUID;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@Configuration
@Slf4j
public class NewMqttOutboundConfiguration {
@Autowired
private MqttPropertiesConfig mqttPropertiesConfig;
@Autowired
private MqttPahoClientFactory mqttPahoClientFactory;
// 消息通道
@Bean
public MessageChannel mqttOutboundChannel2(){
return new DirectChannel();
}
/** 配置出站消息处理器 */
@Bean
@ServiceActivator(inputChannel = "mqttOutboundChannel2") // 指定处理器针对哪个通道的消息进行处理
public MessageHandler mqttOutboundMessageHandler2(){
String clientId = mqttPropertiesConfig.getPubClientId() + "_" + UUID.fastUUID();
MqttPahoMessageHandler mqttPahoMessageHandler = new MqttPahoMessageHandler(
mqttPropertiesConfig.getUrl(),
clientId,
mqttPahoClientFactory
);
mqttPahoMessageHandler.setDefaultQos(1);
mqttPahoMessageHandler.setDefaultTopic(mqttPropertiesConfig.getPubTopic2());
mqttPahoMessageHandler.setAsync(true);
return mqttPahoMessageHandler;
}
}
//package com.fuyuanshen.global.mqtt.config;
//
//import cn.hutool.core.lang.UUID;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.integration.annotation.ServiceActivator;
//import org.springframework.integration.channel.DirectChannel;
//import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
//import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
//import org.springframework.messaging.MessageChannel;
//import org.springframework.messaging.MessageHandler;
//
//@Configuration
//@Slf4j
//public class NewMqttOutboundConfiguration {
// @Autowired
// private MqttPropertiesConfig mqttPropertiesConfig;
// @Autowired
// private MqttPahoClientFactory mqttPahoClientFactory;
//
// // 消息通道
// @Bean
// public MessageChannel mqttOutboundChannel2(){
// return new DirectChannel();
// }
//
//
// /** 配置出站消息处理器 */
// @Bean
// @ServiceActivator(inputChannel = "mqttOutboundChannel2") // 指定处理器针对哪个通道的消息进行处理
// public MessageHandler mqttOutboundMessageHandler2(){
// String clientId = mqttPropertiesConfig.getPubClientId() + "_" + UUID.fastUUID();
// MqttPahoMessageHandler mqttPahoMessageHandler = new MqttPahoMessageHandler(
// mqttPropertiesConfig.getUrl(),
// clientId,
// mqttPahoClientFactory
// );
// mqttPahoMessageHandler.setDefaultQos(1);
// mqttPahoMessageHandler.setDefaultTopic(mqttPropertiesConfig.getPubTopic2());
// mqttPahoMessageHandler.setAsync(true);
// return mqttPahoMessageHandler;
// }
//
//}

View File

@ -0,0 +1,69 @@
package com.fuyuanshen.global.mqtt.config;
import cn.hutool.core.lang.UUID;
//import com.fuyuanshen.global.mqtt.receiver.NewReceiverMessageHandler;
import com.fuyuanshen.global.mqtt.receiver.RegisEquipReceiverMessageHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@Configuration
@Slf4j
public class RegisEquipMqttInboundConfiguration {
@Autowired
private MqttPropertiesConfig mqttPropertiesConfig;
@Autowired
private MqttPahoClientFactory mqttPahoClientFactory;
@Autowired
private RegisEquipReceiverMessageHandler receiverMessageHandler3;
//消息通道
@Bean
public MessageChannel messageInboundChannel3(){
return new DirectChannel();
}
/**
* 配置入站适配器
* 作用: 设置订阅主题,以及指定消息的通道 等相关属性
* */
@Bean
public MessageProducer messageProducer3(){
// 生成一个不重复的随机数
String clientId = mqttPropertiesConfig.getSubClientId() + "_" + UUID.fastUUID();
String subTopic = mqttPropertiesConfig.getSubTopic2();
log.info("订阅主题:{}", subTopic);
MqttPahoMessageDrivenChannelAdapter mqttPahoMessageDrivenChannelAdapter = new MqttPahoMessageDrivenChannelAdapter(
mqttPropertiesConfig.getUrl(),
clientId,
mqttPahoClientFactory,
subTopic.split(",")
);
mqttPahoMessageDrivenChannelAdapter.setQos(1);
mqttPahoMessageDrivenChannelAdapter.setConverter(new DefaultPahoMessageConverter());
mqttPahoMessageDrivenChannelAdapter.setOutputChannel(messageInboundChannel3());
return mqttPahoMessageDrivenChannelAdapter;
}
/** 指定处理消息来自哪个通道 */
@Bean
@ServiceActivator(inputChannel = "messageInboundChannel3")
public MessageHandler messageHandler3(){
return receiverMessageHandler3;
}
// @Bean
// @ServiceActivator(inputChannel = "messageInboundChannel") // 确保通道名称正确
// public MessageHandler deviceAlarmMessageHandler() {
// return new DeviceAlrmMessageHandler();
// }
}

View File

@ -0,0 +1,46 @@
package com.fuyuanshen.global.mqtt.config;
import cn.hutool.core.lang.UUID;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@Configuration
@Slf4j
public class RegisEquipMqttOutboundConfiguration {
@Autowired
private MqttPropertiesConfig mqttPropertiesConfig;
@Autowired
private MqttPahoClientFactory mqttPahoClientFactory;
// 消息通道
@Bean
public MessageChannel mqttOutboundChannel3(){
return new DirectChannel();
}
/** 配置出站消息处理器 */
@Bean
@ServiceActivator(inputChannel = "mqttOutboundChannel3") // 指定处理器针对哪个通道的消息进行处理
public MessageHandler mqttOutboundMessageHandler3(){
String clientId = mqttPropertiesConfig.getPubClientId() + "_" + UUID.fastUUID();
MqttPahoMessageHandler mqttPahoMessageHandler = new MqttPahoMessageHandler(
mqttPropertiesConfig.getUrl(),
clientId,
mqttPahoClientFactory
);
mqttPahoMessageHandler.setDefaultQos(1);
mqttPahoMessageHandler.setDefaultTopic(mqttPropertiesConfig.getPubTopic2());
mqttPahoMessageHandler.setAsync(true);
return mqttPahoMessageHandler;
}
}

View File

@ -1,125 +1,125 @@
package com.fuyuanshen.global.mqtt.receiver;
import cn.hutool.core.lang.Dict;
import com.baomidou.lock.LockTemplate;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.json.utils.JsonUtils;
import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleEngine;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.queue.MqttMessageQueueConstants;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
@Service
@Slf4j
public class NewReceiverMessageHandler implements MessageHandler {
@Autowired
private NewMqttRuleEngine newRuleEngine;
@Override
public void handleMessage(Message<?> message) throws MessagingException {
Object payload = message.getPayload();
MessageHeaders headers = message.getHeaders();
String receivedTopic = Objects.requireNonNull(headers.get("mqtt_receivedTopic")).toString();
String receivedQos = Objects.requireNonNull(headers.get("mqtt_receivedQos")).toString();
String timestamp = Objects.requireNonNull(headers.get("timestamp")).toString();
log.info("MQTT2 payload= {} \n receivedTopic = {} \n receivedQos = {} \n timestamp = {}",
payload, receivedTopic, receivedQos, timestamp);
Dict payloadDict = JsonUtils.parseMap(payload.toString());
if (receivedTopic == null || payloadDict == null) {
return;
}
String imei = payloadDict.getStr("imei");
String funcType = payloadDict.getStr("funcType");
// 执行业务逻辑
if(StringUtils.isNotBlank(imei)){
String queueKey = MqttMessageQueueConstants.MQTT_MESSAGE_QUEUE_KEY;
String dedupKey = MqttMessageQueueConstants.MQTT_MESSAGE_DEDUP_KEY;
RedisUtils.offerDeduplicated(queueKey,dedupKey,imei, Duration.ofSeconds(900));
//在线状态
String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ imei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ;
RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360));
}
String[] topicArr = receivedTopic.split("/");
NewMqttRuleContext context = new NewMqttRuleContext();
context.setCommandType(topicArr[2]+"_"+funcType);
context.setDeviceImei(imei);
context.setPayloadDict(payloadDict);
boolean ruleExecuted = newRuleEngine.executeRule(context);
if (!ruleExecuted) {
log.warn("未找到匹配的规则来处理命令类型: {}", topicArr[2] + " : " +funcType);
}
// final LockInfo lockInfo = lockTemplate.lock(GlobalConstants.GLOBAL_REDIS_KEY + lockKey + imei, 100L, 3000L, RedissonLockExecutor.class);
// if (null == lockInfo) {
// log.info("MQTT3业务处理中,请稍后再试:funcType=>{},imei=>{}",funcType,imei);
//package com.fuyuanshen.global.mqtt.receiver;
//
//import cn.hutool.core.lang.Dict;
//import com.baomidou.lock.LockTemplate;
//import com.fuyuanshen.common.core.constant.GlobalConstants;
//import com.fuyuanshen.common.core.utils.StringUtils;
//import com.fuyuanshen.common.json.utils.JsonUtils;
//import com.fuyuanshen.common.redis.utils.RedisUtils;
//import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
//import com.fuyuanshen.global.mqtt.base.NewMqttRuleEngine;
//import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
//import com.fuyuanshen.global.queue.MqttMessageQueueConstants;
//import lombok.extern.slf4j.Slf4j;
//import org.redisson.api.RLock;
//import org.redisson.api.RedissonClient;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.messaging.Message;
//import org.springframework.messaging.MessageHandler;
//import org.springframework.messaging.MessageHeaders;
//import org.springframework.messaging.MessagingException;
//import org.springframework.stereotype.Service;
//
//import java.time.Duration;
//import java.util.Objects;
//import java.util.concurrent.TimeUnit;
//
//import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
//
//@Service
//@Slf4j
//public class NewReceiverMessageHandler implements MessageHandler {
//
// @Autowired
// private NewMqttRuleEngine newRuleEngine;
//
// @Override
// public void handleMessage(Message<?> message) throws MessagingException {
//
// Object payload = message.getPayload();
// MessageHeaders headers = message.getHeaders();
// String receivedTopic = Objects.requireNonNull(headers.get("mqtt_receivedTopic")).toString();
// String receivedQos = Objects.requireNonNull(headers.get("mqtt_receivedQos")).toString();
// String timestamp = Objects.requireNonNull(headers.get("timestamp")).toString();
//
// log.info("MQTT2 payload= {} \n receivedTopic = {} \n receivedQos = {} \n timestamp = {}",
// payload, receivedTopic, receivedQos, timestamp);
//
// Dict payloadDict = JsonUtils.parseMap(payload.toString());
// if (receivedTopic == null || payloadDict == null) {
// return;
// }
//// 获取锁成功,处理业务
// try {
// if(StringUtils.isNotBlank(imei)){
// String queueKey = MqttMessageQueueConstants.MQTT_MESSAGE_QUEUE_KEY;
// String dedupKey = MqttMessageQueueConstants.MQTT_MESSAGE_DEDUP_KEY;
// RedisUtils.offerDeduplicated(queueKey,dedupKey,imei, Duration.ofSeconds(900));
// //在线状态
// String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ imei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ;
// RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360));
// }
//
// String[] topicArr = receivedTopic.split("/");
//
// NewMqttRuleContext context = new NewMqttRuleContext();
// context.setCommandType(topicArr[2]+"_"+funcType);
// context.setDeviceImei(imei);
// context.setPayloadDict(payloadDict);
//
// boolean ruleExecuted = newRuleEngine.executeRule(context);
//
// if (!ruleExecuted) {
// log.warn("未找到匹配的规则来处理命令类型: {}", topicArr[2] + " : " +funcType);
// }
// } finally {
// //释放锁
// lockTemplate.releaseLock(lockInfo);
// String imei = payloadDict.getStr("imei");
// String funcType = payloadDict.getStr("funcType");
// // 执行业务逻辑
// if(StringUtils.isNotBlank(imei)){
// String queueKey = MqttMessageQueueConstants.MQTT_MESSAGE_QUEUE_KEY;
// String dedupKey = MqttMessageQueueConstants.MQTT_MESSAGE_DEDUP_KEY;
// RedisUtils.offerDeduplicated(queueKey,dedupKey,imei, Duration.ofSeconds(900));
// //在线状态
// String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ imei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ;
// RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360));
// }
/* ===== 追加:根据报文内容识别格式并统一解析 ===== */
// int intType = MqttXinghanCommandType.computeVirtualCommandType(payloadDict);
// if (intType > 0) {
// MqttRuleContext newCtx = new MqttRuleContext();
// String commandType = "Light_"+intType;
// newCtx.setCommandType(commandType);
// newCtx.setDeviceImei(imei);
// newCtx.setPayloadDict(payloadDict);
//
// boolean ok = ruleEngine.executeRule(newCtx);
// if (!ok) {
// log.warn("新规则引擎未命中, imei={}", imei);
// }
// String[] topicArr = receivedTopic.split("/");
//
// NewMqttRuleContext context = new NewMqttRuleContext();
// context.setCommandType(topicArr[2]+"_"+funcType);
// context.setDeviceImei(imei);
// context.setPayloadDict(payloadDict);
//
// boolean ruleExecuted = newRuleEngine.executeRule(context);
//
// if (!ruleExecuted) {
// log.warn("未找到匹配的规则来处理命令类型: {}", topicArr[2] + " : " +funcType);
// }
}
}
//// final LockInfo lockInfo = lockTemplate.lock(GlobalConstants.GLOBAL_REDIS_KEY + lockKey + imei, 100L, 3000L, RedissonLockExecutor.class);
//// if (null == lockInfo) {
//// log.info("MQTT3业务处理中,请稍后再试:funcType=>{},imei=>{}",funcType,imei);
//// return;
//// }
////// 获取锁成功,处理业务
//// try {
//// if(StringUtils.isNotBlank(imei)){
//// String queueKey = MqttMessageQueueConstants.MQTT_MESSAGE_QUEUE_KEY;
//// String dedupKey = MqttMessageQueueConstants.MQTT_MESSAGE_DEDUP_KEY;
//// RedisUtils.offerDeduplicated(queueKey,dedupKey,imei, Duration.ofSeconds(900));
//// //在线状态
//// String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ imei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ;
//// RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360));
//// }
////
//// String[] topicArr = receivedTopic.split("/");
////
//// NewMqttRuleContext context = new NewMqttRuleContext();
//// context.setCommandType(topicArr[2]+"_"+funcType);
//// context.setDeviceImei(imei);
//// context.setPayloadDict(payloadDict);
////
//// boolean ruleExecuted = newRuleEngine.executeRule(context);
////
//// if (!ruleExecuted) {
//// log.warn("未找到匹配的规则来处理命令类型: {}", topicArr[2] + " : " +funcType);
//// }
//// } finally {
//// //释放锁
//// lockTemplate.releaseLock(lockInfo);
//// }
//
//
// /* ===== 追加:根据报文内容识别格式并统一解析 ===== */
//// int intType = MqttXinghanCommandType.computeVirtualCommandType(payloadDict);
//// if (intType > 0) {
//// MqttRuleContext newCtx = new MqttRuleContext();
//// String commandType = "Light_"+intType;
//// newCtx.setCommandType(commandType);
//// newCtx.setDeviceImei(imei);
//// newCtx.setPayloadDict(payloadDict);
////
//// boolean ok = ruleEngine.executeRule(newCtx);
//// if (!ok) {
//// log.warn("新规则引擎未命中, imei={}", imei);
//// }
//// }
// }
//}

View File

@ -0,0 +1,143 @@
package com.fuyuanshen.global.mqtt.receiver;
import cn.hutool.core.lang.Dict;
import cn.hutool.json.JSONObject;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.json.utils.JsonUtils;
import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.equipment.domain.Device;
import com.fuyuanshen.equipment.domain.DeviceType;
import com.fuyuanshen.equipment.domain.form.DeviceForm;
import com.fuyuanshen.equipment.domain.query.DeviceTypeQueryCriteria;
import com.fuyuanshen.equipment.mapper.DeviceMapper;
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
import com.fuyuanshen.equipment.service.DeviceService;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleEngine;
import com.fuyuanshen.global.mqtt.config.MqttGateway;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.queue.MqttMessageQueueConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.Objects;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
/**
* 注册设备消息接收处理
*/
@Service
@Slf4j
public class RegisEquipReceiverMessageHandler implements MessageHandler {
@Autowired
private NewMqttRuleEngine newRuleEngine;
@Autowired
private MqttGateway mqttGateway;
@Autowired
private DeviceMapper deviceMapper;
@Autowired
private DeviceService deviceService;
@Autowired
private DeviceTypeMapper deviceTypeMapper;
@Override
public void handleMessage(Message<?> message) throws MessagingException {
Object payload = message.getPayload();
MessageHeaders headers = message.getHeaders();
String receivedTopic = Objects.requireNonNull(headers.get("mqtt_receivedTopic")).toString();
// 只处理 regis/equip/# 主题的消息
if (!receivedTopic.startsWith("regis/equip/")) {
return;
}
// 从主题中提取设备ID
String[] topicParts = receivedTopic.split("/");
if (topicParts.length < 3) {
log.warn("Invalid topic format: {}", receivedTopic);
return;
}
String deviceTypeName = topicParts[2]; // HBY100-J
String receivedQos = Objects.requireNonNull(headers.get("mqtt_receivedQos")).toString();
String timestamp = Objects.requireNonNull(headers.get("timestamp")).toString();
log.info("MQTT3 payload= {} \n receivedTopic = {} \n receivedQos = {} \n timestamp = {}",
payload, receivedTopic, receivedQos, timestamp);
// 解析JSON payload获取imei和mac
Dict payloadDict = JsonUtils.parseMap(payload.toString());
if (payloadDict == null) {
log.warn("Failed to parse payload JSON");
return;
}
String imei = payloadDict.getStr("imei");
String mac = payloadDict.getStr("mac");
log.info("Extracted IMEI: {}, MAC: {}", imei, mac);
// 验证必要字段
if (StringUtils.isEmpty(imei) || StringUtils.isEmpty(mac)) {
log.warn("Missing required fields - IMEI: {}, MAC: {}", imei, mac);
return;
}
DeviceTypeQueryCriteria criteria = new DeviceTypeQueryCriteria();
criteria.setTypeName(deviceTypeName);
DeviceType deviceType = deviceTypeMapper.queryByName(criteria);
if (deviceType == null) {
log.warn("Device type not found for name: {}", deviceTypeName);
return;
}
Device device = deviceMapper.selectDeviceByImei(imei);
if (device != null) {
log.warn("Device already exists for IMEI: {}", imei);
return;
}
// 提取MAC地址后6位
String macSuffix = mac.replaceAll(":", "").substring(6); // 43:73:43:33:53:33 -> 335333
// 构建设备名称和蓝牙名称:设备类型+MAC后6位
String deviceName = deviceTypeName + "-" + macSuffix; // HBY100-335333
DeviceForm deviceForm = new DeviceForm();
deviceForm.setDeviceImei(imei);
deviceForm.setDeviceMac(mac);
deviceForm.setDeviceName(deviceName);
deviceForm.setBluetoothName(deviceName);
deviceForm.setDeviceType(deviceType.getId());
try {
deviceService.addDevice(deviceForm);
} catch (Exception e) {
throw new RuntimeException(e);
}
// 解析原始JSON数据
JSONObject originalData = new JSONObject();
originalData.put("code", 200);
// 发送到MQTT
String topic = "regis/" + imei;
mqttGateway.sendMsgToMqtt(topic, originalData.toString());
}
}

View File

@ -1,46 +1,46 @@
//package com.fuyuanshen.global.mqtt.rule.hby100j;
//
//import com.alibaba.fastjson2.JSONObject;
//import com.fuyuanshen.common.core.constant.GlobalConstants;
//import com.fuyuanshen.common.redis.utils.RedisUtils;
//import com.fuyuanshen.global.mqtt.base.NewMqttMessageRule;
//import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Component;
//
//import java.util.Map;
//
//import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
//
///**
// * 获取设备基础信息
// */
//@Slf4j
//@Component
//public class FuncType2BaseInfo implements NewMqttMessageRule {
//
// @Override
// public String getCommandType() {
// return "HBY100_2";
// }
//
// @Override
// public void execute(NewMqttRuleContext context) {
// log.info("开始处理强制声光报警开关,消息负载:{}", context.getPayloadDict());
//
// try {
// // 构建强制声光报警开关的Redis键
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
// context.getDeviceImei() + ":force_audio_visual_alarm_switch";
//
// Map<String, Object> payloadDict = context.getPayloadDict();
// if (payloadDict != null) {
// // 存储强制声光报警开关状态到Redis
// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
// }
// log.info("强制声光报警开关处理完成设备ID{}", context.getDeviceImei());
// } catch (Exception e) {
// log.error("处理强制声光报警开关失败", e);
// }
// }
//}
package com.fuyuanshen.global.mqtt.rule.hby100j;
import com.alibaba.fastjson2.JSONObject;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.global.mqtt.base.NewMqttMessageRule;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
/**
* 获取设备基础信息
*/
@Slf4j
@Component
public class FuncType2BaseInfo implements NewMqttMessageRule {
@Override
public String getCommandType() {
return "HBY100_2";
}
@Override
public void execute(NewMqttRuleContext context) {
log.info("开始处理强制声光报警开关,消息负载:{}", context.getPayloadDict());
try {
// 构建强制声光报警开关的Redis键
String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
context.getDeviceImei() + ":force_audio_visual_alarm_switch";
Map<String, Object> payloadDict = context.getPayloadDict();
if (payloadDict != null) {
// 存储强制声光报警开关状态到Redis
RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
}
log.info("强制声光报警开关处理完成设备ID{}", context.getDeviceImei());
} catch (Exception e) {
log.error("处理强制声光报警开关失败", e);
}
}
}

View File

@ -0,0 +1,106 @@
package com.fuyuanshen.web.controller.device.bjq;
import com.fuyuanshen.app.domain.vo.AppDeviceHBY100JDetailVo;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.web.controller.device.domain.dto.*;
import com.fuyuanshen.web.service.device.DeviceHBY100JBizService;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* HBY100J设备控制类
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/hby100j/device")
public class WebDeviceHBY100JController extends BaseController {
private final DeviceHBY100JBizService deviceHBY100JBizService;
/**
* 获取设备详细信息
*
* @param id 主键
*/
@GetMapping("/{id}")
public R<AppDeviceHBY100JDetailVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(deviceHBY100JBizService.getInfo(id));
}
/**
* 更新语音
*/
@PostMapping("/updateVoice")
public R<Void> updateVoice(@RequestBody HBY100JUpdateVoiceDto dto) {
deviceHBY100JBizService.updateVoice(dto);
return R.ok();
}
/**
* 强制报警
*
*/
@PostMapping("/forceAlarmActivation")
public R<Void> forceAlarmActivation(@RequestBody HBY100JForceAlarmActivationDto bo) {
deviceHBY100JBizService.forceAlarmActivation(bo);
return R.ok();
}
/**
* 语音播报
*
*/
@PostMapping("/voiceBroadcast")
public R<Void> voiceBroadcast(@RequestBody HBY100JVoiceBroadcastDto params) {
deviceHBY100JBizService.voiceBroadcast(params);
return R.ok();
}
/**
* 爆闪模式
*/
@PostMapping("/strobeMode")
public R<Void> strobeMode(@RequestBody HBY100JStrobeModeDto params) {
deviceHBY100JBizService.strobeMode(params);
return R.ok();
}
/**
* 灯光调节
*/
@PostMapping("/lightAdjustment")
public R<Void> lightAdjustment(@RequestBody HBY100JLightAdjustmentDto params) {
deviceHBY100JBizService.lightAdjustment(params);
return R.ok();
}
/**
* 爆闪频率
*/
@PostMapping("/strobeFrequency")
public R<Void> strobeFrequency(@RequestBody HBY100JStrobeFrequencyDto params) {
deviceHBY100JBizService.strobeFrequency(params);
return R.ok();
}
/**
* 修改音量
*/
@PostMapping("/updateVolume")
public R<Void> updateVolume(@RequestBody HBY100JUpdateVolumeDto params) {
deviceHBY100JBizService.updateVolume(params);
return R.ok();
}
}

View File

@ -0,0 +1,23 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
import java.util.List;
@Data
public class HBY100JForceAlarmActivationDto {
/**
* 设备ID
*/
List<Long> deviceIds;
/**
* 0 关闭, 1开启
*/
private Integer voiceStrobeAlarm;
/**
* 0 公安,1消防,2应急,3交警4 市政5 铁路6 医疗7语音
*/
private Integer mode;
}

View File

@ -0,0 +1,31 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JLightAdjustmentDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* 亮度值0-100
*/
private Integer brightness;
// /**
// * 红色LED亮度值0-100
// */
// private Integer red;
//
// /**
// * 蓝色LED亮度值0-100
// */
// private Integer blue;
//
// /**
// * 黄色LED亮度值0-100
// */
// private Integer yellow;
}

View File

@ -0,0 +1,16 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JStrobeFrequencyDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* "frequency": 1-12
*/
private Integer frequency;
}

View File

@ -0,0 +1,21 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JStrobeModeDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* 0 关闭 1 开启
*/
private Integer enable;
/**
* 0 红色爆闪1 蓝色爆闪2 黄色爆闪3红色顺时针旋转爆闪4黄色顺时针旋转爆闪5红蓝顺时针旋转爆闪6 红蓝交替爆闪
*/
private Integer mode;
}

View File

@ -0,0 +1,10 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JUpdateVoiceDto {
private Long id;
}

View File

@ -0,0 +1,16 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JUpdateVolumeDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* "volume": 1-100(app端可根据需求把40作为低音量, 70作为中音量100作为高音量)
*/
private Integer volume;
}

View File

@ -0,0 +1,17 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JVoiceBroadcastDto {
/**
* 设备ID
*/
Long deviceId;
/**
* 0 关闭, 1开启
*/
private Integer voiceBroadcast;
}

View File

@ -86,7 +86,7 @@ public class DeviceBizService {
List<AppDeviceVo> records = result.getRecords();
if (records != null && !records.isEmpty()) {
records.forEach(item -> {
if (item.getCommunicationMode() != null && item.getCommunicationMode() == 0) {
if (item.getCommunicationMode() != null && (item.getCommunicationMode() == 0 || item.getCommunicationMode() == 2)) {
// 设备在线状态
String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX);

View File

@ -1,63 +1,43 @@
package com.fuyuanshen.web.service.device;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fuyuanshen.app.controller.device.bjq.AppDeviceHBY100JController;
import com.fuyuanshen.app.domain.AppBusinessFile;
import com.fuyuanshen.app.domain.AppPersonnelInfo;
import com.fuyuanshen.app.domain.AppPersonnelInfoRecords;
import com.fuyuanshen.app.domain.bo.AppBusinessFileBo;
import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo;
import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto;
import com.fuyuanshen.app.domain.dto.DeviceInstructDto;
import com.fuyuanshen.app.domain.vo.AppBusinessFileVo;
import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo;
import com.fuyuanshen.app.domain.vo.AppDeviceHBY100JDetailVo;
import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo;
import com.fuyuanshen.app.mapper.AppBusinessFileMapper;
import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper;
import com.fuyuanshen.app.mapper.AppPersonnelInfoRecordsMapper;
import com.fuyuanshen.app.service.IAppBusinessFileService;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.domain.model.LoginUser;
import com.fuyuanshen.common.core.exception.ServiceException;
import com.fuyuanshen.common.core.utils.*;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.equipment.domain.AppBusinessFile;
import com.fuyuanshen.equipment.domain.Device;
import com.fuyuanshen.equipment.domain.DeviceType;
import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo;
import com.fuyuanshen.equipment.enums.LightModeEnum;
import com.fuyuanshen.equipment.domain.vo.AppBusinessFileVo;
import com.fuyuanshen.equipment.mapper.AppBusinessFileMapper;
import com.fuyuanshen.equipment.mapper.DeviceLogMapper;
import com.fuyuanshen.equipment.mapper.DeviceMapper;
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
import com.fuyuanshen.equipment.service.IAppBusinessFileService;
import com.fuyuanshen.global.mqtt.config.MqttGateway;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.mqtt.constants.MqttConstants;
import com.fuyuanshen.global.mqtt.rule.hby100j.domin.*;
import com.fuyuanshen.global.mqtt.utils.GenerateIdUtil;
import com.fuyuanshen.system.domain.SysOss;
import com.fuyuanshen.system.domain.vo.SysOssVo;
import com.fuyuanshen.system.mapper.SysOssMapper;
import com.fuyuanshen.web.controller.device.domain.dto.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.time.Duration;
import java.util.*;
import java.util.Date;
import java.util.List;
import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY;
import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.buildArr;
import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.generateFixedBitmapData;
import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX;
@Slf4j
@ -249,7 +229,7 @@ public class DeviceHBY100JBizService {
}
public void forceAlarmActivation(AppDeviceHBY100JController.HBY100JForceAlarmActivationDto bo) {
public void forceAlarmActivation(HBY100JForceAlarmActivationDto bo) {
List<Long> deviceIds = bo.getDeviceIds();
if (deviceIds == null || deviceIds.isEmpty()) {
throw new ServiceException("请选择设备");
@ -279,7 +259,7 @@ public class DeviceHBY100JBizService {
}
public void updateVoice(AppDeviceHBY100JController.HBY100JUpdateVoiceDto dto) {
public void updateVoice(HBY100JUpdateVoiceDto dto) {
AppBusinessFileVo appBusinessFileVo = appBusinessFileMapper.selectVoById(dto.getId());
if(appBusinessFileVo == null){
throw new ServiceException("文件不存在");
@ -320,7 +300,7 @@ public class DeviceHBY100JBizService {
return MqttConstants.GLOBAL_PUB_KEY2 +tenantId + "/" + DEVICE_TYPE + deviceImei;
}
public void strobeMode(AppDeviceHBY100JController.HBY100JStrobeModeDto params) {
public void strobeMode(HBY100JStrobeModeDto params) {
Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
@ -338,7 +318,7 @@ public class DeviceHBY100JBizService {
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
}
public void lightAdjustment(AppDeviceHBY100JController.HBY100JLightAdjustmentDto params) {
public void lightAdjustment(HBY100JLightAdjustmentDto params) {
log.info("HBY100J灯光调节请求参数{}", params);
Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (deviceObj == null) {
@ -361,7 +341,7 @@ public class DeviceHBY100JBizService {
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
}
public void strobeFrequency(AppDeviceHBY100JController.HBY100JStrobeFrequencyDto params) {
public void strobeFrequency(HBY100JStrobeFrequencyDto params) {
Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (deviceObj == null) {
throw new ServiceException("设备不存在");
@ -381,7 +361,7 @@ public class DeviceHBY100JBizService {
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
}
public void updateVolume(AppDeviceHBY100JController.HBY100JUpdateVolumeDto params) {
public void updateVolume(HBY100JUpdateVolumeDto params) {
Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (deviceObj == null) {
throw new ServiceException("设备不存在");
@ -401,7 +381,7 @@ public class DeviceHBY100JBizService {
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
}
public void voiceBroadcast(AppDeviceHBY100JController.HBY100JVoiceBroadcastDto params) {
public void voiceBroadcast(HBY100JVoiceBroadcastDto params) {
Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (deviceObj == null) {
throw new ServiceException("设备不存在");

View File

@ -282,10 +282,10 @@ mqtt:
password: #YtvpSfCNG
url: tcp://47.120.79.150:2883
subClientId: fys_subClient
subTopic: A/#
pubTopic: B/#
subTopic2: command/894078/#
pubTopic2: status/894078/#
subTopic: A/#,status/#
pubTopic: B/#,command/#
subTopic2: regis/equip/#
pubTopic2: regis/#
pubClientId: fys_pubClient

View File

@ -283,10 +283,10 @@ mqtt:
password: #YtvpSfCNG
url: tcp://47.120.79.150:3883
subClientId: fys_subClient
subTopic: A/#
pubTopic: B/#
subTopic2: status/894078/#
pubTopic2: command/894078/#
subTopic: A/#,status/#
pubTopic: B/#,command/#
subTopic2: regis/equip/#
pubTopic2: regis/#
pubClientId: fys_pubClient
# TTS语音交互配置

View File

@ -209,6 +209,20 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
DeviceTypeGrants typeGrants = new DeviceTypeGrants();
// 修改为:
Long userId;
LoginUser loginUser;
try {
loginUser = LoginHelper.getLoginUser();
userId = loginUser != null ? loginUser.getUserId() : 1938143703108689922L; // 如果没有登录用户使用默认系统用户ID
} catch (Exception e) {
userId = 1938143703108689922L; // 出现异常时使用默认系统用户ID
loginUser = new LoginUser();
loginUser.setUserId(userId);
loginUser.setNickname("admin");
loginUser.setTenantId("894078"); // 设置租户ID
}
if (deviceForm.getDeviceType() != null) {
DeviceTypeQueryCriteria queryCriteria = new DeviceTypeQueryCriteria();
queryCriteria.setDeviceTypeId(deviceForm.getDeviceType());
@ -281,8 +295,8 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
throw new RuntimeException("设备类型名称已存在,无法新增!!!");
}
LoginUser loginUser = LoginHelper.getLoginUser();
newDeviceType.setCreateByName(loginUser.getNickname());
newDeviceType.setTenantId(loginUser.getTenantId());
deviceTypeMapper.insert(newDeviceType);
// 重新查询确保获取到正确的ID
@ -294,6 +308,7 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
deviceTypeGrants.setCustomerId(loginUser.getUserId());
deviceTypeGrants.setGrantorCustomerId(loginUser.getUserId());
deviceTypeGrants.setGrantedAt(new Date());
deviceTypeGrants.setTenantId(loginUser.getTenantId());
deviceTypeGrantsMapper.insert(deviceTypeGrants);
}
@ -318,13 +333,13 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
BeanUtil.copyProperties(deviceForm, device, true);
device.setDeviceNo(createDeviceNo());
LoginUser loginUser = LoginHelper.getLoginUser();
device.setCurrentOwnerId(loginUser.getUserId());
device.setOriginalOwnerId(loginUser.getUserId());
device.setCreateByName(loginUser.getNickname());
device.setTypeName(deviceType.getTypeName());
device.setDeviceType(deviceType.getId());
device.setDevicePic(deviceType.getDevicePic());
device.setTenantId(loginUser.getTenantId());
if (device.getDeviceImei() != null) {
device.setPubTopic("A/" + device.getDeviceImei());
device.setSubTopic("B/" + device.getDeviceImei());
@ -336,7 +351,7 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
// 查询设备类型的文件列表
// 4. 核心优化:同步设备类型的文件列表 (一行代码)
appBusinessFileService.cloneFiles(deviceType.getId(), device.getId());
//同步设备类型的视频列表
// 同步设备类型的视频列表
appOperationVideoService.cloneFiles(deviceType.getId(), device.getId());
// 新增设备类型记录
@ -351,10 +366,12 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
assignments.setActive(DeviceActiveStatusEnum.ACTIVE.getCode());
String lever = USER_ID_SEPARATOR + loginUser.getUserId();
assignments.setLever(lever);
assignments.setTenantId(loginUser.getTenantId());
deviceAssignmentsService.save(assignments);
}
private String createDeviceNo() {
String uuidStr = UUID.fastUUID().toString(); // 获取带 - 的标准格式字符串
return uuidStr.replaceAll("-", "");

View File

@ -2,7 +2,7 @@
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fuyuanshen.app.mapper.AppBusinessFileMapper">
<mapper namespace="com.fuyuanshen.equipment.mapper.AppBusinessFileMapper">
<select id="queryAppFileList" resultType="com.fuyuanshen.equipment.domain.vo.AppFileVo">
select a.id,a.business_id,a.file_id,a.file_type,b.file_name,b.url fileUrl,a.duration,

BIN
generated_speech.wav Normal file

Binary file not shown.

0
log/de_english-words.txt Normal file
View File

0
log/de_unknown.txt Normal file
View File

BIN
公安报警中.wav Normal file

Binary file not shown.