feat(device): 实现设备批量控制指令发送功能- 新增批量发送设备控制指令方法 sendCommandBatch- 支持设备离线状态检查和异常处理
- 添加设备操作日志记录和报警创建- 实现设备SOS档位批量设置接口 - 在设备指令处理中增加消息去重机制 - 优化设备报警处理的分布式锁逻辑 - 完善设备数据规则中的并发控制
This commit is contained in:
@ -109,6 +109,17 @@ public class DeviceXinghanController extends BaseController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* SOS档位 批量
|
||||
* SOS档位,2,1,0, 分别表示红蓝模式/爆闪模式/关闭
|
||||
*/
|
||||
@PostMapping("/SOSGradeSettingsBatch")
|
||||
public R<Void> SOSGradeSettingsBatch(@RequestBody DeviceXinghanInstructDto params) {
|
||||
// params 转 JSONObject
|
||||
deviceXinghanBizService.sendCommandBatch(params,"ins_SOSGrade","SOS档位");
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 静止报警状态
|
||||
* 静止报警状态,0-未静止报警,1-正在静止报警。
|
||||
|
||||
@ -2,6 +2,8 @@ package com.fuyuanshen.web.domain.Dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class DeviceXinghanInstructDto {
|
||||
private Long deviceId;
|
||||
@ -12,4 +14,5 @@ public class DeviceXinghanInstructDto {
|
||||
*/
|
||||
private String instructValue;
|
||||
private Boolean isBluetooth = false;
|
||||
private List<Long> deviceIds;
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ import com.fuyuanshen.common.json.utils.JsonUtils;
|
||||
import com.fuyuanshen.common.redis.utils.RedisUtils;
|
||||
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
|
||||
import com.fuyuanshen.equipment.domain.Device;
|
||||
import com.fuyuanshen.equipment.domain.DeviceLog;
|
||||
import com.fuyuanshen.equipment.domain.DeviceType;
|
||||
import com.fuyuanshen.equipment.domain.bo.DeviceAlarmBo;
|
||||
import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo;
|
||||
@ -531,6 +532,75 @@ public class DeviceXinghanBizService {
|
||||
createAlarm(device.getId(),deviceImei,payloadKey,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量发送设备控制指令
|
||||
*
|
||||
* @param dto 设备ID列表
|
||||
* @param payloadKey 指令负载数据的键名
|
||||
* @param deviceAction 设备操作类型描述
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class) // 1. 事务注解
|
||||
public void sendCommandBatch(DeviceXinghanInstructDto dto, String payloadKey, String deviceAction) {
|
||||
List<String> errorMessages = Collections.synchronizedList(new ArrayList<>());
|
||||
int value;
|
||||
try {
|
||||
value = Integer.parseInt(dto.getInstructValue());
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("指令值格式不正确,必须为整数。", e);
|
||||
}
|
||||
Map<String, List<Integer>> payload = Map.of(payloadKey, List.of(value));
|
||||
|
||||
// 一次性查询所有设备信息
|
||||
List<Device> devices = deviceMapper.selectList(
|
||||
new QueryWrapper<Device>().lambda().in(Device::getId, dto.getDeviceIds())
|
||||
);
|
||||
// 日志信息
|
||||
String contentText = resolveGradeDesc(payloadKey, value);
|
||||
|
||||
List<DeviceLog> logs = new ArrayList<>();
|
||||
try {
|
||||
for (Device device : devices) {
|
||||
String deviceImei = device.getDeviceImei();
|
||||
String deviceName = device.getDeviceName();
|
||||
|
||||
// 2. 提前进行设备状态检查,逻辑更清晰
|
||||
if (isDeviceOffline(deviceImei)) {
|
||||
throw new ServiceException("设备已断开连接:" + deviceName);
|
||||
}
|
||||
|
||||
String topic = MqttConstants.GLOBAL_PUB_KEY + deviceImei;
|
||||
String json = JsonUtils.toJsonString(payload);
|
||||
|
||||
mqttGateway.sendMsgToMqtt(topic, 1, json);
|
||||
log.info("发送指令成功 => topic:{}, payload:{}", topic, json);
|
||||
|
||||
// 创建设备日志实体
|
||||
DeviceLog deviceLog = new DeviceLog();
|
||||
deviceLog.setDeviceId(device.getId());
|
||||
deviceLog.setDeviceAction(deviceAction);
|
||||
deviceLog.setContent(contentText);
|
||||
deviceLog.setCreateBy(AppLoginHelper.getUserId());
|
||||
deviceLog.setDeviceName(deviceName);
|
||||
deviceLog.setCreateTime(new Date());
|
||||
logs.add(deviceLog);
|
||||
|
||||
createAlarm(device.getId(), deviceImei, payloadKey, value);
|
||||
}
|
||||
deviceLogMapper.insertBatch(logs);
|
||||
} catch (ServiceException e) {
|
||||
// 捕获并重新抛出自定义异常,避免内层异常被外层泛化捕获
|
||||
log.error("批量发送指令失败: {}", e.getMessage(), e);
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("批量发送指令发生未知错误", e);
|
||||
throw new ServiceException("批量发送指令失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查设备是否离线
|
||||
*/
|
||||
|
||||
// private boolean isDeviceOffline(String imei) {
|
||||
// // 原方法名语义相反,这里取反,使含义更清晰
|
||||
// return getDeviceStatus(imei);
|
||||
|
||||
@ -54,7 +54,7 @@ public class AppSmsAuthStrategy implements IAuthStrategy {
|
||||
String phonenumber = loginBody.getPhonenumber();
|
||||
String smsCode = loginBody.getSmsCode();
|
||||
AppLoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
|
||||
// loginService.checkLogin(LoginType.SMS, tenantId, phonenumber, () -> !validateSmsCode(tenantId, phonenumber, smsCode));
|
||||
loginService.checkLogin(LoginType.SMS, tenantId, phonenumber, () -> !validateSmsCode(tenantId, phonenumber, smsCode));
|
||||
AppUserVo user = loadUserByPhonenumber(phonenumber);
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
//新增Appuser
|
||||
|
||||
Reference in New Issue
Block a user