forked from dyf/fys-Multi-tenant
Merge branch 'dyf-device' into 6170
This commit is contained in:
@ -263,18 +263,21 @@ public class AppAuthController {
|
||||
@GetMapping("/version")
|
||||
public R<List<SysDictDataVo>> getAppVersion() {
|
||||
List<SysDictDataVo> list = dictTypeService.selectDictDataByType("app_version");
|
||||
|
||||
list.forEach(d -> {
|
||||
String[] arr = d.getRemark().split("\\|");
|
||||
d.setDictLabel(d.getDictLabel()); // ios/android
|
||||
d.setDictValue(arr[0]); // 版本号
|
||||
d.setRemark(arr[1]); // 下载地址
|
||||
// 1. 安全拆分
|
||||
String[] arr = d.getRemark() == null ? new String[0] : d.getRemark().split("\\|");
|
||||
if (arr.length < 2) { // 格式不对
|
||||
log.warn("字典数据 app_version 格式非法:dictLabel={}, remark={}", d.getDictLabel(), d.getRemark());
|
||||
d.setDictValue(""); // 或者 d.setDictValue(d.getDictValue());
|
||||
d.setRemark(""); // 下载地址留空
|
||||
return; // 跳过
|
||||
}
|
||||
// 2. 正常赋值
|
||||
d.setDictValue(arr[0].trim()); // 版本号
|
||||
d.setRemark(arr[1].trim()); // 下载地址
|
||||
});
|
||||
// 只保留方法体:筛选 label=ios 且版本号 ≥ 2.5.0 的列表
|
||||
// List<SysDictDataVo> result = list.stream()
|
||||
// .peek(d -> { String[] a = d.getRemark().split("\\|"); d.setDictValue(a[0]); d.setRemark(a[1]); })
|
||||
// .filter(d -> "ios".equalsIgnoreCase(d.getDictLabel()))
|
||||
// .filter(d -> VersionComparator.INSTANCE.compare(d.getDictValue(), "2.5.0") >= 0)
|
||||
// .toList();
|
||||
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation;
|
||||
import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessBatcAnnotation;
|
||||
import com.fuyuanshen.common.web.core.BaseController;
|
||||
import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo;
|
||||
import com.fuyuanshen.web.domain.Dto.DeviceXinghanInstructDto;
|
||||
import com.fuyuanshen.web.service.device.DeviceBJQBizService;
|
||||
import com.fuyuanshen.web.service.device.DeviceXinghanBizService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -70,7 +71,7 @@ public class AppDeviceXinghanController extends BaseController {
|
||||
*/
|
||||
@Log(title = "xinghan指令-静电预警档位")
|
||||
@PostMapping("/DetectGradeSettings")
|
||||
public R<Void> DetectGradeSettings(@RequestBody DeviceInstructDto params) {
|
||||
public R<Void> DetectGradeSettings(@RequestBody DeviceXinghanInstructDto params) {
|
||||
// params 转 JSONObject
|
||||
appDeviceService.upDetectGradeSettings(params);
|
||||
return R.ok();
|
||||
@ -82,7 +83,7 @@ public class AppDeviceXinghanController extends BaseController {
|
||||
*/
|
||||
@Log(title = "xinghan指令-照明档位")
|
||||
@PostMapping("/LightGradeSettings")
|
||||
public R<Void> LightGradeSettings(@RequestBody DeviceInstructDto params) {
|
||||
public R<Void> LightGradeSettings(@RequestBody DeviceXinghanInstructDto params) {
|
||||
// params 转 JSONObject
|
||||
appDeviceService.upLightGradeSettings(params);
|
||||
return R.ok();
|
||||
@ -94,7 +95,7 @@ public class AppDeviceXinghanController extends BaseController {
|
||||
*/
|
||||
@Log(title = "xinghan指令-SOS档位s")
|
||||
@PostMapping("/SOSGradeSettings")
|
||||
public R<Void> SOSGradeSettings(@RequestBody DeviceInstructDto params) {
|
||||
public R<Void> SOSGradeSettings(@RequestBody DeviceXinghanInstructDto params) {
|
||||
// params 转 JSONObject
|
||||
appDeviceService.upSOSGradeSettings(params);
|
||||
return R.ok();
|
||||
@ -106,7 +107,7 @@ public class AppDeviceXinghanController extends BaseController {
|
||||
*/
|
||||
@Log(title = "xinghan指令-静止报警状态")
|
||||
@PostMapping("/ShakeBitSettings")
|
||||
public R<Void> ShakeBitSettings(@RequestBody DeviceInstructDto params) {
|
||||
public R<Void> ShakeBitSettings(@RequestBody DeviceXinghanInstructDto params) {
|
||||
// params 转 JSONObject
|
||||
appDeviceService.upShakeBitSettings(params);
|
||||
return R.ok();
|
||||
|
||||
@ -61,5 +61,14 @@ public class MqttXinghanJson {
|
||||
*/
|
||||
@JsonProperty("sta_latitude")
|
||||
public String stalatitude;
|
||||
/**
|
||||
* 第十二键值对,系统现状,0关机,1仅充电,2开机未充电,3,开机且充电
|
||||
*/
|
||||
@JsonProperty("sta_system")
|
||||
public String stasystem;
|
||||
/**
|
||||
* 电量百分比(适配控制列表显示)
|
||||
*/
|
||||
public String batteryPercentage;
|
||||
|
||||
}
|
||||
|
||||
@ -1,33 +1,42 @@
|
||||
package com.fuyuanshen.global.mqtt.rule.xinghan;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fuyuanshen.common.core.constant.GlobalConstants;
|
||||
import com.fuyuanshen.common.core.utils.StringUtils;
|
||||
import com.fuyuanshen.common.core.utils.date.DurationUtils;
|
||||
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.bo.DeviceAlarmBo;
|
||||
import com.fuyuanshen.equipment.domain.vo.DeviceAlarmVo;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceAlarmMapper;
|
||||
import com.fuyuanshen.equipment.service.DeviceService;
|
||||
import com.fuyuanshen.equipment.service.IDeviceAlarmService;
|
||||
import com.fuyuanshen.equipment.utils.map.GetAddressFromLatUtil;
|
||||
import com.fuyuanshen.equipment.utils.map.LngLonUtil;
|
||||
import com.fuyuanshen.global.mqtt.base.MqttMessageRule;
|
||||
import com.fuyuanshen.global.mqtt.base.MqttRuleContext;
|
||||
import com.fuyuanshen.global.mqtt.base.MqttXinghanJson;
|
||||
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
|
||||
import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants;
|
||||
import com.fuyuanshen.global.mqtt.constants.XingHanCommandTypeConstants;
|
||||
import com.fuyuanshen.global.mqtt.listener.domain.FunctionAccessStatus;
|
||||
import com.fuyuanshen.web.enums.AlarmTypeEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY;
|
||||
import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY;
|
||||
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*;
|
||||
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
|
||||
|
||||
@ -57,6 +66,9 @@ public class XinghanDeviceDataRule implements MqttMessageRule {
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
private final IDeviceAlarmService deviceAlarmService;
|
||||
private final DeviceService deviceService;
|
||||
private final DeviceAlarmMapper deviceAlarmMapper;
|
||||
|
||||
@Override
|
||||
public void execute(MqttRuleContext context) {
|
||||
@ -65,7 +77,7 @@ public class XinghanDeviceDataRule implements MqttMessageRule {
|
||||
// Latitude, longitude
|
||||
//主灯档位,激光灯档位,电量百分比,充电状态,电池剩余续航时间
|
||||
MqttXinghanJson deviceStatus = objectMapper.convertValue(context.getPayloadDict(), MqttXinghanJson.class);
|
||||
|
||||
deviceStatus.setBatteryPercentage(deviceStatus.getStaPowerPercent().toString());
|
||||
// 发送设备状态和位置信息到Redis
|
||||
asyncSendDeviceDataToRedisWithFuture(context.getDeviceImei(),deviceStatus);
|
||||
RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20));
|
||||
@ -99,12 +111,113 @@ public class XinghanDeviceDataRule implements MqttMessageRule {
|
||||
// 异步发送经纬度到Redis
|
||||
asyncSendLocationToRedisWithFuture(deviceImei, deviceStatus.getStalatitude(), deviceStatus.getStalongitude());
|
||||
|
||||
// 保存报警信息
|
||||
saveAlarm(deviceImei,deviceStatus);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("异步发送设备信息到Redis时出错: device={}, error={}", deviceImei, e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 入口:保存报警(SOS 与 Shake 完全独立)
|
||||
*/
|
||||
public void saveAlarm(String deviceImei, MqttXinghanJson status) {
|
||||
int sos = Optional.ofNullable(status.getStaSOSGrade()).orElse(0);
|
||||
// 1. 处理 SOS 报警
|
||||
handleSingleAlarm(deviceImei,
|
||||
sos > 0,
|
||||
AlarmTypeEnum.SOS);
|
||||
int shake = Optional.ofNullable(status.getStaShakeBit()).orElse(0);
|
||||
// 2. 处理 Shake 报警
|
||||
handleSingleAlarm(deviceImei,
|
||||
shake > 0,
|
||||
AlarmTypeEnum.SHAKE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用:对单个报警源的“开始/结束”生命周期管理
|
||||
*/
|
||||
private void handleSingleAlarm(String deviceImei, boolean nowAlarming, AlarmTypeEnum type) {
|
||||
String redisKey = buildAlarmRedisKey(deviceImei, type);
|
||||
|
||||
Long alarmId = RedisUtils.getCacheObject(redisKey);
|
||||
|
||||
// ---------- 情况 1:当前正在报警 ----------
|
||||
if (nowAlarming) {
|
||||
// 已存在未结束报警 -> 什么都不做(同一条报警)
|
||||
if (alarmId != null) {
|
||||
// key 还在 -> 同一条报警,只续期
|
||||
RedisUtils.setCacheObject(redisKey, alarmId, Duration.ofMinutes(10));
|
||||
return;
|
||||
}
|
||||
// 不存在 -> 新建
|
||||
DeviceAlarmBo bo = createAlarmBo(deviceImei, type);
|
||||
deviceAlarmService.insertByBo(bo);
|
||||
RedisUtils.setCacheObject(redisKey, bo.getId(), Duration.ofMinutes(10)); // 5分钟后结束过期
|
||||
return;
|
||||
}
|
||||
|
||||
// ---------- 情况 2:当前不报警 ----------
|
||||
if (alarmId != null) {
|
||||
// 结束它
|
||||
finishAlarm(alarmId);
|
||||
RedisUtils.deleteObject(redisKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束报警:写库
|
||||
*/
|
||||
private void finishAlarm(Long alarmId) {
|
||||
DeviceAlarmVo vo = deviceAlarmService.queryById(alarmId);
|
||||
if (vo == null || vo.getTreatmentState() == 0) {
|
||||
return; // 已处理或已被删
|
||||
}
|
||||
DeviceAlarmBo bo = BeanUtil.toBean(vo, DeviceAlarmBo.class);
|
||||
bo.setFinishTime(new Date());
|
||||
bo.setDurationTime(DurationUtils.getDurationBetween(vo.getStartTime(), bo.getFinishTime()));
|
||||
bo.setTreatmentState(0); // 已处理
|
||||
deviceAlarmService.updateByBo(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建报警 Bo
|
||||
*/
|
||||
private DeviceAlarmBo createAlarmBo(String deviceImei, AlarmTypeEnum type) {
|
||||
Device device = deviceService.selectDeviceByImei(deviceImei);
|
||||
if (device == null) {
|
||||
return null;
|
||||
}
|
||||
DeviceAlarmBo bo = new DeviceAlarmBo();
|
||||
bo.setDeviceId(device.getId());
|
||||
bo.setDeviceImei(deviceImei);
|
||||
bo.setDeviceAction(2); // 自动报警
|
||||
bo.setStartTime(new Date());
|
||||
bo.setTreatmentState(1); // 未处理
|
||||
bo.setTenantId(device.getTenantId());
|
||||
|
||||
// 报警内容
|
||||
bo.setContent("自动报警:" + type.getDesc());
|
||||
|
||||
// 位置
|
||||
String location = RedisUtils.getCacheObject(
|
||||
GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + deviceImei + DEVICE_LOCATION_KEY_PREFIX);
|
||||
if (StrUtil.isNotBlank(location)) {
|
||||
bo.setLocation(JSONObject.parseObject(location).getString("address"));
|
||||
}
|
||||
return bo;
|
||||
}
|
||||
|
||||
/**
|
||||
* key 构建
|
||||
*/
|
||||
private String buildAlarmRedisKey(String deviceImei, AlarmTypeEnum type) {
|
||||
return StrUtil.format("{}{}{}{}:alarm_id",
|
||||
GLOBAL_REDIS_KEY, DEVICE_KEY_PREFIX, deviceImei, type.getSuffix());
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步发送位置信息到Redis(使用CompletableFuture)
|
||||
*
|
||||
|
||||
@ -10,6 +10,7 @@ import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation;
|
||||
import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessBatcAnnotation;
|
||||
import com.fuyuanshen.common.web.core.BaseController;
|
||||
import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo;
|
||||
import com.fuyuanshen.web.domain.Dto.DeviceXinghanInstructDto;
|
||||
import com.fuyuanshen.web.domain.vo.DeviceXinghanDetailVo;
|
||||
import com.fuyuanshen.web.service.device.DeviceXinghanBizService;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@ -80,7 +81,7 @@ public class DeviceXinghanController extends BaseController {
|
||||
* 3,2,1,0,分别表示高档/中档/低挡/关闭
|
||||
*/
|
||||
@PostMapping("/DetectGradeSettings")
|
||||
public R<Void> DetectGradeSettings(@RequestBody DeviceInstructDto params) {
|
||||
public R<Void> DetectGradeSettings(@RequestBody DeviceXinghanInstructDto params) {
|
||||
// params 转 JSONObject
|
||||
deviceXinghanBizService.upDetectGradeSettings(params);
|
||||
return R.ok();
|
||||
@ -91,7 +92,7 @@ public class DeviceXinghanController extends BaseController {
|
||||
* 照明档位,2,1,0,分别表示弱光/强光/关闭
|
||||
*/
|
||||
@PostMapping("/LightGradeSettings")
|
||||
public R<Void> LightGradeSettings(@RequestBody DeviceInstructDto params) {
|
||||
public R<Void> LightGradeSettings(@RequestBody DeviceXinghanInstructDto params) {
|
||||
// params 转 JSONObject
|
||||
deviceXinghanBizService.upLightGradeSettings(params);
|
||||
return R.ok();
|
||||
@ -102,7 +103,7 @@ public class DeviceXinghanController extends BaseController {
|
||||
* SOS档位,2,1,0, 分别表示红蓝模式/爆闪模式/关闭
|
||||
*/
|
||||
@PostMapping("/SOSGradeSettings")
|
||||
public R<Void> SOSGradeSettings(@RequestBody DeviceInstructDto params) {
|
||||
public R<Void> SOSGradeSettings(@RequestBody DeviceXinghanInstructDto params) {
|
||||
// params 转 JSONObject
|
||||
deviceXinghanBizService.upSOSGradeSettings(params);
|
||||
return R.ok();
|
||||
@ -113,7 +114,7 @@ public class DeviceXinghanController extends BaseController {
|
||||
* 静止报警状态,0-未静止报警,1-正在静止报警。
|
||||
*/
|
||||
@PostMapping("/ShakeBitSettings")
|
||||
public R<Void> ShakeBitSettings(@RequestBody DeviceInstructDto params) {
|
||||
public R<Void> ShakeBitSettings(@RequestBody DeviceXinghanInstructDto params) {
|
||||
// params 转 JSONObject
|
||||
deviceXinghanBizService.upShakeBitSettings(params);
|
||||
return R.ok();
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package com.fuyuanshen.web.domain.Dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DeviceXinghanInstructDto {
|
||||
private Long deviceId;
|
||||
|
||||
private String deviceImei;
|
||||
/**
|
||||
* 下发指令
|
||||
*/
|
||||
private String instructValue;
|
||||
private Boolean isBluetooth = false;
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.fuyuanshen.web.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 报警类型枚举
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum AlarmTypeEnum {
|
||||
SOS("_sos", "SOS报警"),
|
||||
SHAKE("_shake", "静止报警");
|
||||
|
||||
private final String suffix;
|
||||
private final String desc;
|
||||
}
|
||||
@ -10,18 +10,15 @@ import com.fuyuanshen.app.service.IAppBusinessFileService;
|
||||
import com.fuyuanshen.app.service.IAppOperationVideoService;
|
||||
import com.fuyuanshen.common.core.exception.ServiceException;
|
||||
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.equipment.service.DeviceService;
|
||||
import com.fuyuanshen.system.domain.vo.SysOssVo;
|
||||
import com.fuyuanshen.system.service.ISysOssService;
|
||||
import com.fuyuanshen.web.domain.vo.DeviceInfoVo;
|
||||
import com.fuyuanshen.web.util.FileHashUtil;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import com.fuyuanshen.equipment.utils.FileHashUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.fuyuanshen.web.service.device;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
@ -28,17 +29,21 @@ 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.DeviceType;
|
||||
import com.fuyuanshen.equipment.domain.bo.DeviceAlarmBo;
|
||||
import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo;
|
||||
import com.fuyuanshen.equipment.enums.LightModeEnum;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceLogMapper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceMapper;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
|
||||
import com.fuyuanshen.equipment.service.IDeviceAlarmService;
|
||||
import com.fuyuanshen.global.mqtt.base.MqttXinghanJson;
|
||||
import com.fuyuanshen.global.mqtt.config.MqttGateway;
|
||||
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
|
||||
import com.fuyuanshen.global.mqtt.constants.MqttConstants;
|
||||
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 lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -68,6 +73,7 @@ public class DeviceXinghanBizService {
|
||||
private final MqttGateway mqttGateway;
|
||||
private final DeviceLogMapper deviceLogMapper;
|
||||
private final AppPersonnelInfoRecordsMapper appPersonnelInfoRecordsMapper;
|
||||
private final IDeviceAlarmService deviceAlarmService;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@ -95,28 +101,39 @@ public class DeviceXinghanBizService {
|
||||
/**
|
||||
* 设置静电预警档位
|
||||
*/
|
||||
public void upDetectGradeSettings(DeviceInstructDto dto) {
|
||||
public void upDetectGradeSettings(DeviceXinghanInstructDto dto) {
|
||||
sendCommand(dto, "ins_DetectGrade","静电预警档位");
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置照明档位
|
||||
*/
|
||||
public void upLightGradeSettings(DeviceInstructDto dto) {
|
||||
public void upLightGradeSettings(DeviceXinghanInstructDto dto) {
|
||||
sendCommand(dto, "ins_LightGrade","照明档位");
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置SOS档位
|
||||
*/
|
||||
public void upSOSGradeSettings(DeviceInstructDto dto) {
|
||||
sendCommand(dto, "ins_SOSGrade","SOS档位");
|
||||
public void upSOSGradeSettings(DeviceXinghanInstructDto dto) {
|
||||
if(dto.getIsBluetooth()){
|
||||
long deviceId = dto.getDeviceId();
|
||||
|
||||
// 1. 使用Optional简化空值检查,使代码更简洁
|
||||
Device device = Optional.ofNullable(deviceMapper.selectById(deviceId))
|
||||
.orElseThrow(() -> new ServiceException("设备不存在"));
|
||||
int sosGrade = Integer.parseInt(dto.getInstructValue());
|
||||
// 6. 新建报警信息
|
||||
createAlarm(device.getId(),device.getDeviceImei(),"ins_SOSGrade",sosGrade);
|
||||
}else {
|
||||
sendCommand(dto, "ins_SOSGrade","SOS档位");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置强制报警
|
||||
*/
|
||||
public void upShakeBitSettings(DeviceInstructDto dto) {
|
||||
public void upShakeBitSettings(DeviceXinghanInstructDto dto) {
|
||||
sendCommand(dto, "ins_ShakeBit","强制报警");
|
||||
}
|
||||
|
||||
@ -465,7 +482,7 @@ public class DeviceXinghanBizService {
|
||||
* @param payloadKey 指令负载数据的键名
|
||||
* @param deviceAction 设备操作类型描述
|
||||
*/
|
||||
private void sendCommand(DeviceInstructDto dto, String payloadKey, String deviceAction) {
|
||||
private void sendCommand(DeviceXinghanInstructDto dto, String payloadKey, String deviceAction) {
|
||||
long deviceId = dto.getDeviceId();
|
||||
|
||||
// 1. 使用Optional简化空值检查,使代码更简洁
|
||||
@ -509,6 +526,9 @@ public class DeviceXinghanBizService {
|
||||
deviceAction,
|
||||
content,
|
||||
AppLoginHelper.getUserId());
|
||||
|
||||
// 6. 新建报警信息
|
||||
createAlarm(device.getId(),deviceImei,payloadKey,value);
|
||||
}
|
||||
|
||||
// private boolean isDeviceOffline(String imei) {
|
||||
@ -516,6 +536,48 @@ public class DeviceXinghanBizService {
|
||||
// return getDeviceStatus(imei);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 新建报警 Bo
|
||||
*/
|
||||
private void createAlarm(Long deviceId, String deviceImei,
|
||||
String payloadKey, int value) {
|
||||
// 这里直接放你原来的 createAlarmBo 全部逻辑
|
||||
if (!"ins_SOSGrade".equals(payloadKey) || value == 0) {
|
||||
return;
|
||||
}
|
||||
AlarmTypeEnum type = value == 1 ? AlarmTypeEnum.SOS : AlarmTypeEnum.SHAKE;
|
||||
String redisKey = buildAlarmRedisKey(deviceImei, type);
|
||||
Long alarmId = RedisUtils.getCacheObject(redisKey);
|
||||
// 已存在未结束报警 -> 什么都不做(同一条报警)
|
||||
if (alarmId != null) {
|
||||
// key 还在 -> 同一条报警,只续期
|
||||
RedisUtils.setCacheObject(redisKey, alarmId, Duration.ofMinutes(10));
|
||||
return;
|
||||
}
|
||||
// 不存在 -> 新建
|
||||
DeviceAlarmBo bo = new DeviceAlarmBo();
|
||||
bo.setDeviceId(deviceId);
|
||||
bo.setDeviceImei(deviceImei);
|
||||
bo.setDeviceAction(0); // 强制报警
|
||||
bo.setStartTime(new Date());
|
||||
bo.setTreatmentState(1); // 未处理
|
||||
bo.setContent("强制报警:" + type.getDesc());
|
||||
String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + deviceImei + DEVICE_LOCATION_KEY_PREFIX);
|
||||
if (StrUtil.isNotBlank(location)) {
|
||||
bo.setLocation(JSONObject.parseObject(location).getString("address"));
|
||||
}
|
||||
deviceAlarmService.insertByBo(bo);
|
||||
RedisUtils.setCacheObject(redisKey, bo.getId(), Duration.ofMinutes(10));
|
||||
}
|
||||
|
||||
/**
|
||||
* key 构建
|
||||
*/
|
||||
private String buildAlarmRedisKey(String deviceImei, AlarmTypeEnum type) {
|
||||
return StrUtil.format("{}{}{}{}:alarm_id",
|
||||
GLOBAL_REDIS_KEY, DEVICE_KEY_PREFIX, deviceImei, type.getSuffix());
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录设备操作日志
|
||||
* @param deviceId 设备ID
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
package com.fuyuanshen.web.util;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.HexFormat;
|
||||
|
||||
/**
|
||||
* 文件哈希工具类
|
||||
*/
|
||||
public class FileHashUtil {
|
||||
private static final String ALGORITHM = "SHA-256";
|
||||
|
||||
public static String hash(MultipartFile file) throws IOException {
|
||||
MessageDigest digest = DigestUtils.getDigest(ALGORITHM);
|
||||
try (InputStream in = file.getInputStream()) {
|
||||
byte[] buf = new byte[8192];
|
||||
int len;
|
||||
while ((len = in.read(buf)) != -1) {
|
||||
digest.update(buf, 0, len);
|
||||
}
|
||||
}
|
||||
return HexFormat.of().formatHex(digest.digest());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user