forked from dyf/fys-Multi-tenant
Merge branch 'dyf-device' into 6170
This commit is contained in:
@ -3,6 +3,7 @@ package com.fuyuanshen.global.mqtt.config;
|
||||
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import com.fuyuanshen.global.mqtt.receiver.ReceiverMessageHandler;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -55,4 +56,10 @@ public class MqttInboundConfiguration {
|
||||
public MessageHandler messageHandler(){
|
||||
return receiverMessageHandler;
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// @ServiceActivator(inputChannel = "messageInboundChannel") // 确保通道名称正确
|
||||
// public MessageHandler deviceAlarmMessageHandler() {
|
||||
// return new DeviceAlrmMessageHandler();
|
||||
// }
|
||||
}
|
||||
@ -1,8 +1,18 @@
|
||||
package com.fuyuanshen.global.mqtt.rule.bjq;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fuyuanshen.common.core.constant.GlobalConstants;
|
||||
import com.fuyuanshen.common.core.domain.model.LoginUser;
|
||||
import com.fuyuanshen.common.core.utils.StringUtils;
|
||||
import com.fuyuanshen.common.core.utils.date.DurationUtils;
|
||||
import com.fuyuanshen.common.redis.utils.RedisUtils;
|
||||
import com.fuyuanshen.common.satoken.utils.LoginHelper;
|
||||
import com.fuyuanshen.equipment.domain.Device;
|
||||
import com.fuyuanshen.equipment.domain.bo.DeviceAlarmBo;
|
||||
import com.fuyuanshen.equipment.domain.vo.DeviceAlarmVo;
|
||||
import com.fuyuanshen.equipment.service.DeviceService;
|
||||
import com.fuyuanshen.equipment.service.IDeviceAlarmService;
|
||||
import com.fuyuanshen.global.mqtt.base.MqttMessageRule;
|
||||
import com.fuyuanshen.global.mqtt.base.MqttRuleContext;
|
||||
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
|
||||
@ -13,9 +23,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Date;
|
||||
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.*;
|
||||
|
||||
/**
|
||||
@ -26,6 +38,11 @@ import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*;
|
||||
@Slf4j
|
||||
public class BjqAlarmRule implements MqttMessageRule {
|
||||
|
||||
|
||||
private final IDeviceAlarmService deviceAlarmService;
|
||||
private final DeviceService deviceService;
|
||||
|
||||
|
||||
@Override
|
||||
public String getCommandType() {
|
||||
return LightingCommandTypeConstants.ALARM_MESSAGE;
|
||||
@ -38,14 +55,21 @@ public class BjqAlarmRule implements MqttMessageRule {
|
||||
Object[] convertArr = context.getConvertArr();
|
||||
|
||||
String convertValue = convertArr[1].toString();
|
||||
if(StringUtils.isNotBlank(convertValue)){
|
||||
if (StringUtils.isNotBlank(convertValue)) {
|
||||
// 将设备状态信息存储到Redis中
|
||||
String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_ALARM_KEY_PREFIX;
|
||||
String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_ALARM_KEY_PREFIX;
|
||||
|
||||
// 存储到Redis
|
||||
RedisUtils.setCacheObject(deviceRedisKey, convertValue);
|
||||
}
|
||||
RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20));
|
||||
|
||||
// 保存告警信息
|
||||
String deviceImei = context.getDeviceImei();
|
||||
// 设备告警状态 0:解除告警 1:报警产生
|
||||
Byte state = (Byte) convertArr[1];
|
||||
savaAlarm(deviceImei, state);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理告警命令时出错", e);
|
||||
RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20));
|
||||
@ -53,4 +77,49 @@ public class BjqAlarmRule implements MqttMessageRule {
|
||||
}
|
||||
|
||||
|
||||
public void savaAlarm(String deviceImei, Byte state) {
|
||||
DeviceAlarmVo deviceAlarmVo = deviceAlarmService.queryLatestByDeviceImei(deviceImei);
|
||||
DeviceAlarmBo deviceAlarmBo = new DeviceAlarmBo();
|
||||
|
||||
// 解除告警
|
||||
if (state == 0) {
|
||||
if (deviceAlarmVo != null) {
|
||||
if (deviceAlarmVo.getFinishTime() == null) {
|
||||
BeanUtil.copyProperties(deviceAlarmVo, deviceAlarmBo);
|
||||
deviceAlarmBo.setFinishTime(new Date());
|
||||
String durationBetween = DurationUtils.getDurationBetween(deviceAlarmVo.getStartTime(), deviceAlarmBo.getFinishTime());
|
||||
deviceAlarmBo.setDurationTime(durationBetween);
|
||||
deviceAlarmService.updateByBo(deviceAlarmBo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 报警产生
|
||||
if (state == 1) {
|
||||
if (deviceAlarmVo == null || deviceAlarmVo.getFinishTime() != null) {
|
||||
|
||||
Device device = deviceService.selectDeviceByImei(deviceImei);
|
||||
deviceAlarmBo.setDeviceId(device.getId());
|
||||
deviceAlarmBo.setDeviceImei(deviceImei);
|
||||
// 0-强制报警,1-撞击闯入,2-自动报警,3-电子围栏告警
|
||||
deviceAlarmBo.setDeviceAction(0);
|
||||
deviceAlarmBo.setStartTime(new Date());
|
||||
// 0已处理,1未处理
|
||||
deviceAlarmBo.setTreatmentState(1);
|
||||
|
||||
// LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
// deviceAlarmBo.setCreateBy(loginUser.getUserId());
|
||||
deviceAlarmBo.setTenantId(device.getTenantId());
|
||||
|
||||
String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + deviceImei + DEVICE_LOCATION_KEY_PREFIX);
|
||||
if (StringUtils.isNotBlank(location)) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(location);
|
||||
deviceAlarmBo.setLocation(jsonObject.getString("address"));
|
||||
}
|
||||
deviceAlarmService.insertByBo(deviceAlarmBo);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -47,6 +47,7 @@ public class DeviceFenceAccessRecordController extends BaseController {
|
||||
return deviceFenceAccessRecordService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出围栏进出记录列表
|
||||
*/
|
||||
|
||||
@ -50,6 +50,7 @@ public class DeviceGeoFenceController extends BaseController {
|
||||
return deviceGeoFenceService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出电子围栏列表
|
||||
*/
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
// package com.fuyuanshen.web.handler.mqtt;
|
||||
//
|
||||
// import cn.hutool.core.lang.Dict;
|
||||
// import com.fuyuanshen.common.core.constant.GlobalConstants;
|
||||
// import com.fuyuanshen.common.json.utils.JsonUtils;
|
||||
// import com.fuyuanshen.common.redis.utils.RedisUtils;
|
||||
// import com.fuyuanshen.global.mqtt.base.MqttRuleContext;
|
||||
// import com.fuyuanshen.global.mqtt.base.MqttRuleEngine;
|
||||
// import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
|
||||
// import lombok.extern.slf4j.Slf4j;
|
||||
// import org.apache.commons.lang3.StringUtils;
|
||||
// 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;
|
||||
//
|
||||
// /**
|
||||
// * @author: 默苍璃
|
||||
// * @date: 2025-09-1609:28
|
||||
// */
|
||||
// @Service
|
||||
// @Slf4j
|
||||
// public class DeviceAlrmMessageHandler implements MessageHandler {
|
||||
//
|
||||
// @Autowired
|
||||
// private MqttRuleEngine ruleEngine;
|
||||
//
|
||||
// @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();
|
||||
//
|
||||
// log.info("设备强制报警消息处理器 - MQTT payload= {} \n receivedTopic = {}", payload, receivedTopic);
|
||||
//
|
||||
// // 解析消息并执行相应逻辑
|
||||
// Dict payloadDict = JsonUtils.parseMap(payload.toString());
|
||||
// if (payloadDict != null) {
|
||||
// // 根据主题或消息内容执行不同的处理逻辑
|
||||
// processMessage(receivedTopic, payloadDict);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void processMessage(String topic, Dict payloadDict) {
|
||||
// // 实现具体的业务逻辑
|
||||
// // 可以根据不同的主题执行不同的操作
|
||||
// if (topic.contains("newTopic")) {
|
||||
// // 处理特定主题的消息
|
||||
// handleNewTopicMessage(payloadDict);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void handleNewTopicMessage(Dict payloadDict) {
|
||||
// // 实现新主题消息的具体处理逻辑
|
||||
// String deviceImei = payloadDict.getStr("imei");
|
||||
// if (StringUtils.isNotBlank(deviceImei)) {
|
||||
// // 更新设备状态到Redis
|
||||
// String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY +
|
||||
// DEVICE_KEY_PREFIX + deviceImei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX;
|
||||
// RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(62));
|
||||
//
|
||||
// // 执行规则引擎
|
||||
// MqttRuleContext context = new MqttRuleContext();
|
||||
// context.setDeviceImei(deviceImei);
|
||||
// context.setPayloadDict(payloadDict);
|
||||
// // 设置命令类型
|
||||
// context.setCommandType((byte) 0x02); // 根据实际需要设置命令类型
|
||||
//
|
||||
// boolean ruleExecuted = ruleEngine.executeRule(context);
|
||||
// if (!ruleExecuted) {
|
||||
// log.warn("未找到匹配的规则来处理新主题消息,设备IMEI: {}", deviceImei);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
@ -301,8 +301,8 @@ file:
|
||||
mqtt:
|
||||
username: admin
|
||||
password: #YtvpSfCNG
|
||||
url: tcp://47.120.79.150:2883
|
||||
url: tcp://47.120.79.150:3883
|
||||
subClientId: fys_subClient
|
||||
subTopic: worker/location/#
|
||||
subTopic: A/#
|
||||
pubTopic: B/#
|
||||
pubClientId: fys_pubClient
|
||||
@ -0,0 +1,108 @@
|
||||
package com.fuyuanshen.common.core.utils.date;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 持续时间工具类
|
||||
* 提供计算两个日期之间差值的方法,并以时分秒格式返回
|
||||
*
|
||||
* @author fys
|
||||
*/
|
||||
public class DurationUtils {
|
||||
|
||||
/**
|
||||
* 计算两个日期之间的差值,返回时分秒格式的字符串
|
||||
* 格式为 "X小时 Y分钟 Z秒"
|
||||
*
|
||||
* @param startDate 开始日期
|
||||
* @param endDate 结束日期
|
||||
* @return 时分秒格式的时间差字符串
|
||||
*/
|
||||
public static String getDurationBetween(Date startDate, Date endDate) {
|
||||
if (startDate == null || endDate == null) {
|
||||
return "0小时 0分钟 0秒";
|
||||
}
|
||||
|
||||
long diffInMillis = Math.abs(endDate.getTime() - startDate.getTime());
|
||||
long hours = TimeUnit.MILLISECONDS.toHours(diffInMillis);
|
||||
long minutes = TimeUnit.MILLISECONDS.toMinutes(diffInMillis) % 60;
|
||||
long seconds = TimeUnit.MILLISECONDS.toSeconds(diffInMillis) % 60;
|
||||
|
||||
return String.format("%d小时 %d分钟 %d秒", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两个日期之间的差值,返回时分秒格式的字符串
|
||||
* 仅显示非零单位
|
||||
*
|
||||
* @param startDate 开始日期
|
||||
* @param endDate 结束日期
|
||||
* @return 时分秒格式的时间差字符串,仅显示非零单位
|
||||
*/
|
||||
public static String getDurationBetweenPretty(Date startDate, Date endDate) {
|
||||
if (startDate == null || endDate == null) {
|
||||
return "0秒";
|
||||
}
|
||||
|
||||
long diffInMillis = Math.abs(endDate.getTime() - startDate.getTime());
|
||||
long hours = TimeUnit.MILLISECONDS.toHours(diffInMillis);
|
||||
long minutes = TimeUnit.MILLISECONDS.toMinutes(diffInMillis) % 60;
|
||||
long seconds = TimeUnit.MILLISECONDS.toSeconds(diffInMillis) % 60;
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
if (hours > 0) {
|
||||
result.append(hours).append("小时 ");
|
||||
}
|
||||
if (minutes > 0) {
|
||||
result.append(minutes).append("分钟 ");
|
||||
}
|
||||
if (seconds > 0 || result.length() == 0) {
|
||||
result.append(seconds).append("秒");
|
||||
}
|
||||
|
||||
return result.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算指定毫秒数的持续时间,返回时分秒格式的字符串
|
||||
*
|
||||
* @param millis 毫秒数
|
||||
* @return 时分秒格式的持续时间字符串
|
||||
*/
|
||||
public static String getDurationFromMillis(long millis) {
|
||||
long absMillis = Math.abs(millis);
|
||||
long hours = TimeUnit.MILLISECONDS.toHours(absMillis);
|
||||
long minutes = TimeUnit.MILLISECONDS.toMinutes(absMillis) % 60;
|
||||
long seconds = TimeUnit.MILLISECONDS.toSeconds(absMillis) % 60;
|
||||
|
||||
return String.format("%d小时 %d分钟 %d秒", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算指定毫秒数的持续时间,返回时分秒格式的字符串
|
||||
* 仅显示非零单位
|
||||
*
|
||||
* @param millis 毫秒数
|
||||
* @return 时分秒格式的持续时间字符串,仅显示非零单位
|
||||
*/
|
||||
public static String getDurationFromMillisPretty(long millis) {
|
||||
long absMillis = Math.abs(millis);
|
||||
long hours = TimeUnit.MILLISECONDS.toHours(absMillis);
|
||||
long minutes = TimeUnit.MILLISECONDS.toMinutes(absMillis) % 60;
|
||||
long seconds = TimeUnit.MILLISECONDS.toSeconds(absMillis) % 60;
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
if (hours > 0) {
|
||||
result.append(hours).append("小时 ");
|
||||
}
|
||||
if (minutes > 0) {
|
||||
result.append(minutes).append("分钟 ");
|
||||
}
|
||||
if (seconds > 0 || result.length() == 0) {
|
||||
result.append(seconds).append("秒");
|
||||
}
|
||||
|
||||
return result.toString().trim();
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,8 @@ package com.fuyuanshen.equipment.domain;
|
||||
|
||||
import com.fuyuanshen.common.tenant.core.TenantEntity;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import io.github.linpeilie.annotations.AutoMapping;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@ -100,4 +102,12 @@ public class DeviceAlarm extends TenantEntity {
|
||||
private Long treatmentState;
|
||||
|
||||
|
||||
/**
|
||||
* 设备IMEI
|
||||
* device_imei
|
||||
*/
|
||||
@Schema(title = "设备IMEI")
|
||||
@AutoMapping(target = "deviceImei")
|
||||
private String deviceImei;
|
||||
|
||||
}
|
||||
|
||||
@ -52,12 +52,12 @@ public class DeviceFenceAccessRecord extends BaseEntity {
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
private Long latitude;
|
||||
private Double latitude;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
private Long longitude;
|
||||
private Double longitude;
|
||||
|
||||
/**
|
||||
* 定位精度
|
||||
|
||||
@ -59,8 +59,8 @@ public class DeviceType extends TenantEntity {
|
||||
@Schema(title = "联网方式", example = "0:无;1:4G;2:WIFI")
|
||||
private String networkWay;
|
||||
|
||||
@Schema(title = "通讯方式", example = "0:4G;1:蓝牙,2 4G&蓝牙")
|
||||
private String communicationMode;
|
||||
@Schema(title = "通讯方式", example = "通讯方式 0:4G;1:蓝牙,2 4G&蓝牙")
|
||||
private Integer communicationMode;
|
||||
|
||||
/**
|
||||
* 创建人名称
|
||||
|
||||
@ -2,6 +2,7 @@ package com.fuyuanshen.equipment.domain.bo;
|
||||
|
||||
import com.fuyuanshen.common.core.validate.EditGroup;
|
||||
import com.fuyuanshen.common.mybatis.core.domain.BaseEntity;
|
||||
import com.fuyuanshen.common.tenant.core.TenantEntity;
|
||||
import com.fuyuanshen.equipment.domain.DeviceAlarm;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@ -19,7 +20,7 @@ import java.util.Date;
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = DeviceAlarm.class, reverseConvertGenerate = false)
|
||||
public class DeviceAlarmBo extends BaseEntity {
|
||||
public class DeviceAlarmBo extends TenantEntity {
|
||||
|
||||
/**
|
||||
* ID
|
||||
@ -35,6 +36,7 @@ public class DeviceAlarmBo extends BaseEntity {
|
||||
/**
|
||||
* 报警事项
|
||||
* device_action
|
||||
* 0-强制报警,1-撞击闯入,2-自动报警,3-电子围栏告警
|
||||
*/
|
||||
private Integer deviceAction;
|
||||
|
||||
@ -99,7 +101,7 @@ public class DeviceAlarmBo extends BaseEntity {
|
||||
/**
|
||||
* 报警持续时间
|
||||
*/
|
||||
private Long durationTime;
|
||||
private String durationTime;
|
||||
|
||||
/**
|
||||
* 报警查询时间
|
||||
|
||||
@ -74,6 +74,16 @@ public class DeviceFenceAccessRecordBo extends BaseEntity {
|
||||
@NotNull(message = "事件时间不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Date eventTime;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
private String beginTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 记录创建时间
|
||||
*/
|
||||
|
||||
@ -23,7 +23,7 @@ public class AppDeviceBo {
|
||||
private String deviceMac;
|
||||
|
||||
/**
|
||||
* 通讯方式 0:4G; 1:蓝牙
|
||||
* 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙
|
||||
*/
|
||||
@NotNull(message = "通讯方式不能为空", groups = { EditGroup.class })
|
||||
private Integer communicationMode;
|
||||
|
||||
@ -21,13 +21,13 @@ public class DeviceTypeForm {
|
||||
private Boolean isSupportBle;
|
||||
|
||||
@Schema(title = "定位方式", example = "0:无;1:GPS;2:基站;3:wifi;4:北斗")
|
||||
private String locateMode;
|
||||
private Integer locateMode;
|
||||
|
||||
@Schema(title = "联网方式", example = "0:无;1:4G;2:WIFI")
|
||||
private String networkWay;
|
||||
private Integer networkWay;
|
||||
|
||||
@Schema(title = "通讯方式", example = "0:4G;1:蓝牙")
|
||||
private String communicationMode;
|
||||
@Schema(title = "通讯方式", example = "通讯方式 0:4G;1:蓝牙,2 4G&蓝牙")
|
||||
private Integer communicationMode;
|
||||
|
||||
/**
|
||||
* 型号字典用于APP页面跳转
|
||||
|
||||
@ -59,7 +59,7 @@ public class APPDeviceQueryCriteria1 {
|
||||
@Schema(name = "租户ID")
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(name = "通讯方式", example = "0:4G;1:蓝牙")
|
||||
@Schema(name = "通讯方式", example = "通讯方式 0:4G;1:蓝牙,2 4G&蓝牙")
|
||||
private Integer communicationMode;
|
||||
|
||||
}
|
||||
|
||||
@ -82,9 +82,10 @@ public class DeviceQueryCriteria extends BaseEntity {
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 通讯方式 0:4G;1:蓝牙
|
||||
* 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙
|
||||
* communication_mode
|
||||
*/
|
||||
@Schema(title = "通讯方式", example = "0:4G;1:蓝牙,2 4G&蓝牙")
|
||||
private Integer communicationMode;
|
||||
|
||||
/* app绑定用户id */
|
||||
|
||||
@ -26,7 +26,7 @@ public class AppDeviceVo implements Serializable {
|
||||
private String deviceMac;
|
||||
|
||||
/**
|
||||
* 通讯方式 0:4G;1:蓝牙
|
||||
* 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙
|
||||
*/
|
||||
private Integer communicationMode;
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import com.fuyuanshen.common.excel.annotation.ExcelDictFormat;
|
||||
import com.fuyuanshen.common.excel.convert.ExcelDictConvert;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
@ -134,4 +135,5 @@ public class DeviceAlarmVo implements Serializable {
|
||||
@Schema(name = "设备图片")
|
||||
private String devicePic;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ public class WebDeviceVo implements Serializable {
|
||||
private String deviceMac;
|
||||
|
||||
/**
|
||||
* 通讯方式 0:4G;1:蓝牙
|
||||
* 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙
|
||||
*/
|
||||
private Integer communicationMode;
|
||||
|
||||
|
||||
@ -25,4 +25,13 @@ public interface DeviceAlarmMapper extends BaseMapperPlus<DeviceAlarm, DeviceAla
|
||||
*/
|
||||
Page<DeviceAlarmVo> selectVoPage( Page pageQuery,@Param("bo") DeviceAlarmBo bo);
|
||||
|
||||
/**
|
||||
* 根据设备IMEI查询最新的一条告警数据
|
||||
*
|
||||
* @param deviceImei 设备IMEI
|
||||
* @return 设备告警
|
||||
*/
|
||||
DeviceAlarmVo selectLatestByDeviceImei(@Param("deviceImei") String deviceImei);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -109,4 +109,12 @@ public interface DeviceMapper extends BaseMapper<Device> {
|
||||
int getUsageDataForMonth(@Param("deviceId") Long deviceId,
|
||||
@Param("year") int year,
|
||||
@Param("month") int month);
|
||||
|
||||
/**
|
||||
* 根据设备IMEI查询设备
|
||||
*
|
||||
* @param deviceImei 设备IMEI
|
||||
* @return 设备信息
|
||||
*/
|
||||
Device selectDeviceByImei(@Param("deviceImei") String deviceImei);
|
||||
}
|
||||
@ -144,4 +144,12 @@ public interface DeviceService extends IService<Device> {
|
||||
* @return
|
||||
*/
|
||||
List<Map<String, Object>> getEquipmentUsageData(Long deviceTypeId, Integer range);
|
||||
|
||||
/**
|
||||
* 根据设备IMEI查询设备
|
||||
*
|
||||
* @param deviceImei 设备IMEI
|
||||
* @return 设备信息
|
||||
*/
|
||||
Device selectDeviceByImei(String deviceImei);
|
||||
}
|
||||
@ -65,4 +65,14 @@ public interface IDeviceAlarmService {
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 根据设备IMEI查询最新的一条告警数据
|
||||
*
|
||||
* @param deviceImei 设备IMEI
|
||||
* @return 设备告警
|
||||
*/
|
||||
DeviceAlarmVo queryLatestByDeviceImei(String deviceImei);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.fuyuanshen.equipment.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.fuyuanshen.common.core.utils.MapstructUtils;
|
||||
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
|
||||
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
|
||||
@ -102,11 +103,13 @@ public class DeviceAlarmServiceImpl implements IDeviceAlarmService {
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(DeviceAlarmBo bo) {
|
||||
DeviceAlarm add = MapstructUtils.convert(bo, DeviceAlarm.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
DeviceAlarm deviceAlarm = new DeviceAlarm();
|
||||
// DeviceAlarm add = MapstructUtils.convert(bo, DeviceAlarm.class);
|
||||
BeanUtil.copyProperties(bo, deviceAlarm);
|
||||
validEntityBeforeSave(deviceAlarm);
|
||||
boolean flag = baseMapper.insert(deviceAlarm) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
bo.setId(deviceAlarm.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
@ -145,4 +148,17 @@ public class DeviceAlarmServiceImpl implements IDeviceAlarmService {
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据设备IMEI查询最新的一条告警数据
|
||||
*
|
||||
* @param deviceImei 设备IMEI
|
||||
* @return 设备告警
|
||||
*/
|
||||
@Override
|
||||
public DeviceAlarmVo queryLatestByDeviceImei(String deviceImei) {
|
||||
return baseMapper.selectLatestByDeviceImei(deviceImei);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@ public class DeviceFenceAccessRecordServiceImpl implements IDeviceFenceAccessRec
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询符合条件的围栏进出记录列表
|
||||
*
|
||||
@ -70,6 +71,7 @@ public class DeviceFenceAccessRecordServiceImpl implements IDeviceFenceAccessRec
|
||||
return baseMapper.selectVoPageWithFenceAndDeviceName(lqw);
|
||||
}
|
||||
|
||||
|
||||
private LambdaQueryWrapper<DeviceFenceAccessRecord> buildQueryWrapper(DeviceFenceAccessRecordBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<DeviceFenceAccessRecord> lqw = Wrappers.lambdaQuery();
|
||||
@ -86,6 +88,7 @@ public class DeviceFenceAccessRecordServiceImpl implements IDeviceFenceAccessRec
|
||||
return lqw;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新增围栏进出记录
|
||||
*
|
||||
|
||||
@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.fuyuanshen.equipment.domain.DeviceGeoFence;
|
||||
import com.fuyuanshen.equipment.domain.bo.DeviceFenceAccessRecordBo;
|
||||
import com.fuyuanshen.equipment.domain.bo.DeviceFenceStatusBo;
|
||||
import com.fuyuanshen.equipment.domain.bo.DeviceGeoFenceBo;
|
||||
import com.fuyuanshen.equipment.domain.dto.FenceCheckResponse;
|
||||
@ -16,6 +17,7 @@ import com.fuyuanshen.equipment.domain.query.FenceCheckRequest;
|
||||
import com.fuyuanshen.equipment.domain.vo.DeviceFenceStatusVo;
|
||||
import com.fuyuanshen.equipment.domain.vo.DeviceGeoFenceVo;
|
||||
import com.fuyuanshen.equipment.mapper.DeviceGeoFenceMapper;
|
||||
import com.fuyuanshen.equipment.service.IDeviceFenceAccessRecordService;
|
||||
import com.fuyuanshen.equipment.service.IDeviceFenceStatusService;
|
||||
import com.fuyuanshen.equipment.service.IDeviceGeoFenceService;
|
||||
import com.fuyuanshen.equipment.utils.map.GeoFenceChecker;
|
||||
@ -41,6 +43,8 @@ public class DeviceGeoFenceServiceImpl implements IDeviceGeoFenceService {
|
||||
|
||||
private final IDeviceFenceStatusService fenceStatusService; // 添加此行
|
||||
|
||||
private final IDeviceFenceAccessRecordService fenceAccessRecordService; // 添加此行
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -96,6 +100,7 @@ public class DeviceGeoFenceServiceImpl implements IDeviceGeoFenceService {
|
||||
return lqw;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新增电子围栏
|
||||
*
|
||||
@ -213,9 +218,9 @@ public class DeviceGeoFenceServiceImpl implements IDeviceGeoFenceService {
|
||||
DeviceFenceStatusVo latestStatus = fenceStatusService.getLatestStatusByDeviceAndFence(
|
||||
request.getDeviceId(), fence.getId());
|
||||
|
||||
// 判断设备与围栏的关系变化
|
||||
Long previousStatus = latestStatus != null ? latestStatus.getStatus() : 0L; // 默认在围栏外
|
||||
Long currentStatus = pointInFence ? 1L : 0L; // 当前状态:1-在围栏内,0-在围栏外
|
||||
// 判断设备与围栏的关系变化 1=进入围栏,2=离开围栏
|
||||
Long previousStatus = latestStatus != null ? latestStatus.getStatus() : 2L; // 默认在围栏外
|
||||
Long currentStatus = pointInFence ? 1L : 2L; // 当前状态:1-在围栏内,2-在围栏外
|
||||
|
||||
// 如果状态发生变化,则记录
|
||||
if (!previousStatus.equals(currentStatus)) {
|
||||
@ -229,6 +234,17 @@ public class DeviceGeoFenceServiceImpl implements IDeviceGeoFenceService {
|
||||
// 保存状态记录
|
||||
fenceStatusService.insertByBo(newStatus);
|
||||
|
||||
// 添加围栏进出记录
|
||||
DeviceFenceAccessRecordBo recordBo = new DeviceFenceAccessRecordBo();
|
||||
recordBo.setDeviceId(request.getDeviceId());
|
||||
recordBo.setFenceId(fence.getId());
|
||||
recordBo.setLatitude(request.getLatitude());
|
||||
recordBo.setLongitude(request.getLongitude());
|
||||
recordBo.setEventTime(new Date());
|
||||
// 1表示进入围栏,2表示离开围栏
|
||||
recordBo.setEventType(currentStatus);
|
||||
fenceAccessRecordService.insertByBo(recordBo);
|
||||
|
||||
// 根据状态变化更新响应
|
||||
if (currentStatus == 1L) {
|
||||
// 设备进入围栏
|
||||
|
||||
@ -661,4 +661,9 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Device selectDeviceByImei(String deviceImei) {
|
||||
return baseMapper.selectDeviceByImei(deviceImei);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
<!-- 查询设备告警列表 -->
|
||||
<select id="selectVoPage" resultType="com.fuyuanshen.equipment.domain.vo.DeviceAlarmVo">
|
||||
select *, d.device_mac as deviceMac, d.device_imei as deviceImei,
|
||||
select *, d.device_mac as deviceMac, d.device_imei as deviceImei,d.device_name as deviceName,
|
||||
d.type_name as deviceTypeName, d.device_pic as devicePic
|
||||
from device_alarm da
|
||||
left join device d on da.device_id = d.id
|
||||
@ -30,4 +30,20 @@
|
||||
</where>
|
||||
</select>
|
||||
|
||||
|
||||
<!-- 根据设备IMEI查询最新的一条告警数据 -->
|
||||
<select id="selectLatestByDeviceImei" resultType="com.fuyuanshen.equipment.domain.vo.DeviceAlarmVo">
|
||||
select *, d.device_mac as deviceMac, d.device_imei as deviceImei,
|
||||
d.type_name as deviceTypeName, d.device_pic as devicePic
|
||||
from device_alarm da
|
||||
left join device d on da.device_id = d.id
|
||||
left join device_type dt on dt.id = da.device_type
|
||||
<where>
|
||||
da.device_imei = #{deviceImei}
|
||||
</where>
|
||||
order by da.create_time desc
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@ -4,11 +4,10 @@
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.fuyuanshen.equipment.mapper.DeviceFenceAccessRecordMapper">
|
||||
|
||||
<!-- 分页查询围栏进出记录列表 -->
|
||||
<!-- 修改后的分页查询围栏进出记录列表 -->
|
||||
<select id="selectVoPageWithFenceAndDeviceName"
|
||||
resultType="com.fuyuanshen.equipment.domain.vo.DeviceFenceAccessRecordVo">
|
||||
SELECT
|
||||
r.id,
|
||||
SELECT r.id,
|
||||
r.fence_id,
|
||||
f.name AS fence_name,
|
||||
r.device_id,
|
||||
@ -23,9 +22,7 @@
|
||||
FROM device_fence_access_record r
|
||||
LEFT JOIN device_geo_fence f ON r.fence_id = f.id
|
||||
LEFT JOIN device d ON r.device_id = d.id
|
||||
<where>
|
||||
${ew.customSqlSegment}
|
||||
</where>
|
||||
ORDER BY r.id ASC
|
||||
</select>
|
||||
|
||||
|
||||
@ -423,4 +423,9 @@
|
||||
AND MONTH (dl.create_time) = #{month}
|
||||
</select>
|
||||
|
||||
<!-- 根据设备IMEI查询设备 -->
|
||||
<select id="selectDeviceByImei" resultType="com.fuyuanshen.equipment.domain.Device">
|
||||
SELECT * FROM device WHERE device_imei = #{deviceImei}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user