处理 设备在线 发消息

This commit is contained in:
gong
2025-11-24 16:37:56 +08:00
parent e76a85b521
commit 7146128b4c
15 changed files with 156 additions and 38 deletions

View File

@@ -24,6 +24,13 @@
<artifactId>cash-common-log</artifactId> <artifactId>cash-common-log</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.czg</groupId>
<artifactId>cash-common-mq</artifactId>
<version>1.0.0</version>
</dependency>
<dependency> <dependency>
<groupId>com.czg</groupId> <groupId>com.czg</groupId>
<artifactId>system-service</artifactId> <artifactId>system-service</artifactId>

View File

@@ -1,6 +1,5 @@
package com.czg.controller.admin; package com.czg.controller.admin;
import com.czg.annotation.SaAdminCheckPermission;
import com.czg.resp.CzgResult; import com.czg.resp.CzgResult;
import com.czg.system.dto.SysDevicesDTO; import com.czg.system.dto.SysDevicesDTO;
import com.czg.system.dto.SysDevicesPageDTO; import com.czg.system.dto.SysDevicesPageDTO;
@@ -29,7 +28,7 @@ public class SysDeviceController {
* 新增设备 * 新增设备
*/ */
@PostMapping @PostMapping
@SaAdminCheckPermission(value = "devices:add", name = "新增设备") // @SaAdminCheckPermission(value = "devices:add", name = "新增设备")
public CzgResult<Long> addDevice(@RequestBody @Validated(InsertGroup.class) SysDevicesDTO param) { public CzgResult<Long> addDevice(@RequestBody @Validated(InsertGroup.class) SysDevicesDTO param) {
return CzgResult.success(sysDevicesService.addDevice(param)); return CzgResult.success(sysDevicesService.addDevice(param));
} }
@@ -38,7 +37,7 @@ public class SysDeviceController {
* 修改设备 * 修改设备
*/ */
@PutMapping @PutMapping
@SaAdminCheckPermission(value = "devices:update", name = "修改设备") // @SaAdminCheckPermission(value = "devices:update", name = "修改设备")
public CzgResult<Long> updateDevice(@RequestBody @Validated(UpdateGroup.class) SysDevicesDTO param) { public CzgResult<Long> updateDevice(@RequestBody @Validated(UpdateGroup.class) SysDevicesDTO param) {
return CzgResult.success(sysDevicesService.updateDevice(param)); return CzgResult.success(sysDevicesService.updateDevice(param));
} }
@@ -47,7 +46,7 @@ public class SysDeviceController {
* 删除设备 * 删除设备
*/ */
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
@SaAdminCheckPermission(value = "devices:delete", name = "删除设备") // @SaAdminCheckPermission(value = "devices:delete", name = "删除设备")
public CzgResult<Long> deleteDevice(@PathVariable Long id) { public CzgResult<Long> deleteDevice(@PathVariable Long id) {
return CzgResult.success(sysDevicesService.deleteDevice(id)); return CzgResult.success(sysDevicesService.deleteDevice(id));
} }
@@ -56,8 +55,8 @@ public class SysDeviceController {
* 查询设备分页 * 查询设备分页
*/ */
@GetMapping("page") @GetMapping("page")
@SaAdminCheckPermission(value = "devices:page", name = "查询设备分页") // @SaAdminCheckPermission(value = "devices:page", name = "查询设备分页")
public CzgResult<Page<SysDevicesDTO>> queryDevice(SysDevicesPageDTO param) { public CzgResult<Page<SysDevicesDTO>> queryDevice(SysDevicesPageDTO param) {
return CzgResult.success(sysDevicesService.queryDevice(param)); return CzgResult.success(sysDevicesService.queryDevicePage(param));
} }
} }

View File

@@ -41,6 +41,7 @@ public class MqttServerHandler extends ChannelInboundHandlerAdapter {
// 并发安全的 Map缓存 Channel连接→ clientId设备唯一标识的映射 // 并发安全的 Map缓存 Channel连接→ clientId设备唯一标识的映射
private final Map<Channel, String> channelClientIdMap = new ConcurrentHashMap<>(); private final Map<Channel, String> channelClientIdMap = new ConcurrentHashMap<>();
private final Map<String, Channel> clientIdChannelMap = new ConcurrentHashMap<>();
// 注入共享的订阅关系管理器(单例) // 注入共享的订阅关系管理器(单例)
private final MqttSubscriptionManager subscriptionManager; private final MqttSubscriptionManager subscriptionManager;
@@ -50,6 +51,7 @@ public class MqttServerHandler extends ChannelInboundHandlerAdapter {
// 创建一个调度线程池(可以全局复用) // 创建一个调度线程池(可以全局复用)
private static final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(4); private static final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(4);
// 构造函数(接收共享组件) // 构造函数(接收共享组件)
public MqttServerHandler(MqttSubscriptionManager subscriptionManager, DeviceStatusManager deviceStatusManager) { public MqttServerHandler(MqttSubscriptionManager subscriptionManager, DeviceStatusManager deviceStatusManager) {
this.subscriptionManager = subscriptionManager; this.subscriptionManager = subscriptionManager;
@@ -66,18 +68,20 @@ public class MqttServerHandler extends ChannelInboundHandlerAdapter {
@Override @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception { public void channelInactive(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel(); Channel channel = ctx.channel();
// 通过 Channel 找 clientId
String clientId = channelClientIdMap.get(channel); String clientId = channelClientIdMap.get(channel);
if (clientId != null) { if (clientId != null) {
// 标记离线 // 移除两个映射
deviceStatusManager.markDeviceOffline(clientId);
// 清理映射
channelClientIdMap.remove(channel); channelClientIdMap.remove(channel);
// 清理订阅(原有逻辑) clientIdChannelMap.remove(clientId);
subscriptionManager.removeAllSubscriptions(channel);
// 标记设备离线
deviceStatusManager.markDeviceOffline(clientId);
log.info("设备断开连接已标记离线clientId={}, 地址={}", clientId, channel.remoteAddress());
} else {
log.warn("未知 Channel 断开:{}", channel.remoteAddress());
} }
log.info("客户端断开连接:{}", ctx.channel().remoteAddress());
super.channelInactive(ctx); super.channelInactive(ctx);
} }
@@ -167,29 +171,39 @@ public class MqttServerHandler extends ChannelInboundHandlerAdapter {
*/ */
private void handleConnect(ChannelHandlerContext ctx, MqttConnectMessage msg) { private void handleConnect(ChannelHandlerContext ctx, MqttConnectMessage msg) {
MqttConnectPayload payload = msg.payload(); MqttConnectPayload payload = msg.payload();
// 设备唯一标识(客户端必须携带)
String clientId = payload.clientIdentifier(); String clientId = payload.clientIdentifier();
// 设备地址
String remoteAddress = ctx.channel().remoteAddress().toString(); String remoteAddress = ctx.channel().remoteAddress().toString();
// 1. 校验 clientId非空MQTT3.1.1 要求)
if (clientId == null || clientId.isEmpty()) { if (clientId == null || clientId.isEmpty()) {
sendConnectAck(ctx, MqttConnectReturnCode.CONNECTION_REFUSED_CLIENT_IDENTIFIER_NOT_VALID); sendConnectAck(ctx, MqttConnectReturnCode.CONNECTION_REFUSED_CLIENT_IDENTIFIER_NOT_VALID);
log.error("设备连接拒绝clientId 为空,地址={}", remoteAddress); log.error("设备连接拒绝clientId 为空,地址={}", remoteAddress);
return; return;
} }
// 2. 缓存 Channel ↔ clientId 映射(核心:后续通过 Channel 找设备) // 🔒 检查是否已经存在该 clientId 的连接
if (clientIdChannelMap.containsKey(clientId)) {
Channel existingChannel = clientIdChannelMap.get(clientId);
log.warn("设备重复连接已拒绝clientId={}, 原连接={}, 新连接={}",
clientId, existingChannel.remoteAddress(), ctx.channel().remoteAddress());
// 返回 "服务器不可用" 或 "已存在连接" 错误码,拒绝新连接
sendConnectAck(ctx, MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE);
ctx.close(); // 主动关闭多余的连接
return;
}
// ✅ 当前连接是合法的、唯一的,继续处理
Channel channel = ctx.channel(); Channel channel = ctx.channel();
channelClientIdMap.put(channel, clientId); channelClientIdMap.put(channel, clientId);
// 维护反向映射
clientIdChannelMap.put(clientId, channel);
// 3. 注册设备状态(标记为在线) // 注册设备状态
deviceStatusManager.registerDevice(clientId, remoteAddress); deviceStatusManager.registerDevice(clientId, remoteAddress);
// 4. 响应连接成功(原有逻辑) // 回复 CONNACK
sendConnectAck(ctx, MqttConnectReturnCode.CONNECTION_ACCEPTED); sendConnectAck(ctx, MqttConnectReturnCode.CONNECTION_ACCEPTED);
log.info("设备连接成功clientId={}, 地址={}, 协议版本={}", log.info("设备连接成功clientId={}, 地址={}, 协议版本={}", clientId, remoteAddress, msg.variableHeader().version());
clientId, remoteAddress, msg.variableHeader().version());
} }
private void handlePublish(ChannelHandlerContext ctx, MqttPublishMessage msg) { private void handlePublish(ChannelHandlerContext ctx, MqttPublishMessage msg) {
@@ -211,12 +225,16 @@ public class MqttServerHandler extends ChannelInboundHandlerAdapter {
log.info("收到发布消息topic={}, QoS={}, 消息ID={}, 内容={}, 客户端={}", log.info("收到发布消息topic={}, QoS={}, 消息ID={}, 内容={}, 客户端={}",
topic, qosLevel.value(), messageId, content, ctx.channel().remoteAddress()); topic, qosLevel.value(), messageId, content, ctx.channel().remoteAddress());
// -------------------------- 核心新增:收到 con 主题消息,回复 7941610A 主题 -------------------------- // -------------------------- 收到 con 主题消息,回复 --------------------------
if ("con".equals(topic)) { if ("con".equals(topic)) {
// 延迟 2 秒执行 // 延迟 2 秒执行
SCHEDULER.schedule(() -> { SCHEDULER.schedule(() -> sendResponseToClient(ctx, "处理成功"), 2, TimeUnit.SECONDS);
sendResponseToClient(ctx, "微信到账,十二元"); // SCHEDULER.schedule(() -> deviceStatusManager.sendMqMsg(content), 0, TimeUnit.SECONDS);
}, 2, TimeUnit.SECONDS); try {
deviceStatusManager.sendMqMsg(content);
} catch (Exception e) {
e.printStackTrace();
}
} }
// 按QoS等级回复确认重点实现QoS2 // 按QoS等级回复确认重点实现QoS2

View File

@@ -1,5 +1,9 @@
package com.czg.mqtt.manager; package com.czg.mqtt.manager;
import com.alibaba.fastjson2.JSONObject;
import com.czg.config.RabbitPublisher;
import com.czg.system.service.SysDevicesService;
import jakarta.annotation.Resource;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
@@ -11,6 +15,7 @@ import java.util.concurrent.ConcurrentHashMap;
/** /**
* 设备在线状态管理器(单例) * 设备在线状态管理器(单例)
* 维护 clientId → 设备状态的映射,线程安全 * 维护 clientId → 设备状态的映射,线程安全
*
* @author yjjie * @author yjjie
* @date 2025/11/18 15:33 * @date 2025/11/18 15:33
*/ */
@@ -20,6 +25,12 @@ public class DeviceStatusManager {
// 并发安全的 Mapkey=clientId设备唯一标识value=设备状态 // 并发安全的 Mapkey=clientId设备唯一标识value=设备状态
private final Map<String, DeviceStatus> deviceStatusMap = new ConcurrentHashMap<>(); private final Map<String, DeviceStatus> deviceStatusMap = new ConcurrentHashMap<>();
@Resource
private SysDevicesService sysDevicesService;
@Resource
private RabbitPublisher rabbitPublisher;
/** /**
* 设备状态实体 * 设备状态实体
*/ */
@@ -46,7 +57,9 @@ public class DeviceStatusManager {
public void registerDevice(String clientId, String remoteAddress) { public void registerDevice(String clientId, String remoteAddress) {
DeviceStatus status = new DeviceStatus(clientId, remoteAddress); DeviceStatus status = new DeviceStatus(clientId, remoteAddress);
deviceStatusMap.put(clientId, status); deviceStatusMap.put(clientId, status);
System.out.printf("设备注册上线clientId=%s, 地址=%s%n", clientId, remoteAddress); log.info("设备注册上线clientId={}, 地址={}", clientId, remoteAddress);
sysDevicesService.updateDeviceOnlineStatus(clientId, 1);
} }
/** /**
@@ -58,8 +71,9 @@ public class DeviceStatusManager {
status.setLastPingTime(System.currentTimeMillis()); status.setLastPingTime(System.currentTimeMillis());
// 刷新为在线状态 // 刷新为在线状态
status.setOnline(true); status.setOnline(true);
System.out.printf("设备 Ping 刷新clientId=%s, 最后活跃时间=%d%n",
clientId, status.getLastPingTime()); log.info("设备上线clientId={}, 最后Ping时间={}", clientId, status.getLastPingTime());
sysDevicesService.updateDeviceOnlineStatus(clientId, 1);
} }
} }
@@ -71,8 +85,10 @@ public class DeviceStatusManager {
if (status != null) { if (status != null) {
status.setOnline(false); status.setOnline(false);
System.out.printf("设备离线clientId=%s%n", clientId); System.out.printf("设备离线clientId=%s%n", clientId);
// 可选:保留离线状态一段时间,或直接移除(根据业务需求) log.info("设备下线clientId={}, 最后Ping时间={}", clientId, status.getLastPingTime());
// deviceStatusMap.remove(clientId);
deviceStatusMap.remove(clientId);
sysDevicesService.updateDeviceOnlineStatus(clientId, 0);
} }
} }
@@ -83,6 +99,11 @@ public class DeviceStatusManager {
return deviceStatusMap.get(clientId); return deviceStatusMap.get(clientId);
} }
public void sendMqMsg(String content) {
JSONObject jsonObject = JSONObject.parseObject(content);
rabbitPublisher.sendOrderProductStatusMsg(jsonObject.getString("msg"));
}
/** /**
* 定时清理长时间离线的设备 * 定时清理长时间离线的设备
* offlineThresholdMs = 4 * 60 * 1000 = 14400000 毫秒 = 4分钟 * offlineThresholdMs = 4 * 60 * 1000 = 14400000 毫秒 = 4分钟

View File

@@ -26,6 +26,12 @@ spring:
server-addr: 121.40.109.122:8848 server-addr: 121.40.109.122:8848
namespace: 237e1905-0a66-4375-9bb6-a51c3c034aca namespace: 237e1905-0a66-4375-9bb6-a51c3c034aca
rabbitmq:
host: 121.40.109.122
port: 5672
username: chaozg
password: chaozg123
dubbo: dubbo:
application: application:
name: system-server name: system-server

View File

@@ -26,6 +26,12 @@ spring:
server-addr: 121.40.109.122:8848 server-addr: 121.40.109.122:8848
namespace: 237e1905-0a66-4375-9bb6-a51c3c034aca namespace: 237e1905-0a66-4375-9bb6-a51c3c034aca
rabbitmq:
host: 121.40.109.122
port: 5672
username: chaozg
password: chaozg123
dubbo: dubbo:
application: application:
name: system-server name: system-server

View File

@@ -26,6 +26,12 @@ spring:
server-addr: 121.40.109.122:8848 server-addr: 121.40.109.122:8848
namespace: 237e1905-0a66-4375-9bb6-a51c3c034aca namespace: 237e1905-0a66-4375-9bb6-a51c3c034aca
rabbitmq:
host: 121.40.109.122
port: 5672
username: chaozg
password: chaozg123
dubbo: dubbo:
application: application:
name: system-server name: system-server

View File

@@ -143,4 +143,14 @@ public class RabbitConfig {
public Binding bindingBirthdayGiftSmsExchange(Queue birthdayGiftSmsQueue, DirectExchange exchange) { public Binding bindingBirthdayGiftSmsExchange(Queue birthdayGiftSmsQueue, DirectExchange exchange) {
return BindingBuilder.bind(birthdayGiftSmsQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE); return BindingBuilder.bind(birthdayGiftSmsQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE);
} }
//------------------------------------------------------ 订单商品状态
@Bean
public Queue orderProductStatusQueue() {
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE, true);
}
@Bean
public Binding bindingOrderProductStatusExchange(Queue orderProductStatusQueue, DirectExchange exchange) {
return BindingBuilder.bind(orderProductStatusQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE);
}
} }

View File

@@ -19,6 +19,11 @@ public interface RabbitConstants {
public static final String CALL_TABLE_PRINT_QUEUE = "call.table.print.queue"; public static final String CALL_TABLE_PRINT_QUEUE = "call.table.print.queue";
public static final String PRODUCT_INFO_CHANGE_QUEUE = "product.info.change.queue"; public static final String PRODUCT_INFO_CHANGE_QUEUE = "product.info.change.queue";
/**
* 订单商品状态队列
*/
public static final String ORDER_PRODUCT_STATUS_QUEUE = "order.product.status.queue";
/** /**
* 1,2,applySmsTemp 模版审核 * 1,2,applySmsTemp 模版审核
* 1,2,sendMarkSms 发送营销短信 * 1,2,sendMarkSms 发送营销短信

View File

@@ -121,6 +121,13 @@ public class RabbitPublisher {
sendMsg(RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE, param); sendMsg(RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE, param);
} }
/**
* 订单商品状态消息
*/
public void sendOrderProductStatusMsg(String qrContent) {
sendMsg(RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE, qrContent);
}
private void sendMsg(String queue, String msg) { private void sendMsg(String queue, String msg) {
log.info("开始发送mq消息,exchange:{}, queue: {}, msg: {}", activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE, activeProfile + "-" + queue, msg); log.info("开始发送mq消息,exchange:{}, queue: {}, msg: {}", activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE, activeProfile + "-" + queue, msg);
rabbitTemplate.convertAndSend(activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE, activeProfile + "-" + queue, msg); rabbitTemplate.convertAndSend(activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE, activeProfile + "-" + queue, msg);

View File

@@ -59,7 +59,7 @@ public class SysDevicesDTO implements Serializable {
/** /**
* 在线状态0 离线1 在线 * 在线状态0 离线1 在线
*/ */
private Integer unlineStatus; private Integer onlineStatus;
/** /**
* 最后上线时间 * 最后上线时间

View File

@@ -29,7 +29,7 @@ public class SysDevicesPageDTO {
/** /**
* 在线状态0 离线1 在线 * 在线状态0 离线1 在线
*/ */
private Integer unlineStatus; private Integer onlineStatus;
/** /**
* 页码 * 页码

View File

@@ -2,6 +2,7 @@ package com.czg.system.entity;
import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@@ -32,7 +33,7 @@ public class SysDevices implements Serializable {
/** /**
* 主键 * 主键
*/ */
@Id @Id(keyType = KeyType.Auto)
private Long id; private Long id;
/** /**
@@ -53,7 +54,7 @@ public class SysDevices implements Serializable {
/** /**
* 在线状态0 离线1 在线 * 在线状态0 离线1 在线
*/ */
private Integer unlineStatus; private Integer onlineStatus;
/** /**
* 最后上线时间 * 最后上线时间

View File

@@ -20,5 +20,7 @@ public interface SysDevicesService extends IService<SysDevices> {
Long deleteDevice(Long id); Long deleteDevice(Long id);
Page<SysDevicesDTO> queryDevice(SysDevicesPageDTO reqDTO); Page<SysDevicesDTO> queryDevicePage(SysDevicesPageDTO reqDTO);
void updateDeviceOnlineStatus(String sn, Integer online);
} }

View File

@@ -8,17 +8,22 @@ import com.czg.system.dto.SysDevicesDTO;
import com.czg.system.dto.SysDevicesPageDTO; import com.czg.system.dto.SysDevicesPageDTO;
import com.czg.system.entity.SysDevices; import com.czg.system.entity.SysDevices;
import com.czg.system.service.SysDevicesService; import com.czg.system.service.SysDevicesService;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl; import com.mybatisflex.spring.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
/** /**
* 设备管理 服务层实现。 * 设备管理 服务层实现。
* *
* @author ww * @author ww
* @since 2025-11-24 * @since 2025-11-24
*/ */
@Slf4j
@Service @Service
public class SysDevicesServiceImpl extends ServiceImpl<SysDevicesMapper, SysDevices> implements SysDevicesService { public class SysDevicesServiceImpl extends ServiceImpl<SysDevicesMapper, SysDevices> implements SysDevicesService {
@@ -50,7 +55,7 @@ public class SysDevicesServiceImpl extends ServiceImpl<SysDevicesMapper, SysDevi
devices.setDeviceSn(reqDTO.getDeviceSn()); devices.setDeviceSn(reqDTO.getDeviceSn());
devices.setDeviceType(reqDTO.getDeviceType()); devices.setDeviceType(reqDTO.getDeviceType());
devices.setConnType(reqDTO.getConnType()); devices.setConnType(reqDTO.getConnType());
devices.setUnlineStatus(reqDTO.getUnlineStatus()); devices.setOnlineStatus(reqDTO.getOnlineStatus());
updateById(devices); updateById(devices);
return devices.getId(); return devices.getId();
@@ -68,7 +73,7 @@ public class SysDevicesServiceImpl extends ServiceImpl<SysDevicesMapper, SysDevi
} }
@Override @Override
public Page<SysDevicesDTO> queryDevice(SysDevicesPageDTO reqDTO) { public Page<SysDevicesDTO> queryDevicePage(SysDevicesPageDTO reqDTO) {
QueryWrapper wrapper = new QueryWrapper(); QueryWrapper wrapper = new QueryWrapper();
if (StrUtil.isNotBlank(reqDTO.getDeviceSn())) { if (StrUtil.isNotBlank(reqDTO.getDeviceSn())) {
wrapper.like(SysDevices::getDeviceSn, reqDTO.getDeviceSn()); wrapper.like(SysDevices::getDeviceSn, reqDTO.getDeviceSn());
@@ -79,7 +84,32 @@ public class SysDevicesServiceImpl extends ServiceImpl<SysDevicesMapper, SysDevi
if (StrUtil.isNotBlank(reqDTO.getConnType())) { if (StrUtil.isNotBlank(reqDTO.getConnType())) {
wrapper.eq(SysDevices::getConnType, reqDTO.getConnType()); wrapper.eq(SysDevices::getConnType, reqDTO.getConnType());
} }
if (reqDTO.getOnlineStatus() != null) {
wrapper.eq(SysDevices::getOnlineStatus, reqDTO.getOnlineStatus());
}
return page(Page.of(reqDTO.getPage(), reqDTO.getSize()), wrapper).map(devices -> BeanUtil.toBean(devices, SysDevicesDTO.class)); wrapper.orderBy(SysDevices::getOnlineStatus, false);
wrapper.orderBy(SysDevices::getId, false);
return page(PageUtil.buildPage(), wrapper).map(devices -> BeanUtil.toBean(devices, SysDevicesDTO.class));
}
@Override
public void updateDeviceOnlineStatus(String sn, Integer online) {
SysDevices devices = getOne(query().eq(SysDevices::getDeviceSn, sn));
if (devices == null) {
log.info("心跳设备不存在sn={}", sn);
return;
}
if (online == 0) {
devices.setOnlineStatus(0);
devices.setOfflineTime(LocalDateTime.now());
} else {
devices.setOnlineStatus(1);
devices.setLastUnlineTime(LocalDateTime.now());
devices.setOfflineTime(null);
}
updateById(devices);
} }
} }