diff --git a/cn-universal-admin/pom.xml b/cn-universal-admin/pom.xml
index 6bb577f929d92862cd10331f5291a029b22c4a92..4e137091732b474e9e8ba8f7c2e4b3f15271a989 100644
--- a/cn-universal-admin/pom.xml
+++ b/cn-universal-admin/pom.xml
@@ -114,7 +114,12 @@
${project.version}
compile
-
+
+ cn.universal.iot
+ cn-universal-notice
+ ${project.version}
+ compile
+
\ No newline at end of file
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/network/doc/NetworkApiDoc.java b/cn-universal-admin/src/main/java/cn/universal/admin/network/doc/NetworkApiDoc.java
deleted file mode 100644
index 8066702996e173570cfffba6721dae6b48dec9cd..0000000000000000000000000000000000000000
--- a/cn-universal-admin/src/main/java/cn/universal/admin/network/doc/NetworkApiDoc.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *
- * Copyright (c) 2025, IoT-Universal. All Rights Reserved.
- *
- * @Description: 本文件由 Aleo 开发并拥有版权,未经授权严禁擅自商用、复制或传播。
- * @Author: Aleo
- * @Email: wo8335224@gmail.com
- * @Wechat: outlookFil
- *
- *
- */
-
-package cn.universal.admin.network.doc;
-
-/**
- * 网络组件API文档
- *
- * @version 1.0 @Author Aleo
- * @since 2025/1/20
- */
-public class NetworkApiDoc {
-
- /**
- * 网络组件管理API文档
- *
- *
基础路径: /admin/network
- *
- *
1. 查询网络组件列表 GET /admin/network/list 参数: - page: 页码 (可选,默认1) - size: 每页大小 (可选,默认10) - type:
- * 网络类型 (可选,单个类型,如 TCP_CLIENT) - types: 网络类型列表 (可选,多个类型,如 ["MQTT_CLIENT", "MQTT_SERVER"]) - name:
- * 网络组件名称 (可选,模糊查询) - productKey: 产品Key (可选) - state: 状态 (可选,true/false) - unionId: 唯一标识 (可选)
- *
- *
2. 查询网络组件列表(支持多个类型) GET /admin/network/list/multi-type 参数: - page: 页码 (可选,默认1) - size: 每页大小
- * (可选,默认10) - type: 网络类型 (可选,支持逗号分隔多个类型,如 "MQTT_CLIENT,MQTT_SERVER") - name: 网络组件名称 (可选,模糊查询) -
- * productKey: 产品Key (可选) - state: 状态 (可选,true/false) - unionId: 唯一标识 (可选)
- *
- *
3. 根据ID查询网络组件 GET /admin/network/{id} 参数: - id: 网络组件ID (路径参数)
- *
- *
4. 新增网络组件 POST /admin/network 请求体: { "type": "TCP_SERVER", "unionId": "unique_id",
- * "productKey": "product_key", "name": "网络组件名称", "description": "详细描述", "state": false,
- * "configuration": "{\"host\":\"0.0.0.0\",\"port\":6372,\"ssl\":false}", "createUser": "admin" }
- *
- *
5. 修改网络组件 PUT /admin/network 请求体: { "id": 1, "type": "TCP_SERVER", "unionId": "unique_id",
- * "productKey": "product_key", "name": "网络组件名称", "description": "详细描述", "state": false,
- * "configuration": "{\"host\":\"0.0.0.0\",\"port\":6372,\"ssl\":false}" }
- *
- *
6. 删除网络组件 DELETE /admin/network/{id} 参数: - id: 网络组件ID (路径参数)
- *
- *
7. 批量删除网络组件 DELETE /admin/network/batch/{ids} 参数: - ids: 网络组件ID数组 (路径参数,逗号分隔)
- *
- *
8. 启动网络组件 POST /admin/network/start/{id} 参数: - id: 网络组件ID (路径参数)
- *
- *
9. 停止网络组件 POST /admin/network/stop/{id} 参数: - id: 网络组件ID (路径参数)
- *
- *
10. 重启网络组件 POST /admin/network/restart/{id} 参数: - id: 网络组件ID (路径参数)
- *
- *
11. 获取网络类型列表 GET /admin/network/types
- *
- *
12. 验证网络组件配置 POST /admin/network/validate 请求体: { "type": "TCP_SERVER", "unionId":
- * "unique_id", "name": "网络组件名称", "configuration":
- * "{\"host\":\"0.0.0.0\",\"port\":6372,\"ssl\":false}" }
- *
- *
响应格式: { "code": 200, "msg": "操作成功", "data": { // 具体数据 } }
- *
- *
网络类型说明: - TCP_CLIENT: TCP客户端 - TCP_SERVER: TCP服务端 - MQTT_CLIENT: MQTT客户端 - MQTT_SERVER:
- * MQTT服务端
- *
- *
配置示例:
- *
- *
TCP_SERVER配置: { "allIdleTime": 0, "allowInsert": false, "alwaysPreDecode": false,
- * "decoderType": "STRING", "host": "0.0.0.0", "idleInterval": 0, "onlyCache": false,
- * "parserConfiguration": { "byteOrderLittle": true, "delimited": "]", "delimitedMaxlength": 1024,
- * "failFast": true }, "parserType": "DELIMITED", "port": 6372, "productKey":
- * "630477f1cd68445d90b04653", "readerIdleTime": 360, "readTimeout": 0, "sendTimeout": 0, "ssl":
- * false, "writerIdleTime": 0 }
- *
- *
MQTT_SERVER配置: { "autoReconnect": true, "cleanSession": true, "clientIdPrefix": "univ_cli_",
- * "defaultQos": 1, "enabled": true, "host": "tcp://125.210.48.96:1883", "id":
- * "6863896d75386b5c1e7e908c", "keepAliveInterval": 60, "password": "univiot@2025!", "productKey":
- * "local", "ssl": false, "subscribeTopics": "$univ_cli/up/property/+/+", "username": "univ_cli",
- * "connectTimeout": 30 }
- */
-}
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/network/service/INetworkService.java b/cn-universal-admin/src/main/java/cn/universal/admin/network/service/INetworkService.java
index 08dbe55cd0405ce1fc03d9da8ac688650785bf47..f91ba2cf2f1a77ef039b8e27a4f889bff4645060 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/network/service/INetworkService.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/network/service/INetworkService.java
@@ -29,26 +29,16 @@ import java.util.List;
*/
public interface INetworkService {
- boolean start(String productKey);
-
- boolean stop(String productKey);
-
- Object get(String productKey);
-
boolean del(String productKey);
List selectNetworkList(NetworkBO bo);
- NetworkVO getDetail(Long id);
-
List queryMileSightList(NetworkBO bo);
R insertDevInstance(IoTDeviceBO devInstancebo);
R deleteDevInstanceByIds(String[] ids);
- void reloadTcpClient(String applicationId);
-
/**
* 查询网络组件列表
*
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/network/service/impl/NetworkServiceImpl.java b/cn-universal-admin/src/main/java/cn/universal/admin/network/service/impl/NetworkServiceImpl.java
index 5f4038c22ee6663b29e9554fc601ec0d430c6004..b3726ee2e3f29c78f54deb58efc98770b598b87e 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/network/service/impl/NetworkServiceImpl.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/network/service/impl/NetworkServiceImpl.java
@@ -12,6 +12,7 @@
package cn.universal.admin.network.service.impl;
+import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
@@ -25,12 +26,15 @@ import cn.universal.common.domain.R;
import cn.universal.common.enums.NetworkType;
import cn.universal.common.exception.IoTException;
import cn.universal.core.service.IoTDownlFactory;
+import cn.universal.dm.device.service.protocol.ProtocolClusterService;
+import cn.universal.dm.device.service.protocol.ProtocolServerManager;
import cn.universal.mqtt.protocol.third.ThirdMQTTServerManager;
import cn.universal.persistence.entity.IoTDevice;
import cn.universal.persistence.entity.IoTProduct;
import cn.universal.persistence.entity.IoTUser;
import cn.universal.persistence.entity.Network;
import cn.universal.persistence.entity.bo.IoTDeviceBO;
+import cn.universal.persistence.entity.bo.IoTProductBO;
import cn.universal.persistence.entity.bo.NetworkBO;
import cn.universal.persistence.entity.vo.IoTProductVO;
import cn.universal.persistence.entity.vo.NetworkVO;
@@ -49,6 +53,7 @@ import java.util.Map;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
@@ -63,11 +68,8 @@ import tk.mybatis.mapper.entity.Example;
@Service
public class NetworkServiceImpl implements INetworkService {
- @Autowired
- private NetworkMapper networkMapper;
-
@Resource
- private NetworkMapper netWorkMapper;
+ private NetworkMapper networkMapper;
@Resource
private IoTDeviceMapper ioTDeviceMapper;
@Resource
@@ -75,42 +77,31 @@ public class NetworkServiceImpl implements INetworkService {
@Resource
private IoTDeviceFenceRelMapper ioTDeviceFenceRelMapper;
-
+ // 直接注入 TCP 和 MQTT 服务
+ @Qualifier("tcpClusterService")
@Autowired(required = false)
- private ThirdMQTTServerManager mqttServerManager;
-
- @Override
- public boolean start(String productKey) {
-
- return true;
- }
+ private ProtocolClusterService tcpClusterService;
- @Override
- public boolean stop(String productKey) {
+ @Autowired(required = false)
+ private ProtocolServerManager tcpServerManager;
- return true;
- }
+ @Qualifier("udpClusterService")
+ @Autowired(required = false)
+ private ProtocolClusterService udpClusterService;
- @Override
- public Object get(String productKey) {
- return null;
- }
+ @Autowired(required = false)
+ private ThirdMQTTServerManager mqttServerManager;
@Override
public boolean del(String productKey) {
Example ex = new Example(Network.class);
ex.createCriteria().andEqualTo("productKey", productKey);
- return netWorkMapper.deleteByExample(ex) > 0;
+ return networkMapper.deleteByExample(ex) > 0;
}
@Override
public List selectNetworkList(NetworkBO bo) {
- return netWorkMapper.selectNetworkListV1(bo);
- }
-
- @Override
- public NetworkVO getDetail(Long id) {
- return netWorkMapper.selectById(id);
+ return networkMapper.selectNetworkListV1(bo);
}
@Override
@@ -182,10 +173,6 @@ public class NetworkServiceImpl implements INetworkService {
return R.ok("删除成功");
}
- @Override
- public void reloadTcpClient(String applicationId) {
- }
-
@Override
public List selectNetworkList(NetworkQuery query) {
// 验证类型参数
@@ -214,9 +201,32 @@ public class NetworkServiceImpl implements INetworkService {
String unionId = bo.getUnionId();
if (NetworkType.TCP_CLIENT.getId().equals(type) || NetworkType.TCP_SERVER.getId()
.equals(type)) {
+ if (tcpClusterService != null && tcpServerManager != null) {
+ Object serverInstance = tcpServerManager.getServerInstance(productKey);
+ if (serverInstance != null && tcpServerManager.isAlive(serverInstance)) {
+ bo.setStateName("已启动");
+ bo.setRunning(Boolean.TRUE);
+ } else {
+ bo.setStateName("未启动");
+ bo.setRunning(Boolean.FALSE);
+ }
+ } else {
+ bo.setStateName("未启动");
+ bo.setRunning(Boolean.FALSE);
+ }
+ // 查出哪些TCP-Server绑定了产品
+ if (NetworkType.TCP_SERVER.getId().equals(type)) {
+ IoTProductBO ioTProductBO = ioTProductMapper.selectTcpProductsUseNetwork(
+ bo.getProductKey());
+ bo.setBindTcpServerProductCount(ioTProductBO == null ? 0 : 1);
+ bo.setBindTcpServerProducts(ioTProductBO);
+ }
} else if (NetworkType.MQTT_CLIENT.getId().equals(type) || NetworkType.MQTT_SERVER.getId()
.equals(type)) {
+ List ioTProductBOS = ioTProductMapper.selectMqttProductsUseNetwork(unionId);
+ bo.setBindMqttServerProductCount(CollUtil.size(ioTProductBOS));
+ bo.setBindMqttServerProducts(ioTProductBOS);
if (mqttServerManager != null && mqttServerManager.isConnected(unionId)) {
bo.setStateName("已启动");
bo.setRunning(Boolean.TRUE);
@@ -224,6 +234,14 @@ public class NetworkServiceImpl implements INetworkService {
bo.setStateName("未启动");
bo.setRunning(Boolean.FALSE);
}
+ } else if (NetworkType.UDP.getId().equals(type)) {
+ if (udpClusterService != null && udpClusterService.isProductServerAlive(productKey)) {
+ bo.setStateName("已启动");
+ bo.setRunning(Boolean.TRUE);
+ } else {
+ bo.setStateName("未启动");
+ bo.setRunning(Boolean.FALSE);
+ }
} else {
bo.setStateName("未知");
bo.setRunning(Boolean.FALSE);
@@ -264,6 +282,9 @@ public class NetworkServiceImpl implements INetworkService {
case NetworkTypeConstants.MQTT_SERVER:
vo.setTypeName(NetworkType.MQTT_SERVER.getDescription());
break;
+ case NetworkTypeConstants.UDP:
+ vo.setTypeName(NetworkType.UDP.getDescription());
+ break;
default:
vo.setTypeName(network.getType());
}
@@ -275,7 +296,19 @@ public class NetworkServiceImpl implements INetworkService {
String unionId = network.getUnionId();
if (NetworkType.TCP_CLIENT.getId().equals(type) || NetworkType.TCP_SERVER.getId()
.equals(type)) {
- //TODO 开源版本无
+ if (tcpClusterService != null && tcpServerManager != null) {
+ Object serverInstance = tcpServerManager.getServerInstance(productKey);
+ if (serverInstance != null && tcpServerManager.isAlive(serverInstance)) {
+ vo.setStateName("已启动");
+ vo.setRunning(Boolean.TRUE);
+ } else {
+ vo.setStateName("未启动");
+ vo.setRunning(Boolean.FALSE);
+ }
+ } else {
+ vo.setStateName("未启动");
+ vo.setRunning(Boolean.FALSE);
+ }
} else if (NetworkType.MQTT_CLIENT.getId().equals(type) || NetworkType.MQTT_SERVER.getId()
.equals(type)) {
@@ -286,6 +319,14 @@ public class NetworkServiceImpl implements INetworkService {
vo.setStateName("未启动");
vo.setRunning(Boolean.FALSE);
}
+ } else if (NetworkType.UDP.getId().equals(type)) {
+ if (udpClusterService != null && udpClusterService.isProductServerAlive(productKey)) {
+ vo.setStateName("已启动");
+ vo.setRunning(Boolean.TRUE);
+ } else {
+ vo.setStateName("未启动");
+ vo.setRunning(Boolean.FALSE);
+ }
} else {
vo.setStateName("未知");
vo.setRunning(Boolean.FALSE);
@@ -347,11 +388,11 @@ public class NetworkServiceImpl implements INetworkService {
network.setUnionId(IdUtil.objectId());
network.setState(false);
- // 新增TCP_SERVER时,必须指定productKey,并且不能重复绑定
+ // 新增TCP_SERVER/UDP时,必须指定productKey,并且不能重复绑定
if (NetworkType.TCP_SERVER.getId().equals(network.getType()) || NetworkType.TCP_CLIENT.getId()
- .equals(network.getType())) {
+ .equals(network.getType()) || NetworkType.UDP.getId().equals(network.getType())) {
if (StrUtil.isBlank(network.getProductKey())) {
- throw new RuntimeException("TCP服务组件必须选择产品");
+ throw new RuntimeException("TCP/UDP服务组件必须选择产品");
}
network.setUnionId(network.getProductKey());
// 检查是否已被绑定
@@ -391,8 +432,8 @@ public class NetworkServiceImpl implements INetworkService {
}
String type = existNetwork.getType();
- if ((NetworkType.TCP_SERVER.getId().equals(type) || NetworkType.TCP_CLIENT.getId()
- .equals(type))) {
+ if ((NetworkType.TCP_SERVER.getId().equals(type) || NetworkType.TCP_CLIENT.getId().equals(type)
+ || NetworkType.UDP.getId().equals(type))) {
// 只有当unionId发生变化时,才做"已被产品关联且产品下有设备时禁止修改"的校验
String oldProductKey = existNetwork.getProductKey();
String networkProductKey = network.getProductKey();
@@ -423,9 +464,9 @@ public class NetworkServiceImpl implements INetworkService {
throw new RuntimeException("网络组件不存在");
}
String type = network.getType();
- // 只对TCP_SERVER和TCP_CLIENT做判断
- if (NetworkType.TCP_SERVER.getId().equals(type) || NetworkType.TCP_CLIENT.getId()
- .equals(type)) {
+ // 只对TCP_SERVER、TCP_CLIENT和UDP做判断
+ if (NetworkType.TCP_SERVER.getId().equals(type) || NetworkType.TCP_CLIENT.getId().equals(type)
+ || NetworkType.UDP.getId().equals(type)) {
// 查找是否有关联产品
String productKey = ioTProductMapper.findProductKeyByNetworkUnionId(network.getUnionId());
if (productKey != null) {
@@ -466,6 +507,11 @@ public class NetworkServiceImpl implements INetworkService {
if (StrUtil.isBlank(host)) {
throw new RuntimeException("MQTT网络组件启动/重启时host不能为空");
}
+ } else if (NetworkType.UDP.getId().equals(type)) {
+ Integer port = config.getInt("port");
+ if (port == null) {
+ throw new RuntimeException("UDP网络组件启动/重启时端口不能为空");
+ }
}
try {
// 根据网络类型调用相应的启动逻辑
@@ -527,6 +573,11 @@ public class NetworkServiceImpl implements INetworkService {
if (StrUtil.isBlank(host)) {
throw new RuntimeException("MQTT网络组件启动/重启时host不能为空");
}
+ } else if (NetworkType.UDP.getId().equals(type)) {
+ Integer port = config.getInt("port");
+ if (port == null) {
+ throw new RuntimeException("UDP网络组件启动/重启时端口不能为空");
+ }
}
try {
// 根据网络类型调用相应的重启逻辑
@@ -548,7 +599,7 @@ public class NetworkServiceImpl implements INetworkService {
@Override
public List getNetworkTypes() {
return Arrays.asList(NetworkType.TCP_CLIENT.getId(), NetworkType.TCP_SERVER.getId(),
- NetworkType.MQTT_CLIENT.getId(), NetworkType.MQTT_SERVER.getId());
+ NetworkType.MQTT_CLIENT.getId(), NetworkType.MQTT_SERVER.getId(), NetworkType.UDP.getId());
}
/**
@@ -608,9 +659,9 @@ public class NetworkServiceImpl implements INetworkService {
try {
JSONObject config = JSONUtil.parseObj(network.getConfiguration());
String type = network.getType();
- // TCP类型检查端口唯一性
- if (NetworkType.TCP_CLIENT.getId().equals(type) || NetworkType.TCP_SERVER.getId()
- .equals(type)) {
+ // TCP/UDP类型检查端口唯一性
+ if (NetworkType.TCP_CLIENT.getId().equals(type) || NetworkType.TCP_SERVER.getId().equals(type)
+ || NetworkType.UDP.getId().equals(type)) {
Integer port = config.getInt("port");
if (port != null) {
List existingNetworks = networkMapper.selectTcpNetworkByPort(port, excludeId);
@@ -663,6 +714,8 @@ public class NetworkServiceImpl implements INetworkService {
case NetworkTypeConstants.MQTT_CLIENT:
case NetworkTypeConstants.MQTT_SERVER:
return startMqttNetwork(network);
+ case NetworkTypeConstants.UDP:
+ return startUdpNetwork(network);
default:
log.warn("不支持的网络类型: {}", type);
return false;
@@ -690,6 +743,8 @@ public class NetworkServiceImpl implements INetworkService {
case NetworkTypeConstants.MQTT_CLIENT:
case NetworkTypeConstants.MQTT_SERVER:
return stopMqttNetwork(network);
+ case NetworkTypeConstants.UDP:
+ return stopUdpNetwork(network);
default:
log.warn("不支持的网络类型: {}", type);
return false;
@@ -708,7 +763,6 @@ public class NetworkServiceImpl implements INetworkService {
*/
private boolean restartNetworkByType(Network network) {
String type = network.getType();
-
try {
switch (type) {
case NetworkTypeConstants.TCP_CLIENT:
@@ -717,6 +771,8 @@ public class NetworkServiceImpl implements INetworkService {
case NetworkTypeConstants.MQTT_CLIENT:
case NetworkTypeConstants.MQTT_SERVER:
return restartMqttNetwork(network);
+ case NetworkTypeConstants.UDP:
+ return restartUdpNetwork(network);
default:
log.warn("不支持的网络类型: {}", type);
return false;
@@ -734,11 +790,28 @@ public class NetworkServiceImpl implements INetworkService {
* @return 是否成功
*/
private boolean startTcpNetwork(Network network) {
+ if (tcpClusterService == null) {
+ log.error("TCP服务管理器未注入,无法启动TCP网络组件: {}", network.getName());
+ return false;
+ }
+
+ String productKey = network.getProductKey();
+ if (StrUtil.isBlank(productKey)) {
+ log.error("TCP网络组件缺少productKey: {}", network.getName());
+ return false;
+ }
+
try {
- //TODO 开源版本无
- return true;
+ // 使用新的方法,从数据库加载配置并启动
+ boolean success = tcpClusterService.start(productKey);
+ if (success) {
+ log.info("TCP网络组件启动成功: productKey={}", productKey);
+ } else {
+ log.error("TCP网络组件启动失败: productKey={}", productKey);
+ }
+ return success;
} catch (Exception e) {
- log.error("启动TCP网络组件失败: productKey={}", "", e);
+ log.error("启动TCP网络组件失败: productKey={}", productKey, e);
return false;
}
}
@@ -750,17 +823,27 @@ public class NetworkServiceImpl implements INetworkService {
* @return 是否成功
*/
private boolean stopTcpNetwork(Network network) {
+ if (tcpClusterService == null) {
+ log.error("TCP服务管理器未注入,无法停止TCP网络组件: {}", network.getName());
+ return false;
+ }
String productKey = network.getProductKey();
if (StrUtil.isBlank(productKey)) {
log.error("TCP网络组件缺少productKey: {}", network.getName());
return false;
}
- try {
- return true;
+ try {
+ boolean success = tcpClusterService.stop(productKey);
+ if (success) {
+ log.info("TCP网络组件停止成功: productKey={}", productKey);
+ } else {
+ log.error("TCP网络组件停止失败: productKey={}", productKey);
+ }
+ return success;
} catch (Exception e) {
- log.error("停止TCP网络组件失败: productKey={}", "", e);
+ log.error("停止TCP网络组件失败: productKey={}", productKey, e);
return false;
}
}
@@ -772,11 +855,27 @@ public class NetworkServiceImpl implements INetworkService {
* @return 是否成功
*/
private boolean restartTcpNetwork(Network network) {
+ if (tcpClusterService == null) {
+ log.error("TCP服务管理器未注入,无法重启TCP网络组件: {}", network.getName());
+ return false;
+ }
+
+ String productKey = network.getProductKey();
+ if (StrUtil.isBlank(productKey)) {
+ log.error("TCP网络组件缺少productKey: {}", network.getName());
+ return false;
+ }
try {
- return true;
+ boolean success = tcpClusterService.restart(productKey);
+ if (success) {
+ log.info("TCP网络组件重启成功: productKey={}", productKey);
+ } else {
+ log.error("TCP网络组件重启失败: productKey={}", productKey);
+ }
+ return success;
} catch (Exception e) {
- log.error("重启TCP网络组件失败: productKey={}", "", e);
+ log.error("重启TCP网络组件失败: productKey={}", productKey, e);
return false;
}
}
@@ -881,4 +980,94 @@ public class NetworkServiceImpl implements INetworkService {
public IoTDevice getDeviceById(String id) {
return ioTDeviceMapper.selectDevInstanceById(id);
}
+
+ /**
+ * 启动UDP网络组件
+ *
+ * @param network 网络组件
+ * @return 是否成功
+ */
+ private boolean startUdpNetwork(Network network) {
+ String productKey = network.getProductKey();
+ if (StrUtil.isBlank(productKey)) {
+ log.error("UDP网络组件缺少productKey: {}", network.getName());
+ return false;
+ }
+
+ try {
+ boolean success;
+ if (udpClusterService != null) {
+ // 使用集群服务启动(会广播到其他节点)
+ success = udpClusterService.start(productKey);
+ log.info("UDP网络组件集群启动: productKey={}, success={}", productKey, success);
+ } else {
+ log.error("UDP集群服务未注入,无法启动UDP网络组件: {}", network.getName());
+ return false;
+ }
+ return success;
+ } catch (Exception e) {
+ log.error("启动UDP网络组件失败: productKey={}", productKey, e);
+ return false;
+ }
+ }
+
+ /**
+ * 停止UDP网络组件
+ *
+ * @param network 网络组件
+ * @return 是否成功
+ */
+ private boolean stopUdpNetwork(Network network) {
+ String productKey = network.getProductKey();
+ if (StrUtil.isBlank(productKey)) {
+ log.error("UDP网络组件缺少productKey: {}", network.getName());
+ return false;
+ }
+
+ try {
+ boolean success;
+ if (udpClusterService != null) {
+ // 使用集群服务停止(会广播到其他节点)
+ success = udpClusterService.stop(productKey);
+ log.info("UDP网络组件集群停止: productKey={}, success={}", productKey, success);
+ } else {
+ log.error("UDP集群服务未注入,无法停止UDP网络组件: {}", network.getName());
+ return false;
+ }
+ return success;
+ } catch (Exception e) {
+ log.error("停止UDP网络组件失败: productKey={}", productKey, e);
+ return false;
+ }
+ }
+
+ /**
+ * 重启UDP网络组件
+ *
+ * @param network 网络组件
+ * @return 是否成功
+ */
+ private boolean restartUdpNetwork(Network network) {
+ String productKey = network.getProductKey();
+ if (StrUtil.isBlank(productKey)) {
+ log.error("UDP网络组件缺少productKey: {}", network.getName());
+ return false;
+ }
+
+ try {
+ boolean success;
+ if (udpClusterService != null) {
+ // 使用集群服务重启(会广播到其他节点)
+ success = udpClusterService.restart(productKey);
+ log.info("UDP网络组件集群重启: productKey={}, success={}", productKey, success);
+ } else {
+ log.error("UDP集群服务未注入,无法重启UDP网络组件: {}", network.getName());
+ return false;
+ }
+ return success;
+ } catch (Exception e) {
+ log.error("重启UDP网络组件失败: productKey={}", productKey, e);
+ return false;
+ }
+ }
}
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/network/utils/NetworkTypeUtil.java b/cn-universal-admin/src/main/java/cn/universal/admin/network/utils/NetworkTypeUtil.java
index dbeb0d0b15caeb65b4e1ba5f7227e2bf5ef092b6..b84fcbba0583737e4b769e833bf2db19966d603e 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/network/utils/NetworkTypeUtil.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/network/utils/NetworkTypeUtil.java
@@ -29,7 +29,7 @@ public class NetworkTypeUtil {
/** 支持的网络类型列表 */
public static final List SUPPORTED_TYPES =
- Arrays.asList("TCP_CLIENT", "TCP_SERVER", "MQTT_CLIENT", "MQTT_SERVER");
+ Arrays.asList("TCP_CLIENT", "TCP_SERVER", "MQTT_CLIENT", "MQTT_SERVER", "UDP");
/**
* 解析网络类型字符串,支持逗号分隔的多个类型
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/network/web/NetworkController.java b/cn-universal-admin/src/main/java/cn/universal/admin/network/web/NetworkController.java
index c6e2bab2136a8f375e0d074dc849703f8e3cfc54..1cd031034edfbb96a3a9ace19c6d591cf889d6d2 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/network/web/NetworkController.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/network/web/NetworkController.java
@@ -329,7 +329,7 @@ public class NetworkController extends BaseController {
}
/** 查询绑定指定星纵网关的设备 */
- @GetMapping("/milesight/list")
+ @GetMapping("/xz/gateway/list")
public TableDataInfo queryMileSightList(NetworkBO bo) {
startPage();
// 设置用户权限过滤
@@ -339,7 +339,7 @@ public class NetworkController extends BaseController {
}
/** 新增设备 */
- @PostMapping("/milesight/add")
+ @PostMapping("/xz/gateway/add")
@Log(title = "新增设备", businessType = BusinessType.INSERT)
public R add(@RequestBody IoTDeviceBO devInstancebo) {
// 设置创建用户
@@ -356,7 +356,7 @@ public class NetworkController extends BaseController {
}
/** 删除设备 */
- @DeleteMapping("/milesight/{ids}")
+ @DeleteMapping("/xz/gateway/{ids}")
@Log(title = "删除设备", businessType = BusinessType.DELETE)
public R remove(@PathVariable String[] ids) {
// 校验用户权限
@@ -385,7 +385,6 @@ public class NetworkController extends BaseController {
public R reloadTcpClient(@PathVariable("applicationId") String applicationId) {
// 校验用户权限 - 需要根据applicationId获取相关的信息进行权限校验
// 这里可能需要额外的业务逻辑来实现权限校验
- iNetworkService.reloadTcpClient(applicationId);
return R.ok();
}
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/IIoTDeviceService.java b/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/IIoTDeviceService.java
index 0eeb24370038df6c0da5e347d296e6a3762c4f51..98035658123091e3dc4d7350b523d31116201fef 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/IIoTDeviceService.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/IIoTDeviceService.java
@@ -27,6 +27,7 @@ import cn.universal.persistence.entity.vo.IoTDeviceModelVO;
import cn.universal.persistence.entity.vo.IoTDeviceVO;
import com.github.pagehelper.Page;
import java.util.List;
+import java.util.Map;
/**
* 设备Service接口
@@ -147,9 +148,15 @@ public interface IIoTDeviceService {
List selectGwIotDevices(IoTGwDeviceBO bo);
- IoTDevice selectDeviceByDeviceId(String deviceId);
+ IoTDevice selectIoTDevice(String productKey, String deviceId);
List selectDevInstanceListWithTags(IoTDeviceBO ioTDeviceBO, IoTUser iotUser);
List selectProductListInBatchFunction(Long applicationId, IoTUser iotUser);
+
+ /** 新:按第三方平台过滤设备列表(不影响旧接口) */
+ List selectDevInstanceListByPlatform(
+ IoTDevice ioTDevice, IoTUser iotUser, String thirdPlatform);
+
+
}
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/IIoTProductService.java b/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/IIoTProductService.java
index aa2317f8bb36718ed84c333e3f968d2494a6ad33..b6b5078387e88937543613f4cca31cab983d09d1 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/IIoTProductService.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/IIoTProductService.java
@@ -178,7 +178,9 @@ public interface IIoTProductService {
Map countDevNumberByProductKey(String unionId);
- AjaxResult selectDevProductByKey(String key);
+ AjaxResult selectIoTProductByKey(String key);
+
+ AjaxResult> selectGatewaySubProductsByKey(String gwProductKey);
int updateDevProductOtherConfig(String otherConfig);
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTDeviceGroupServiceImpl.java b/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTDeviceGroupServiceImpl.java
index c922b2a4429bb8a3c76081e9fa992b81d38097e3..ad08cc725da1b3fbe66b1c5b442fa57587b9476d 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTDeviceGroupServiceImpl.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTDeviceGroupServiceImpl.java
@@ -34,6 +34,7 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -84,7 +85,7 @@ public class IoTDeviceGroupServiceImpl extends BaseServiceImpl implements IIoTDe
// 生成设备分组树
List roots = collect.get(0L);
ioTDeviceGroupVO.setChildren(roots);
- buildGroupTree(roots, collect);
+ groupTree(roots, collect);
return groupVos;
}
@@ -192,12 +193,23 @@ public class IoTDeviceGroupServiceImpl extends BaseServiceImpl implements IIoTDe
}
/**
- * 绑定设备到分组
+ * 绑定设备到分组 iot_dev_action
*
* @param devGroup
* @return
*/
@Override
+ @CacheEvict(
+ cacheNames = {
+ "iot_dev_instance_bo",
+ "iot_dev_metadata_bo",
+ "iot_dev_shadow_bo",
+ "iot_dev_action",
+ "selectDevCount",
+ "iot_dev_product_list",
+ "iot_product_device"
+ },
+ allEntries = true)
public AjaxResult bindDevToGroup(IoTDeviceGroupBO devGroup) {
// 判断分组是否存在
Long groupId = devGroup.getId();
@@ -292,6 +304,17 @@ public class IoTDeviceGroupServiceImpl extends BaseServiceImpl implements IIoTDe
*/
@Override
@Transactional
+ @CacheEvict(
+ cacheNames = {
+ "iot_dev_instance_bo",
+ "iot_dev_metadata_bo",
+ "iot_dev_shadow_bo",
+ "iot_dev_action",
+ "selectDevCount",
+ "iot_dev_product_list",
+ "iot_product_device"
+ },
+ allEntries = true)
public AjaxResult unBindDevByGroupId(String groupId, String[] devId) {
for (int i = 0; i < devId.length; i++) {
ioTDeviceTagsMapper.delete(IoTDeviceTags.builder().iotId(devId[i]).value(groupId).build());
@@ -299,14 +322,8 @@ public class IoTDeviceGroupServiceImpl extends BaseServiceImpl implements IIoTDe
return AjaxResult.success();
}
- /**
- * 生成设备分组树
- *
- * @param ioTDeviceGroupVO
- * @param groups
- * @return
- */
- private void buildGroupTree(
+ /** 生成设备分组列表 */
+ private void groupTree(
List ioTDeviceGroupVO, Map> groups) {
if (ioTDeviceGroupVO == null) {
return;
@@ -315,7 +332,7 @@ public class IoTDeviceGroupServiceImpl extends BaseServiceImpl implements IIoTDe
if (ioTDeviceGroupVO.get(i).getHasChild() == 1) {
List devGroups = groups.get(ioTDeviceGroupVO.get(i).getId());
ioTDeviceGroupVO.get(i).setChildren(devGroups);
- buildGroupTree(devGroups, groups);
+ groupTree(devGroups, groups);
}
}
return;
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTDeviceServiceImpl.java b/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTDeviceServiceImpl.java
index b907e9db930d185e5acfcf490328a58b848753e7..a695f6738d90d3a550471ffa5534c18d9019d858 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTDeviceServiceImpl.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTDeviceServiceImpl.java
@@ -45,7 +45,6 @@ import cn.universal.persistence.mapper.IoTDeviceProtocolMapper;
import cn.universal.persistence.mapper.IoTDeviceShadowMapper;
import cn.universal.persistence.mapper.IoTDeviceTagsMapper;
import cn.universal.persistence.mapper.IoTProductMapper;
-import cn.universal.persistence.query.IoTDeviceQuery;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import jakarta.annotation.Resource;
@@ -149,6 +148,13 @@ public class IoTDeviceServiceImpl extends BaseServiceImpl implements IIoTDeviceS
ioTDevice, iotUser.isAdmin() ? null : iotUser.getUnionId());
}
+ @Override
+ public List selectDevInstanceListByPlatform(
+ IoTDevice ioTDevice, IoTUser iotUser, String thirdPlatform) {
+ return ioTDeviceMapper.selectDevInstanceListByPlatform(
+ ioTDevice, thirdPlatform, iotUser.isAdmin() ? null : iotUser.getUnionId());
+ }
+
/**
* 查询设备列表
*
@@ -229,8 +235,8 @@ public class IoTDeviceServiceImpl extends BaseServiceImpl implements IIoTDeviceS
}
@Override
- public IoTDevice selectDeviceByDeviceId(String deviceId) {
- return ioTDeviceMapper.getOneByDeviceId(IoTDeviceQuery.builder().deviceId(deviceId).build());
+ public IoTDevice selectIoTDevice(String productKey, String deviceId) {
+ return ioTDeviceMapper.selectIoTDevice(productKey, deviceId);
}
@Override
@@ -270,11 +276,12 @@ public class IoTDeviceServiceImpl extends BaseServiceImpl implements IIoTDeviceS
if (ioTDeviceBO.getOtherParams().containsKey("deviceKey")) {
ioTDeviceBO.setSecretKey(ioTDeviceBO.getOtherParams().get("deviceKey").toString());
}
+
if (cn.universal.common.utils.StringUtils.isEmpty(ioTDeviceBO.getLatitude())) {
- ioTDeviceBO.setLatitude("30.4484801");
+ ioTDeviceBO.setLatitude("44.61081");
}
if (cn.universal.common.utils.StringUtils.isEmpty(ioTDeviceBO.getLongitude())) {
- ioTDeviceBO.setLongitude("120.2922654");
+ ioTDeviceBO.setLongitude("80.990372");
}
if (StrUtil.isNotBlank(deviceId)) {
ioTDeviceBO.setGwProductKey(deviceId);
@@ -333,6 +340,17 @@ public class IoTDeviceServiceImpl extends BaseServiceImpl implements IIoTDeviceS
}
@Override
+ @CacheEvict(
+ cacheNames = {
+ "iot_dev_instance_bo",
+ "iot_dev_metadata_bo",
+ "iot_dev_shadow_bo",
+ "iot_dev_action",
+ "selectDevCount",
+ "iot_dev_product_list",
+ "iot_product_device"
+ },
+ allEntries = true)
public int bindApp(String ids, String appUniqueId) {
String[] a = ids.split(",");
return ioTDeviceMapper.bindApp(a, appUniqueId);
@@ -362,7 +380,7 @@ public class IoTDeviceServiceImpl extends BaseServiceImpl implements IIoTDeviceS
downRequest.set("detail", devInstancebo.getDetail());
// 网关产品ProductKey
downRequest.set("gwProductKey", devInstancebo.getGwProductKey());
- downRequest.set("gwDeviceId", devInstancebo.getExtDeviceId());
+ downRequest.set("gwDeviceId", devInstancebo.getGwDeviceId());
downRequest.set("extDeviceId", devInstancebo.getExtDeviceId());
JSONObject ob = new JSONObject();
// 设备实例名称
@@ -506,9 +524,7 @@ public class IoTDeviceServiceImpl extends BaseServiceImpl implements IIoTDeviceS
public R iotFunctionsDown(String productKey, String downRequest) {
JSONObject jsonObject = JSONUtil.parseObj(downRequest);
String deviceId = jsonObject.getStr("deviceId");
- IoTDevice ioTDeviceBo =
- ioTDeviceMapper.getOneByDeviceId(
- IoTDeviceQuery.builder().deviceId(deviceId).productKey(productKey).build());
+ IoTDevice ioTDeviceBo = ioTDeviceMapper.selectIoTDevice(productKey, deviceId);
if (ioTDeviceBo == null) {
return R.error("设备不存在");
}
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTProductServiceImpl.java b/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTProductServiceImpl.java
index d471513fd371b77d70659128adedd948761ef3ec..72c2323b38112cb68f63d783821e233c5a227d1e 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTProductServiceImpl.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/platform/service/impl/IoTProductServiceImpl.java
@@ -25,10 +25,12 @@ import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
+import cn.universal.dm.device.service.protocol.ProtocolClusterService;
import cn.universal.admin.common.service.BaseServiceImpl;
import cn.universal.admin.common.utils.SecurityUtils;
import cn.universal.admin.platform.service.IIoTProductService;
import cn.universal.admin.system.service.IoTDeviceProtocolService;
+import cn.universal.cache.annotation.MultiLevelCacheable;
import cn.universal.common.constant.IoTConstant;
import cn.universal.common.constant.IoTConstant.DeviceNode;
import cn.universal.common.constant.IoTConstant.ProductFlushType;
@@ -192,31 +194,54 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
}
@Override
- // @Cacheable(cacheNames = "iot_dev_product_list", unless = "#result == null", keyGenerator =
- // "redisKeyGenerate")
+ // 分页查询不使用缓存,因为分页参数会导致缓存键不同,效率低下
public List selectDevProductV4List(IoTProductQuery ioTProductQuery) {
- Page page =
- PageHelper.startPage(ioTProductQuery.getPageNum(), ioTProductQuery.getPageSize());
+ // 设置分页参数
+ PageHelper.startPage(ioTProductQuery.getPageNum(), ioTProductQuery.getPageSize());
+
+ // 优化:一次SQL查询获取产品列表和设备数量,避免N+1查询
List devProductVOS = ioTProductMapper.selectDevProductV3List(ioTProductQuery);
- List results =
- ioTProductMapper.countDevNumberByProductKey(ioTProductQuery.getCreatorId());
- if (CollUtil.isNotEmpty(results)) {
- final Map collect =
- results.stream()
- .collect(Collectors.toMap(IoTProductVO::getProductKey, IoTProductVO::getDevNum));
+
+ // 处理图片URL
+ if (CollUtil.isNotEmpty(devProductVOS)) {
for (IoTProductVO devProduct : devProductVOS) {
- devProduct.setDevNum(collect.getOrDefault(devProduct.getProductKey(), 0));
if (JSONUtil.isTypeJSON(devProduct.getPhotoUrl())) {
JSONObject photo = JSONUtil.parseObj(devProduct.getPhotoUrl());
devProduct.setImage(photo.getStr("img", ""));
}
}
}
- // 按设备数量倒序排序
- // if (CollUtil.isNotEmpty(devProductVOS)) {
- // devProductVOS.sort(Comparator.comparingInt(IoTProductVO::getDevNum).reversed());
- // }
- return page;
+
+ return devProductVOS;
+ }
+
+ /** 获取不分页的产品列表(用于缓存) 缓存基础产品数据,不包含分页信息 */
+ @MultiLevelCacheable(
+ cacheNames = "selectDevProductV4ListNoPage",
+ keyGenerator = "redisKeyGenerate",
+ unless = "#result == null",
+ l1Expire = 30)
+ public List selectDevProductV4ListNoPage(IoTProductQuery ioTProductQuery) {
+ // 创建不分页的查询条件
+ IoTProductQuery noPageQuery = new IoTProductQuery();
+ BeanUtil.copyProperties(ioTProductQuery, noPageQuery);
+ noPageQuery.setPageNum(1);
+ noPageQuery.setPageSize(Integer.MAX_VALUE); // 获取所有数据
+
+ // 优化:一次SQL查询获取产品列表和设备数量,避免N+1查询
+ List devProductVOS = ioTProductMapper.selectDevProductV3List(noPageQuery);
+
+ // 处理图片URL
+ if (CollUtil.isNotEmpty(devProductVOS)) {
+ for (IoTProductVO devProduct : devProductVOS) {
+ if (JSONUtil.isTypeJSON(devProduct.getPhotoUrl())) {
+ JSONObject photo = JSONUtil.parseObj(devProduct.getPhotoUrl());
+ devProduct.setImage(photo.getStr("img", ""));
+ }
+ }
+ }
+
+ return devProductVOS;
}
@Override
@@ -237,7 +262,9 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
cacheNames = {
"iot_all_dev_product_list",
"iot_dev_product_list",
- "selectAllEnableNetworkProductKey"
+ "selectAllEnableNetworkProductKey",
+ "selectDevProductV4ListNoPage",
+ "countDevNumberByProductKey"
},
allEntries = true)
public int insertDevProduct(IoTProduct ioTProduct) {
@@ -257,6 +284,9 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
if (StrUtil.isBlank(ioTProduct.getProductSecret())) {
ioTProduct.setProductSecret(IdUtil.fastSimpleUUID());
}
+ if (StrUtil.isBlank(ioTProduct.getConfiguration())) {
+ ioTProduct.setConfiguration(buildProductCfg(ioTProduct));
+ }
ioTProduct.setProductKey(productKey);
ioTProduct.setMetadata(defaultMetadata);
ioTProduct.setThirdConfiguration(thirdConfig);
@@ -268,9 +298,30 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
return i;
}
+ /** 默认创建mqtt设置自动注册 */
+ private String buildProductCfg(IoTProduct ioTProduct) {
+ JSONObject cfg = new JSONObject();
+ boolean isMqtt = false;
+ String thirdPlatform = ioTProduct == null ? null : ioTProduct.getThirdPlatform();
+ if (thirdPlatform == null) {
+ return JSONUtil.toJsonStr(cfg);
+ }
+ if (ProtocolModule.tcp.name().equalsIgnoreCase(thirdPlatform)
+ || ProtocolModule.mqtt.name().equalsIgnoreCase(thirdPlatform)
+ || ProtocolModule.udp.name().equalsIgnoreCase(thirdPlatform)) {
+ cfg.set(IoTConstant.ALLOW_INSERT, true);
+ }
+ return JSONUtil.toJsonStr(cfg);
+ }
+
@Override
@CacheEvict(
- cacheNames = {"iot_all_dev_product_list", "iot_dev_product_list"},
+ cacheNames = {
+ "iot_all_dev_product_list",
+ "iot_dev_product_list",
+ "selectDevProductV4ListNoPage",
+ "countDevNumberByProductKey"
+ },
allEntries = true)
public int insertList(List ioTProductList) {
int i = ioTProductMapper.insertList(ioTProductList);
@@ -280,7 +331,13 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
/** 产品协议导入 */
@Override
@CacheEvict(
- cacheNames = {"iot_all_dev_product_list", "iot_dev_product_list", "supportMQTTNetwork"},
+ cacheNames = {
+ "iot_all_dev_product_list",
+ "iot_dev_product_list",
+ "supportMQTTNetwork",
+ "selectDevProductV4ListNoPage",
+ "countDevNumberByProductKey"
+ },
allEntries = true)
public String importProduct(List productImportBos, String unionId) {
Long timeMillis = System.currentTimeMillis();
@@ -357,7 +414,9 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
devProduct -> {
R r =
IoTDownlFactory.safeInvokeDown(
- ProtocolModule.ctaiot.name(), "downPro", devProduct.getThirdDownRequest());
+ ProtocolModule.ctaiot.name(),
+ IoTConstant.DOWN_TO_THIRD_PLATFORM,
+ devProduct.getThirdDownRequest());
if (!R.SUCCESS.equals(r.getCode())) {
failedList.add(devProduct);
} else {
@@ -395,7 +454,7 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
ioTProductAction.create(null, unionId);
String result =
String.format(
- "导入普通产品总数:%s 个,成功:%s个;导入电信产品总数:%s 个,成功:%s 个;导入协议总数:%s 个,成功:%s 个。",
+ "导入普通产品总数:%s 个,成功:%s个;导入电信ctwing产品总数:%s 个,成功:%s 个;导入协议总数:%s 个,成功:%s 个。",
customProductList.size() + duplicateNum.get(),
customSuccess,
ctwingProductList.size(),
@@ -413,7 +472,13 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
*/
@Override
@CacheEvict(
- cacheNames = {"iot_all_dev_product_list", "iot_dev_product_list", "supportMQTTNetwork"},
+ cacheNames = {
+ "iot_all_dev_product_list",
+ "iot_dev_product_list",
+ "supportMQTTNetwork",
+ "selectDevProductV4ListNoPage",
+ "countDevNumberByProductKey"
+ },
allEntries = true)
public int updateDevProduct(IoTProduct ioTProduct) {
IoTUser iotUser = queryIotUser(SecurityUtils.getUnionId());
@@ -423,7 +488,7 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
String appUnionId = iotUser.getUnionId();
IoTProduct pro = ioTProductMapper.selectByPrimaryKey(ioTProduct.getId());
if (!appUnionId.equals(pro.getCreatorId()) && !iotUser.isAdmin()) {
- throw new IoTException("您没有权限操作此产品!");
+ throw new IoTException("没有产品权限");
}
if (Objects.nonNull(ioTProduct.getClassifiedId())) {
IoTProductSort ioTProductSort =
@@ -432,7 +497,7 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
}
int count = ioTProductMapper.updateDevProduct(ioTProduct);
- log.info("修改产品记录数={},修改人={}", count, appUnionId);
+ log.info("updateDevProduct,操作成功={},userId={}", count, appUnionId);
ioTProductAction.update(ioTProduct);
return count;
}
@@ -445,7 +510,13 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
*/
@Override
@CacheEvict(
- cacheNames = {"iot_all_dev_product_list", "iot_dev_product_list", "supportMQTTNetwork"},
+ cacheNames = {
+ "iot_all_dev_product_list",
+ "iot_dev_product_list",
+ "supportMQTTNetwork",
+ "selectDevProductV4ListNoPage",
+ "countDevNumberByProductKey"
+ },
allEntries = true)
public int deleteDevProductByIds(String[] ids) {
String appUnionId = queryIotUser(SecurityUtils.getUnionId()).getUnionId();
@@ -453,7 +524,7 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
for (String id : ids) {
IoTProduct ioTProduct = ioTProductMapper.selectDevProductById(id);
if (!appUnionId.equals(ioTProduct.getCreatorId())) {
- throw new IoTException("您没有权限操作此产品!");
+ throw new IoTException("无产品权限");
}
count = +deleteDevProductById(id);
}
@@ -468,7 +539,13 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
*/
@Override
@CacheEvict(
- cacheNames = {"iot_all_dev_product_list", "iot_dev_product_list", "supportMQTTNetwork"},
+ cacheNames = {
+ "iot_all_dev_product_list",
+ "iot_dev_product_list",
+ "supportMQTTNetwork",
+ "selectDevProductV4ListNoPage",
+ "countDevNumberByProductKey"
+ },
allEntries = true)
public int deleteDevProductById(String id) {
String appUnionId = queryIotUser(SecurityUtils.getUnionId()).getUnionId();
@@ -477,7 +554,7 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
throw new IoTException("产品不存在");
}
if (!appUnionId.equals(ioTProduct.getCreatorId())) {
- throw new IoTException("您没有权限操作此产品!");
+ throw new IoTException("无产品权限");
}
IoTDevice ioTDevice = IoTDevice.builder().productKey(ioTProduct.getProductKey()).build();
int count = ioTDeviceMapper.selectCount(ioTDevice);
@@ -507,7 +584,8 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
"iot_dev_action",
"selectDevCount",
"supportMQTTNetwork",
- "iot_dev_product_list"
+ "iot_dev_product_list",
+ "getProductConfiguration"
},
allEntries = true)
public int updateDevProductConfig(IoTProductVO devProduct) {
@@ -518,7 +596,7 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
throw new IoTException("产品不存在");
}
if (!appUnionId.equals(product.getCreatorId())) {
- throw new IoTException("您没有权限操作此产品!");
+ throw new IoTException("无产品权限");
}
// 获取新的产品配置信息
JSONObject newConfig = JSONUtil.parseObj(devProduct.getConfiguration());
@@ -802,7 +880,7 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
String appUnionId = queryIotUser(SecurityUtils.getUnionId()).getUnionId();
IoTProduct product = ioTProductMapper.getProductByProductKey(ioTProductBO.getProductKey());
if (!appUnionId.equals(product.getCreatorId())) {
- throw new IoTException("您没有权限操作此产品!");
+ throw new IoTException("无产品权限");
}
ioTProductBO.setPath(getPath(ioTProductBO));
int delCount = ioTProductMapper.deleteMetadata(ioTProductBO);
@@ -840,7 +918,7 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
String appUnionId = queryIotUser(SecurityUtils.getUnionId()).getUnionId();
IoTProduct product = ioTProductMapper.getProductByProductKey(ioTProductBO.getProductKey());
if (!appUnionId.equals(product.getCreatorId())) {
- throw new IoTException("您没有权限操作此产品!");
+ throw new IoTException("无产品权限");
}
ioTProductBO.beanToJson();
// if(getMetadata(ioTProductBO)!=null){
@@ -884,19 +962,41 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
}
@Override
+ @MultiLevelCacheable(
+ cacheNames = "countDevNumberByProductKey",
+ keyGenerator = "redisKeyGenerate",
+ unless = "#result == null",
+ l1Expire = 30)
public Map countDevNumberByProductKey(String unionId) {
List results = ioTProductMapper.countDevNumberByProductKey(unionId);
return results.stream()
.collect(Collectors.toMap(IoTProductVO::getProductKey, IoTProductVO::getDevNum));
}
+ /** 设备数量变化时清除相关缓存 当设备新增、删除、修改时调用此方法 */
+ @CacheEvict(
+ cacheNames = {"countDevNumberByProductKey", "selectDevProductV4ListNoPage"},
+ allEntries = true)
+ public void evictDeviceCountCache() {
+ // 此方法用于手动清除设备数量相关缓存
+ // 当设备数据发生变化时调用
+ }
+
@Override
- public AjaxResult selectDevProductByKey(String key) {
+ public AjaxResult selectIoTProductByKey(String key) {
IoTProduct ioTProduct = new IoTProduct();
ioTProduct.setProductKey(key);
return AjaxResult.success(ioTProductMapper.selectOne(ioTProduct));
}
+ @Override
+ public AjaxResult> selectGatewaySubProductsByKey(String gwProductKey) {
+ IoTProduct ioTProduct = new IoTProduct();
+ ioTProduct.setGwProductKey(gwProductKey);
+ ioTProduct.setState((byte) 0);
+ return AjaxResult.success(ioTProductMapper.select(ioTProduct));
+ }
+
/** 修改产品其他配置信息 */
@Override
@CacheEvict(
@@ -917,7 +1017,7 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
IoTProduct product = ioTProductMapper.selectDevProductById(newConfig.getStr("productId"));
IoTUser iotUser = queryIotUser(SecurityUtils.getUnionId());
if (!product.getCreatorId().equals(iotUser.getUnionId())) {
- throw new IoTException("您没有权限操作此产品!");
+ throw new IoTException("无产品权限");
}
// 获取第三方配置
String thirdConfiguration = product.getThirdConfiguration();
@@ -1042,7 +1142,20 @@ public class IoTProductServiceImpl extends BaseServiceImpl implements IIoTProduc
@Override
public void flushNettyServer(String config, String productKey, TcpFlushType type) {
-
+ JSONObject object = new JSONObject();
+ object.set("type", ProductFlushType.server.name());
+ object.set("productKey", productKey);
+ object.set("customType", type.name());
+ eventPublisher.publishEvent(EventTopics.PRODUCT_CONFIG_UPDATED, object);
+ // 使用ProtocolClusterService进行集群操作
+ ProtocolClusterService tcpClusterService = SpringUtil.getBean(ProtocolClusterService.class);
+ if (tcpClusterService != null) {
+ switch (type) {
+ case start -> tcpClusterService.start(productKey);
+ case reload -> tcpClusterService.restart(productKey);
+ case close -> tcpClusterService.stop(productKey);
+ }
+ }
}
@Override
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/platform/web/IoTDeviceController.java b/cn-universal-admin/src/main/java/cn/universal/admin/platform/web/IoTDeviceController.java
index 84efb189975539b0042897b014211b287fdd933a..d9eb51276dea878245ee9283f8163a29f7ff57e2 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/platform/web/IoTDeviceController.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/platform/web/IoTDeviceController.java
@@ -90,6 +90,18 @@ public class IoTDeviceController extends BaseController {
return getDataTable(list);
}
+ /** 新:按第三方平台过滤的设备列表(用于萤石/乐橙) */
+ @GetMapping("/listByPlatform")
+ public TableDataInfo listByPlatform(
+ IoTDevice ioTDevice,
+ @RequestParam(value = "thirdPlatform", required = false) String thirdPlatform) {
+ IoTUser iotUser = loginIoTUnionUser(SecurityUtils.getUnionId());
+ startPage();
+ List list =
+ iIotDeviceService.selectDevInstanceListByPlatform(ioTDevice, iotUser, thirdPlatform);
+ return getDataTable(list);
+ }
+
/** 查询分组未绑定设备列表 */
@GetMapping("/list/{groupId}")
public TableDataInfo list(@PathVariable("groupId") String groupId, IoTDevice ioTDevice) {
@@ -152,27 +164,18 @@ public class IoTDeviceController extends BaseController {
/** 获取设备详细信息 */
@GetMapping(value = "/{id}")
- public AjaxResult getInfo(@PathVariable("id") String id) {
-
+ public AjaxResult getIotDeviceInfo(@PathVariable("id") String id) {
IoTDevice ioTDevice = iIotDeviceService.selectDevInstanceById(id);
- // if (ObjectUtil.isEmpty(ioTDevice)) {
- // throw new IoTException("设备不存在");
- // }
- // IoTUser iotUser = checkParent(SecurityUtils.getUnionId());
- // if (!iotUser.isAdmin() && !ioTDevice.getCreatorId()
- // .equals(iotUser.getUnionId())) {
- // throw new IoTException("你无权操作");
- // }
- // 是否有编解码插件
int count = ioTDeviceProtocolService.countProtocol(ioTDevice.getProductKey());
IoTDeviceBO ioTDeviceBO = new IoTDeviceBO();
BeanUtil.copyProperties(ioTDevice, ioTDeviceBO);
// 查询网关产品信息
if (StrUtil.isNotBlank(ioTDeviceBO.getGwProductKey())) {
IoTDevice parentDevice =
- iIotDeviceService.selectDeviceByDeviceId(ioTDevice.getGwProductKey());
+ iIotDeviceService.selectIoTDevice(
+ ioTDeviceBO.getGwProductKey(), ioTDevice.getExtDeviceId());
if (ObjectUtil.isNotNull(parentDevice)) {
- ioTDeviceBO.setParentName(
+ ioTDeviceBO.setGwDeviceInfo(
parentDevice.getDeviceId() + "(" + parentDevice.getDeviceName() + ")");
}
}
diff --git a/cn-universal-admin/src/main/java/cn/universal/admin/platform/web/IoTProductController.java b/cn-universal-admin/src/main/java/cn/universal/admin/platform/web/IoTProductController.java
index bab3f268f7673d70f4b2a2554cf1e825cf3998c0..b13b752e6962ea41ba21e20e99df5923e06e1b44 100644
--- a/cn-universal-admin/src/main/java/cn/universal/admin/platform/web/IoTProductController.java
+++ b/cn-universal-admin/src/main/java/cn/universal/admin/platform/web/IoTProductController.java
@@ -20,16 +20,22 @@ import cn.universal.admin.common.annotation.Log;
import cn.universal.admin.common.enums.BusinessType;
import cn.universal.admin.common.utils.SecurityUtils;
import cn.universal.admin.network.service.INetworkService;
+import cn.universal.admin.platform.dto.ConnectionInfoDTO;
+import cn.universal.admin.platform.service.ConnectionInfoService;
import cn.universal.admin.platform.service.IIoTDeviceService;
import cn.universal.admin.platform.service.IIoTProductService;
import cn.universal.admin.platform.service.impl.IoTProductServiceImpl;
import cn.universal.admin.system.service.ISysDictTypeService;
import cn.universal.admin.system.service.IoTDeviceProtocolService;
import cn.universal.admin.system.web.BaseController;
+import cn.universal.common.constant.IoTConstant;
import cn.universal.common.constant.IoTConstant.ProtocolModule;
import cn.universal.common.constant.IoTConstant.TcpFlushType;
+import cn.universal.common.event.EventTopics;
+import cn.universal.common.event.processer.EventPublisher;
import cn.universal.common.exception.IoTException;
import cn.universal.core.service.IoTDownlFactory;
+import cn.universal.ossm.service.ISysOssService;
import cn.universal.persistence.entity.IoTDevice;
import cn.universal.persistence.entity.IoTDeviceEvents;
import cn.universal.persistence.entity.IoTDeviceFunction;
@@ -55,7 +61,6 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationEventPublisher;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@@ -77,29 +82,20 @@ import org.springframework.web.multipart.MultipartFile;
@RequestMapping("/admin/v1/product")
public class IoTProductController extends BaseController {
- @Autowired
- private IIoTProductService devProductService;
- @Autowired
- private IIoTDeviceService iIotDeviceService;
- @Autowired
- private ISysDictTypeService dictTypeService;
- @Resource
- private INetworkService iNetworkService;
- @Resource
- private IoTDeviceProtocolService ioTDeviceProtocolService;
- @Resource
- private IoTProductMapper ioTProductMapper;
- @Autowired
- private IoTProductServiceImpl ioTProductServiceImpl;
- @Autowired
- private ApplicationEventPublisher eventPublisher;
-
- /**
- * 查询设备产品列表
- */
+ @Autowired private IIoTProductService devProductService;
+ @Autowired private IIoTDeviceService iIotDeviceService;
+ @Autowired private ISysDictTypeService dictTypeService;
+ @Resource private INetworkService iNetworkService;
+ @Resource private IoTDeviceProtocolService ioTDeviceProtocolService;
+ @Resource private IoTProductMapper ioTProductMapper;
+ @Autowired private IoTProductServiceImpl ioTProductServiceImpl;
+ @Autowired private EventPublisher eventPublisher;
+ @Autowired private ISysOssService iSysOssService;
+ @Autowired private ConnectionInfoService connectionInfoService;
+
+ /** 查询设备产品列表 */
@GetMapping("/list")
public TableDataInfo list(IoTProductQuery query) {
- // 只能看自己设备,除非是特殊设置和超管
IoTUser iotUser = loginIoTUnionUser(SecurityUtils.getUnionId());
if (!iotUser.viewAllProduct()) {
query.setSelf(true);
@@ -118,20 +114,21 @@ public class IoTProductController extends BaseController {
return getDataTable(list);
}
- /**
- * 获取产品详情通过 ProductKey
- */
+ /** 获取产品详情通过 ProductKey */
@GetMapping("/get/pro/{key}")
public AjaxResult getProByKey(@PathVariable("key") String key) {
- return devProductService.selectDevProductByKey(key);
+ return devProductService.selectIoTProductByKey(key);
}
- /**
- * 查询设备产品列表
- */
+ /** 获取网关绑定的子产品列表 */
+ @GetMapping("/gateway/subProducts/{key}")
+ public AjaxResult> gatewaySubProducts(@PathVariable("key") String gwProductKey) {
+ return devProductService.selectGatewaySubProductsByKey(gwProductKey);
+ }
+
+ /** 查询设备产品列表 */
@GetMapping("/v2/list")
public TableDataInfo v2List(IoTProductQuery query) {
- // 只能看自己设备,除非是特殊设置和超管
IoTUser iotUser = loginIoTUnionUser(SecurityUtils.getUnionId());
if (!iotUser.viewAllProduct()) {
query.setSelf(true);
@@ -150,12 +147,10 @@ public class IoTProductController extends BaseController {
return getDataTable(list);
}
- /**
- * 查询设备产品列表
- */
+ /** 查询设备产品列表 */
@GetMapping("/v3/list")
public TableDataInfo v3List(IoTProductQuery query) {
- // 只能看自己设备,除非是特殊设置和超管
+ //
IoTUser iotUser = loginIoTUnionUser(SecurityUtils.getUnionId());
if (!iotUser.viewAllProduct()) {
query.setSelf(true);
@@ -175,12 +170,10 @@ public class IoTProductController extends BaseController {
return getDataTable(list);
}
- /**
- * 查询设备产品列表
- */
+ /** 查询设备产品列表 */
@GetMapping("/v4/list")
public TableDataInfo v4List(IoTProductQuery query) {
- // 只能看自己设备,除非是特殊设置和超管
+ //
IoTUser iotUser = loginIoTUnionUser(SecurityUtils.getUnionId());
if (!iotUser.viewAllProduct()) {
query.setSelf(true);
@@ -200,70 +193,47 @@ public class IoTProductController extends BaseController {
return getDataTable(list);
}
- /**
- * 查询所有设备产品列表
- */
+ /** 查询所有设备产品列表 */
@GetMapping("/all/list")
public TableDataInfo v3List() {
List list = devProductService.selectDevProductAllList();
return getDataTable(list);
}
- /**
- * 物模型新增内容
- */
+ /** 物模型新增内容 */
@PostMapping("/metadata/add")
@Log(title = "物模型新增内容", businessType = BusinessType.INSERT)
public AjaxResult metadataAdd(@RequestBody IoTProductBO ioTProductBO) {
return toAjax(devProductService.insertMetadata(ioTProductBO));
}
- /**
- * 物模型修改内容
- */
+ /** 物模型修改内容 */
@PostMapping("/metadata/update")
@Log(title = "物模型修改内容", businessType = BusinessType.UPDATE)
public AjaxResult metadataUpdate(@RequestBody IoTProductBO ioTProductBO) {
return toAjax(devProductService.updateMetadata(ioTProductBO));
}
- /**
- * 物模型删除内容
- */
+ /** 物模型删除内容 */
@PostMapping("/metadata/delete")
@Log(title = "物模型删除内容", businessType = BusinessType.DELETE)
public AjaxResult metadataDelete(@RequestBody IoTProductBO ioTProductBO) {
return toAjax(devProductService.deleteMetadata(ioTProductBO));
}
- /**
- * 物模型查询内容
- */
+ /** 物模型查询内容 */
@PostMapping("/metadata/get")
public AjaxResult metadataGet(@RequestBody IoTProductBO ioTProductBO) {
return AjaxResult.success(devProductService.getMetadata(ioTProductBO));
}
- /** 导出设备产品列表 */
- // @PostMapping("/export")
- // public void export(HttpServletResponse response, IoTProduct ioTProduct)
- // {
- // List list = devProductService.selectDevProductList(ioTProduct);
- // ExcelUtil util = new ExcelUtil(IoTProduct.class);
- // util.exportExcel(response, list, "设备产品数据");
- // }
-
- /**
- * 获取设备产品详细信息
- */
+ /** 获取设备产品详细信息 */
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") String id) {
return AjaxResult.success(devProductService.selectDevProductById(id));
}
- /**
- * 查询可绑定网关列表
- */
+ /** 查询可绑定网关列表 */
@Operation(summary = "查询可绑定网关产品列表")
@GetMapping("/gateway/list")
public AjaxResult> getGatewayList() {
@@ -271,20 +241,16 @@ public class IoTProductController extends BaseController {
return AjaxResult.success(list);
}
- /**
- * 查询可绑定网关子设备产品列表
- */
+ /** 查询可绑定网关子设备产品列表 */
@Operation(summary = "查询可绑定网关子设备产品列表")
- @GetMapping("/subdevice/{productKey}")
+ @GetMapping("/sub/device/{productKey}")
public AjaxResult> getGatewaySubDeviceList(
@PathVariable("productKey") String productKey) {
List list = devProductService.getGatewaySubDeviceList(productKey);
return AjaxResult.success(list);
}
- /**
- * 查询电信公共产品列表
- */
+ /** 查询电信公共产品列表 */
@PostMapping(value = "/ctwing/pubpro")
public AjaxResult getCtwingPubPro(@RequestBody String downRequest) {
String creatorId = loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId();
@@ -299,23 +265,27 @@ public class IoTProductController extends BaseController {
downProRequest.set("data", data);
return AjaxResult.success(
IoTDownlFactory.safeInvokeDown(
- ProtocolModule.ctaiot.name(), "downPro", downProRequest.toString()));
+ ProtocolModule.ctaiot.name(),
+ IoTConstant.DOWN_TO_THIRD_PLATFORM,
+ downProRequest.toString()));
}
- /**
- * 新增设备产品
- */
+ /** 新增设备产品 */
@PostMapping
@Log(title = "新增产品", businessType = BusinessType.INSERT)
public AjaxResult add(@RequestBody IoTProduct ioTProduct) {
String unionId = loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId();
ioTProduct.setCreatorId(unionId);
+ // 发布产品配置更新事件
+ Map eventData = new HashMap<>();
+ eventData.put("type", "product");
+ eventData.put("productKey", ioTProduct.getProductKey());
+ eventData.put("operation", "ADD");
+ eventPublisher.publishEvent(EventTopics.PRODUCT_CONFIG_UPDATED, eventData);
return toAjax(devProductService.insertDevProduct(ioTProduct));
}
- /**
- * 新增设备产品NB
- */
+ /** 新增设备产品NB */
@PostMapping(value = "/nb")
@Log(title = "新增产品NB", businessType = BusinessType.INSERT)
public AjaxResult addNb(@RequestBody String downRequest) {
@@ -343,12 +313,12 @@ public class IoTProductController extends BaseController {
downProRequest.set("data", data);
return AjaxResult.success(
IoTDownlFactory.safeInvokeDown(
- ProtocolModule.ctaiot.name(), "downPro", downProRequest.toString()));
+ ProtocolModule.ctaiot.name(),
+ IoTConstant.DOWN_TO_THIRD_PLATFORM,
+ downProRequest.toString()));
}
- /**
- * 新增电信公共产品
- */
+ /** 新增电信公共产品 */
@PostMapping(value = "/ctwing/pubproadd")
@Log(title = "新增电信公共产品", businessType = BusinessType.INSERT)
public AjaxResult addCtwingPubPro(@RequestBody String downRequest) {
@@ -367,12 +337,12 @@ public class IoTProductController extends BaseController {
downProRequest.set("data", data);
return AjaxResult.success(
IoTDownlFactory.safeInvokeDown(
- ProtocolModule.ctaiot.name(), "downPro", downProRequest.toString()));
+ ProtocolModule.ctaiot.name(),
+ IoTConstant.DOWN_TO_THIRD_PLATFORM,
+ downProRequest.toString()));
}
- /**
- * 修改设备产品
- */
+ /** 修改设备产品 */
@PostMapping(value = "/updateNetworkUnionId")
@Log(title = "修改网络组件", businessType = BusinessType.UPDATE)
public AjaxResult editNetwork(@RequestBody IoTProductBO ioTProductBO) {
@@ -387,9 +357,7 @@ public class IoTProductController extends BaseController {
ioTProductBO.getId(), ioTProductBO.getNetworkUnionId()));
}
- /**
- * 子设备绑定网关
- */
+ /** 子设备绑定网关 */
@Operation(summary = "子设备绑定网关")
@PutMapping("/gateway")
@Log(title = "子设备绑定网关", businessType = BusinessType.UPDATE)
@@ -407,9 +375,7 @@ public class IoTProductController extends BaseController {
return toAjax(devProductService.updateDevProduct(productVO));
}
- /**
- * 修改设备产品
- */
+ /** 修改设备产品 */
@PutMapping
@Log(title = "修改设备产品", businessType = BusinessType.UPDATE)
public AjaxResult edit(@RequestBody IoTProductBO ioTProductBO) {
@@ -434,42 +400,45 @@ public class IoTProductController extends BaseController {
downProRequest.set("productKey", ioTProductBO.getProductKey());
return AjaxResult.success(
IoTDownlFactory.safeInvokeDown(
- ProtocolModule.ctaiot.name(), "downPro", downProRequest.toString()));
+ ProtocolModule.ctaiot.name(),
+ IoTConstant.DOWN_TO_THIRD_PLATFORM,
+ downProRequest.toString()));
}
IoTProduct ioTProduct = BeanUtil.toBean(ioTProductBO, IoTProduct.class);
- return toAjax(devProductService.updateDevProduct(ioTProduct));
+ int result = devProductService.updateDevProduct(ioTProduct);
+ if (result > 0) {
+ // 发布产品配置更新事件
+ Map eventData = new HashMap<>();
+ eventData.put("type", "product");
+ eventData.put("productKey", ioTProduct.getProductKey());
+ eventData.put("operation", "UPDATE");
+ eventPublisher.publishEvent(EventTopics.PRODUCT_CONFIG_UPDATED, eventData);
+ }
+ return toAjax(result);
}
- /**
- * 修改产品配置信息
- */
+ /** 修改产品配置信息 */
@PutMapping("/config")
@Log(title = "修改产品配置信息", businessType = BusinessType.UPDATE)
public AjaxResult editConfig(@RequestBody IoTProductVO devProduct) {
return toAjax(devProductService.updateDevProductConfig(devProduct));
}
- /**
- * 修改产品其他配置信息
- */
+ /** 修改产品其他配置信息 */
@PutMapping("/otherConfig")
@Log(title = "修改产品其他配置信息", businessType = BusinessType.UPDATE)
public AjaxResult editOtherConfig(@RequestBody String otherConfig) {
return toAjax(devProductService.updateDevProductOtherConfig(otherConfig));
}
- /**
- * 修改产品存储策略
- */
+ /** 修改产品存储策略 */
@PutMapping("/storeConfig")
@Log(title = "修改产品存储策略", businessType = BusinessType.UPDATE)
public AjaxResult editOtherConfig(@RequestBody IoTProductVO devProduct) {
return toAjax(devProductService.updateDevProductStoreConfig(devProduct));
}
- /**
- * 删除设备产品
- */
+ /** 删除设备产品 */
@DeleteMapping("/{ids}")
@Log(title = "删除设备产品", businessType = BusinessType.DELETE)
public AjaxResult remove(@PathVariable String[] ids) {
@@ -480,7 +449,7 @@ public class IoTProductController extends BaseController {
throw new IoTException("没有该产品");
}
if (!iotUser.isAdmin() && !ioTProduct.getCreatorId().equals(iotUser.getUnionId())) {
- throw new IoTException("您没有权限操作此产品!");
+ throw new IoTException("没有产品权限");
}
IoTDevice ioTDevice = IoTDevice.builder().productKey(ioTProduct.getProductKey()).build();
List ioTDeviceList =
@@ -501,7 +470,9 @@ public class IoTProductController extends BaseController {
return AjaxResult.success(
IoTDownlFactory.safeInvokeDown(
- ProtocolModule.ctaiot.name(), "downPro", downProRequest.toString()));
+ ProtocolModule.ctaiot.name(),
+ IoTConstant.DOWN_TO_THIRD_PLATFORM,
+ downProRequest.toString()));
}
// tcp产品删除时同时删除network表
if (ProtocolModule.tcp.name().equals(ioTProduct.getThirdPlatform())) {
@@ -512,22 +483,25 @@ public class IoTProductController extends BaseController {
}
// 删除协议
ioTDeviceProtocolService.deleteDevProtocolById(ioTProduct.getProductKey());
+
+ // 发布产品删除事件
+ Map eventData = new HashMap<>();
+ eventData.put("type", "product");
+ eventData.put("productKey", ioTProduct.getProductKey());
+ eventData.put("operation", "DELETE");
+ eventPublisher.publishEvent(EventTopics.PRODUCT_CONFIG_UPDATED, eventData);
}
return toAjax(devProductService.deleteDevProductByIds(ids));
}
- /**
- * 查询设备产品物模型属性列表
- */
+ /** 查询设备产品物模型属性列表 */
@GetMapping("/properties/{id}")
public AjaxResult getPropertiesList(@PathVariable("id") String id) {
List list = devProductService.selectDevProperties(id);
return AjaxResult.success(list);
}
- /**
- * 查询设备产品物模型属性列表(功能下发属性)
- */
+ /** 查询设备产品物模型属性列表(功能下发属性) */
@GetMapping("/functionProperties/{id}")
public AjaxResult getFunctionPropertiesList(@PathVariable("id") String id) {
List list = devProductService.selectDevProperties(id);
@@ -535,7 +509,8 @@ public class IoTProductController extends BaseController {
List dataRw =
list.stream().filter((item) -> "rw".equals(item.getMode())).collect(Collectors.toList());
// 获取设备公共字段
- List data = dictTypeService.selectDictDataByType("device_common_property");
+ List data =
+ dictTypeService.selectDictDataByType(IoTConstant.DEVICE_SHADOW_CUSTOMIZED_PROPERTY);
// 根据公共字段过滤
if (Validator.isNotNull(data)) {
for (SysDictData datum : data) {
@@ -558,27 +533,21 @@ public class IoTProductController extends BaseController {
return AjaxResult.success(dataRw);
}
- /**
- * 查询设备产品物模型事件列表
- */
+ /** 查询设备产品物模型事件列表 */
@GetMapping("/events/{id}")
public AjaxResult getEventsList(@PathVariable("id") String id) {
List list = devProductService.selectDevEvents(id);
return AjaxResult.success(list);
}
- /**
- * 查询设备产品物模型方法列表
- */
+ /** 查询设备产品物模型方法列表 */
@GetMapping("/functions/{id}")
public AjaxResult getFunctionsList(@PathVariable("id") String id) {
List list = devProductService.selectDevFunctions(id);
return AjaxResult.success(list);
}
- /**
- * 根据产品key查model配置
- */
+ /** 根据产品key查model配置 */
@GetMapping("/model/{id}")
public AjaxResult getmodel(@PathVariable("id") String id) {
IoTDeviceModelVO ioTDeviceModelVO = devProductService.getModelByProductKey(id);
@@ -590,7 +559,7 @@ public class IoTProductController extends BaseController {
return AjaxResult.success(devProductService.selectMetadataByDevId(devId));
}
- @GetMapping("/devnumber")
+ @GetMapping("/device/count")
public AjaxResult countDevNumberByProductKey() {
IoTUser iotUser = loginIoTUnionUser(SecurityUtils.getUnionId());
Map products =
@@ -599,13 +568,11 @@ public class IoTProductController extends BaseController {
return AjaxResult.success(products);
}
- /**
- * 导出设备产品列表
- */
+ /** 导出设备产品列表 */
@PostMapping("/export")
@Log(title = "产品导出", businessType = BusinessType.EXPORT)
public void export(HttpServletResponse response, IoTProductQuery query) {
- // 只能看自己设备,除非是特殊设置和超管
+ //
IoTUser iotUser = loginIoTUnionUser(SecurityUtils.getUnionId());
query.setSelf(!iotUser.isAdmin());
if (query.isSelf()) {
@@ -646,15 +613,13 @@ public class IoTProductController extends BaseController {
}
}
- /**
- * 批量导入产品
- */
+ /** 批量导入产品 */
@PostMapping("/import")
@Log(title = "产品批量导入", businessType = BusinessType.IMPORT)
@Transactional(rollbackFor = Exception.class)
public AjaxResult importProduct(MultipartFile file) throws Exception {
// 模板
- // 只能看自己设备,除非是特殊设置和超管
+ //
String unionId = loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId();
try {
// 读取JSON文件内容
@@ -675,9 +640,41 @@ public class IoTProductController extends BaseController {
}
}
- /**
- * 下载导入模版
- */
+ /** 上传产品图片并保存到产品信息 */
+ @Operation(summary = "上传产品图片")
+ @PostMapping("/uploadImage")
+ @Log(title = "上传产品图片", businessType = BusinessType.UPDATE)
+ public AjaxResult