处理 设备在线 发消息
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 {
|
|||||||
// 并发安全的 Map:key=clientId(设备唯一标识),value=设备状态
|
// 并发安全的 Map:key=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分钟
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 发送营销短信
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class SysDevicesDTO implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 在线状态:0 离线,1 在线
|
* 在线状态:0 离线,1 在线
|
||||||
*/
|
*/
|
||||||
private Integer unlineStatus;
|
private Integer onlineStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最后上线时间
|
* 最后上线时间
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class SysDevicesPageDTO {
|
|||||||
/**
|
/**
|
||||||
* 在线状态:0 离线,1 在线
|
* 在线状态:0 离线,1 在线
|
||||||
*/
|
*/
|
||||||
private Integer unlineStatus;
|
private Integer onlineStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页码
|
* 页码
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最后上线时间
|
* 最后上线时间
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user