diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index b11ebf49d5..b9026f6897 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -67,6 +67,7 @@
3.0.6
4.1.113.Final
1.2.5
+ 0.6.9
2.17.0
1.27.1
@@ -567,6 +568,12 @@
${jsoup.version}
+
+ org.eclipse.milo
+ sdk-client
+ ${opc.version}
+
+
com.amazonaws
diff --git a/yudao-framework/yudao-common/pom.xml b/yudao-framework/yudao-common/pom.xml
index f364df7c35..51f539b078 100644
--- a/yudao-framework/yudao-common/pom.xml
+++ b/yudao-framework/yudao-common/pom.xml
@@ -138,6 +138,11 @@
easy-trans-anno
+
+ org.eclipse.milo
+ sdk-client
+
+
org.springframework.boot
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/DeviceConnectionStatusEnum.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/DeviceConnectionStatusEnum.java
new file mode 100644
index 0000000000..15c7a9fe8f
--- /dev/null
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/DeviceConnectionStatusEnum.java
@@ -0,0 +1,67 @@
+package cn.iocoder.yudao.framework.common.enums;
+
+import cn.hutool.core.util.ObjUtil;
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 设备连接状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum DeviceConnectionStatusEnum implements IntArrayValuable {
+
+ CONNECTED(1, "已连接"),
+ DISCONNECTED(2, "已断开");
+
+ public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeviceConnectionStatusEnum::getStatus).toArray();
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public int[] array() {
+ return ARRAYS;
+ }
+
+ /**
+ * 判断是否为连接状态
+ */
+ public static boolean isConnected(Integer status) {
+ return ObjUtil.equal(CONNECTED.status, status);
+ }
+
+ /**
+ * 判断是否为断开状态
+ */
+ public static boolean isDisconnected(Integer status) {
+ return ObjUtil.equal(DISCONNECTED.status, status);
+ }
+
+ /**
+ * 根据状态值获取枚举实例
+ */
+ public static DeviceConnectionStatusEnum valueOf(Integer status) {
+ if (status == null) {
+ return null;
+ }
+ for (DeviceConnectionStatusEnum value : values()) {
+ if (ObjUtil.equal(value.status, status)) {
+ return value;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/GlobalErrorCodeConstants.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/GlobalErrorCodeConstants.java
index edf31f24aa..a8df4909ca 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/GlobalErrorCodeConstants.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/enums/GlobalErrorCodeConstants.java
@@ -35,6 +35,7 @@ public interface GlobalErrorCodeConstants {
// ========== 自定义错误段 ==========
ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求
ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作");
+ ErrorCode DEVICE_CONTACT_MODEL_NOT_EXISTS = new ErrorCode(902, "查询不到该设备");
ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/opc/OpcUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/opc/OpcUtils.java
new file mode 100644
index 0000000000..bd6146d6d0
--- /dev/null
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/opc/OpcUtils.java
@@ -0,0 +1,246 @@
+package cn.iocoder.yudao.framework.common.util.opc;
+
+import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
+import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
+import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
+import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
+import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
+import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
+import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+
+/**
+ * OPC UA连接静态工具类 - 适用于Eclipse Milo 0.6.9
+ * 提供OPC UA服务器的连接、断开、数据读写等功能(静态方法版本)
+ */
+public class OpcUtils {
+
+ // 静态成员变量,所有实例共享
+ private static OpcUaClient client;
+ private static String serverUrl;
+ private static boolean isConnected = false;
+ private static final String LOG_PREFIX = "[OPC-UA]";
+
+ // 私有构造方法,防止实例化
+ private OpcUtils() {
+ throw new UnsupportedOperationException("这是一个工具类,不允许创建实例");
+ }
+
+ /**
+ * 连接OPC UA服务器(匿名认证)
+ */
+ public static boolean connect(String url, int timeoutSeconds) {
+ return connect(url, null, null, timeoutSeconds);
+ }
+
+ /**
+ * 连接OPC UA服务器(支持匿名和用户名密码认证)
+ */
+ public static boolean connect(String url, String username, String password, int timeoutSeconds) {
+ if (isConnected) {
+ System.out.println(LOG_PREFIX + "客户端已连接,无需重复连接");
+ return true;
+ }
+
+ serverUrl = url;
+
+ try {
+ System.out.println(LOG_PREFIX + "正在连接到OPC UA服务器: " + url);
+
+ if (username != null && password != null && !username.isEmpty()) {
+ System.out.println(LOG_PREFIX + "使用用户名密码认证: " + username);
+
+ Predicate endpointPredicate = e ->
+ "http://opcfoundation.org/UA/SecurityPolicy#None".equals(e.getSecurityPolicyUri());
+
+ client = OpcUaClient.create(url, endpoints ->
+ endpoints.stream()
+ .filter(endpointPredicate)
+ .findFirst(),
+ configBuilder -> configBuilder
+ .setIdentityProvider(new UsernameProvider(username, password))
+ .setRequestTimeout(UInteger.valueOf(timeoutSeconds * 1000L))
+ .build()
+ );
+ } else {
+ System.out.println(LOG_PREFIX + "使用匿名认证");
+ client = OpcUaClient.create(url);
+ }
+
+ client.connect().get(timeoutSeconds, TimeUnit.SECONDS);
+
+ if (validateConnection()) {
+ isConnected = true;
+ System.out.println(LOG_PREFIX + "服务器连接成功");
+ return true;
+ } else {
+ System.err.println(LOG_PREFIX + "连接验证失败");
+ return false;
+ }
+
+ } catch (Exception e) {
+ System.err.println(LOG_PREFIX + "连接失败: " + e.getMessage());
+ return false;
+ }
+ }
+
+ /**
+ * 断开连接
+ */
+ public static boolean disconnect() {
+ if (!isConnected || client == null) {
+ System.out.println(LOG_PREFIX + "客户端未连接");
+ return true;
+ }
+
+ try {
+ client.disconnect().get(5, TimeUnit.SECONDS);
+ isConnected = false;
+ client = null;
+ System.out.println(LOG_PREFIX + "连接已断开");
+ return true;
+ } catch (Exception e) {
+ System.err.println(LOG_PREFIX + "断开连接失败: " + e.getMessage());
+ return false;
+ }
+ }
+
+ /**
+ * 读取节点值
+ */
+ public static Object readValue(String nodeId) {
+ return readValue(nodeId, 10);
+ }
+
+ /**
+ * 读取节点值(自定义超时时间)
+ */
+ public static Object readValue(String nodeId, int timeoutSeconds) {
+ if (!isConnected()) {
+ System.err.println(LOG_PREFIX + "客户端未连接");
+ return null;
+ }
+
+ try {
+ NodeId id = NodeId.parse(nodeId);
+ DataValue value = client.readValue(0.0, TimestampsToReturn.Both, id)
+ .get(timeoutSeconds, TimeUnit.SECONDS);
+ Object result = value.getValue().getValue();
+ System.out.println(LOG_PREFIX + "读取节点成功: " + nodeId + " = " + result);
+ return result;
+ } catch (Exception e) {
+ System.err.println(LOG_PREFIX + "读取节点值失败[" + nodeId + "]: " + e.getMessage());
+ return null;
+ }
+ }
+
+ /**
+ * 写入节点值
+ */
+ public static boolean writeValue(String nodeId, Object value) {
+ return writeValue(nodeId, value, 10);
+ }
+
+ /**
+ * 写入节点值(自定义超时时间)
+ */
+ public static boolean writeValue(String nodeId, Object value, int timeoutSeconds) {
+ if (!isConnected()) {
+ System.err.println(LOG_PREFIX + "客户端未连接");
+ return false;
+ }
+
+ try {
+ NodeId id = NodeId.parse(nodeId);
+ DataValue dataValue = new DataValue(new Variant(value), null, null);
+
+ client.writeValue(id, dataValue).get(timeoutSeconds, TimeUnit.SECONDS);
+ System.out.println(LOG_PREFIX + "写入节点成功: " + nodeId + " = " + value);
+ return true;
+ } catch (Exception e) {
+ System.err.println(LOG_PREFIX + "写入节点值失败[" + nodeId + "]: " + e.getMessage());
+ return false;
+ }
+ }
+
+ /**
+ * 检查连接状态
+ */
+ public static boolean isConnected() {
+ if (!isConnected || client == null) return false;
+
+ try {
+ return validateConnection();
+ } catch (Exception e) {
+ isConnected = false;
+ return false;
+ }
+ }
+
+ /**
+ * 获取连接详细信息
+ */
+ public static String getConnectionInfo() {
+ if (!isConnected) {
+ return "未连接";
+ }
+ try {
+ return "已连接到: " + serverUrl;
+ } catch (Exception e) {
+ return "已连接到: " + serverUrl + ", 会话信息获取失败";
+ }
+ }
+
+ /**
+ * 验证连接有效性
+ */
+ private static boolean validateConnection() {
+ if (client == null) return false;
+
+ try {
+ NodeId rootNode = new NodeId(0, 84); // RootFolder
+ DataValue value = client.readValue(0.0, TimestampsToReturn.Both, rootNode)
+ .get(5, TimeUnit.SECONDS);
+ return value != null;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * 获取服务器URL
+ */
+ public static String getServerUrl() {
+ return serverUrl;
+ }
+
+ /**
+ * 获取客户端实例(用于高级操作)
+ */
+ public static OpcUaClient getClient() {
+ return client;
+ }
+
+ /**
+ * 显式资源清理方法
+ */
+ public static void destroy() {
+ disconnect();
+ }
+
+ /**
+ * 注册关闭钩子,确保程序退出时清理资源
+ */
+ public static void registerShutdownHook() {
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ if (isConnected) {
+ System.out.println(LOG_PREFIX + "检测到JVM关闭,正在清理OPC UA连接...");
+ disconnect();
+ }
+ }));
+ }
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
index 5fee0eb1de..472b75ce11 100644
--- a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
+++ b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
@@ -12,10 +12,7 @@ public interface ErrorCodeConstants {
ErrorCode DEVICE_NOT_EXISTS = new ErrorCode(1_003_000_000, "设备不存在");
ErrorCode DEVICE_EXISTS = new ErrorCode(1_003_000_000, "同名或同主题设备已存在");
- ErrorCode DEVICE_MODEL_NOT_EXISTS = new ErrorCode(1_003_000_000, "采集设备模型不存在");
- ErrorCode DEVICE_MODEL_ATTRIBUTE_NOT_EXISTS = new ErrorCode(1_003_000_000, "采集设备模型点位不存在");
- ErrorCode DEVICE_ATTRIBUTE_NOT_EXISTS = new ErrorCode(1_003_000_000, "设备属性不存在");
- ErrorCode DEVICE_ATTRIBUTE_TYPE_NOT_EXISTS = new ErrorCode(1_003_000_000, "采集点分类不存在");
+
ErrorCode FORMULA_NOT_EXISTS = new ErrorCode(1_003_000_000, "公式不存在");
ErrorCode FORMULA_DETAIL_NOT_EXISTS = new ErrorCode(1_003_000_000, "公式明细不存在");
ErrorCode GATEWAY_NOT_EXISTS = new ErrorCode(1_003_000_000, "网关不存在");
@@ -35,4 +32,21 @@ public interface ErrorCodeConstants {
ErrorCode ALERT_NOT_EXISTS = new ErrorCode(1_003_000_003, "告警配置不存在");
ErrorCode ALERT_RECORD_NOT_EXISTS = new ErrorCode(1_003_000_003, "告警记录不存在");
+
+ //======================================数据采集相关=================================================
+ ErrorCode DEVICE_MODEL_NOT_EXISTS = new ErrorCode(1_003_000_000, "采集设备模型不存在");
+ ErrorCode DEVICE_ID_MODEL_NOT_EXISTS = new ErrorCode(1_003_000_000, "该设备模型ID不能为空");
+
+ ErrorCode DEVICE_MODEL_ATTRIBUTE_NOT_EXISTS = new ErrorCode(1_003_000_000, "采集设备模型点位不存在");
+ ErrorCode DEVICE_ATTRIBUTE_NOT_EXISTS = new ErrorCode(1_003_000_000, "设备属性不存在");
+ ErrorCode DEVICE_ATTRIBUTE_TYPE_NOT_EXISTS = new ErrorCode(1_003_000_000, "采集点分类不存在");
+ ErrorCode ENDPOINT_DOES_NOT_EXIS = new ErrorCode(1_003_000_000, "暂未设置设备端点");
+ ErrorCode DEVICE_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "该采集设备不存在");
+ ErrorCode DEVICE_ID_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "该设备ID不能为空");
+ ErrorCode OPC_USERNAME_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "OPC连接账号不能为空");
+ ErrorCode OPC_PASSWORD_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "OPC连接账号不能为空");
+ ErrorCode OPC_CONNECT_FAILURE_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "OPC连接失败,请检测url及账号密码是否正确");
+ ErrorCode OPC_CLOSE_CONNECT_FAILURE= new ErrorCode(1_003_000_000, "OPC断开连接失败");
+ ErrorCode OPC_PARAMETER_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "连接关闭参数不存在");
+
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java
index 116bf9764a..d732e0a583 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java
@@ -9,8 +9,12 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DevicePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceSaveReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.DeviceContactModelPageReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.devicemodelattribute.vo.DeviceModelAttributePageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
+import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.iot.service.device.DeviceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -23,7 +27,9 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
+import java.util.Arrays;
import java.util.List;
+import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -54,10 +60,16 @@ public class DeviceController {
@DeleteMapping("/delete")
@Operation(summary = "删除物联设备")
- @Parameter(name = "id", description = "编号", required = true)
+ @Parameter(name = "ids", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('iot:device:delete')")
- public CommonResult deleteDevice(@RequestParam("id") Long id) {
- deviceService.deleteDevice(id);
+ public CommonResult deleteDevice(@RequestParam("ids") String ids) {
+ // 将逗号分隔的字符串转换为Long类型的List
+ List idList = Arrays.stream(ids.split(","))
+ .map(String::trim) // 去除可能存在的空格
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+
+ deviceService.deleteDevice(idList);
return success(true);
}
@@ -98,15 +110,31 @@ public class DeviceController {
return success(BeanUtils.toBean(list, DeviceDO.class));
}
+ @PostMapping("/connect")
+ @Operation(summary = "连接")
+// @PreAuthorize("@ss.hasPermission('iot:device:create')")
+ public CommonResult connectDevice(@RequestBody DeviceSaveReqVO createReqVO) {
+ return success(deviceService.connectDevice(createReqVO));
+ }
+
+
+ @PostMapping("/copy")
+ @Operation(summary = "复制设备")
+// @PreAuthorize("@ss.hasPermission('iot:device-model:create')")
+ public CommonResult copyDevice(@RequestParam("id") Long id) {
+ return success(deviceService.copyDevice(id));
+ }
+
+
+
// ==================== 子表(设备属性) ====================
@GetMapping("/device-attribute/page")
@Operation(summary = "获得设备属性分页")
@Parameter(name = "deviceId", description = "设备id")
@PreAuthorize("@ss.hasPermission('iot:device:query')")
- public CommonResult> getDeviceAttributePage(PageParam pageReqVO,
- @RequestParam("deviceId") Long deviceId) {
- return success(deviceService.getDeviceAttributePage(pageReqVO, deviceId));
+ public CommonResult> getDeviceAttributePage(PageParam pageParam, DeviceContactModelPageReqVO deviceModelAttributePageReqVO) {
+ return success(deviceService.getDeviceAttributePage(pageParam, deviceModelAttributePageReqVO));
}
@PostMapping("/device-attribute/create")
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DevicePageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DevicePageReqVO.java
index 71f520780c..f5071418ad 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DevicePageReqVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DevicePageReqVO.java
@@ -74,4 +74,7 @@ public class DevicePageReqVO extends PageParam {
@Schema(description = "密码", example = "1234")
private String password;
+ @Schema(description = "id集合导出用")
+ private String ids;
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceRespVO.java
index e1a92b0a6f..2a7f992e7b 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceRespVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceRespVO.java
@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
@@ -16,7 +17,7 @@ import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
public class DeviceRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26404")
- @ExcelProperty("ID")
+// @ExcelProperty("ID")
private Long id;
@Schema(description = "设备编号")
@@ -28,7 +29,7 @@ public class DeviceRespVO {
private String deviceName;
@Schema(description = "设备类型", example = "2")
- @ExcelProperty(value = "设备类型", converter = DictConvert.class)
+// @ExcelProperty(value = "设备类型", converter = DictConvert.class)
@DictFormat("iot_device_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private String deviceType;
@@ -38,23 +39,23 @@ public class DeviceRespVO {
private String status;
@Schema(description = "读主题")
- @ExcelProperty("读主题")
+// @ExcelProperty("读主题")
private String readTopic;
@Schema(description = "写主题")
- @ExcelProperty("写主题")
+// @ExcelProperty("写主题")
private String writeTopic;
@Schema(description = "网关id", requiredMode = Schema.RequiredMode.REQUIRED, example = "16311")
- @ExcelProperty("网关id")
+// @ExcelProperty("网关id")
private Long gatewayId;
@Schema(description = "设备品牌id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24731")
- @ExcelProperty("设备品牌id")
+// @ExcelProperty("设备品牌id")
private Long deviceBrandId;
@Schema(description = "离线间隔", requiredMode = Schema.RequiredMode.REQUIRED)
- @ExcelProperty("离线间隔")
+// @ExcelProperty("离线间隔")
private Long offLineDuration;
@Schema(description = "最后上线时间", requiredMode = Schema.RequiredMode.REQUIRED)
@@ -62,20 +63,21 @@ public class DeviceRespVO {
private LocalDateTime lastOnlineTime;
@Schema(description = "备注", example = "你说的对")
- @ExcelProperty("备注")
+// @ExcelProperty("备注")
private String remark;
@Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED)
- @ExcelProperty(value = "是否启用", converter = DictConvert.class)
+// @ExcelProperty(value = "是否启用", converter = DictConvert.class)
@DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private Boolean isEnable;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
+ @ColumnWidth(20) // 设置此列的宽度为 20 个字符的宽度
private LocalDateTime createTime;
@Schema(description = "关联设备模型", example = "1")
- @ExcelProperty("关联设备模型")
+// @ExcelProperty("关联设备模型")
private Long deviceModelId;
@Schema(description = "通讯协议", example = "OPCUA")
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceSaveReqVO.java
index d457b420d9..d512911ffd 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceSaveReqVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DeviceSaveReqVO.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
+import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
@@ -14,9 +15,11 @@ public class DeviceSaveReqVO {
private Long id;
@Schema(description = "设备编号")
+ @NotBlank(message = "设备编号不能为空") // 设备编号通常是字符串,且不能是纯空格
private String deviceCode;
@Schema(description = "设备名称", example = "赵六")
+ @NotBlank(message = "设备名称不能为空") // 设备编号通常是字符串,且不能是纯空格
private String deviceName;
@Schema(description = "设备类型", example = "2")
@@ -51,6 +54,7 @@ public class DeviceSaveReqVO {
private Boolean isEnable;
@Schema(description = "关联设备模型", example = "1")
+ @NotNull(message = "关联设备模型ID不能为空")
private Long deviceModelId;
@Schema(description = "通讯协议", example = "OPCUA")
@@ -67,4 +71,10 @@ public class DeviceSaveReqVO {
@Schema(description = "密码", example = "1234")
private String password;
+
+ @Schema(description = "是否连接1-连接 2-断开连接", example = "1")
+ @NotNull
+ private Integer isConnect;
+
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/DeviceAttributeTypeController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/DeviceAttributeTypeController.java
index cd132f5024..fcb89b025a 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/DeviceAttributeTypeController.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/DeviceAttributeTypeController.java
@@ -14,6 +14,7 @@ import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
+import java.util.stream.Collectors;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -56,10 +57,16 @@ public class DeviceAttributeTypeController {
@DeleteMapping("/delete")
@Operation(summary = "删除采集点分类")
- @Parameter(name = "id", description = "编号", required = true)
+ @Parameter(name = "ids", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('iot:device-attribute-type:delete')")
- public CommonResult deleteDeviceAttributeType(@RequestParam("id") Long id) {
- deviceAttributeTypeService.deleteDeviceAttributeType(id);
+ public CommonResult deleteDeviceAttributeType(@RequestParam("ids") String ids) {
+ // 将逗号分隔的字符串转换为Long类型的List
+ List idList = Arrays.stream(ids.split(","))
+ .map(String::trim) // 去除可能存在的空格
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+
+ deviceAttributeTypeService.deleteDeviceAttributeType(idList);
return success(true);
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypePageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypePageReqVO.java
index 38967b1d6a..107fdc98c5 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypePageReqVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypePageReqVO.java
@@ -28,4 +28,6 @@ public class DeviceAttributeTypePageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
+ @Schema(description = "id集合导出用")
+ private String ids;
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypeRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypeRespVO.java
index 6bfd9b5d7b..df644f6132 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypeRespVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypeRespVO.java
@@ -32,4 +32,9 @@ public class DeviceAttributeTypeRespVO {
@ExcelProperty("创建时间")
private LocalDateTime createTime;
+
+ @Schema(description = "排序", example = "1")
+// @ExcelProperty("排序")
+ private int sort;
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypeSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypeSaveReqVO.java
index d94802f9db..e33fbf3443 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypeSaveReqVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/deviceattributetype/vo/DeviceAttributeTypeSaveReqVO.java
@@ -23,4 +23,8 @@ public class DeviceAttributeTypeSaveReqVO {
@Schema(description = "备注", example = "随便")
private String remark;
+
+ @Schema(description = "排序",example = "2")
+ private int sort;
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/DeviceContactModelController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/DeviceContactModelController.java
new file mode 100644
index 0000000000..da68a4ded0
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/DeviceContactModelController.java
@@ -0,0 +1,103 @@
+package cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel;
+
+import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Operation;
+
+import javax.validation.constraints.*;
+import javax.validation.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.IOException;
+import java.util.stream.Collectors;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
+
+import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.*;
+import cn.iocoder.yudao.module.iot.service.devicecontactmodel.DeviceContactModelService;
+
+@Tag(name = "管理后台 - 采集设备-模型关联")
+@RestController
+@RequestMapping("/iot/device-contact-model")
+@Validated
+public class DeviceContactModelController {
+
+ @Resource
+ private DeviceContactModelService deviceContactModelService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建采集设备模型-点位管理")
+ @PreAuthorize("@ss.hasPermission('iot:device-contact-model:create')")
+ public CommonResult createDeviceContactModel(@Valid @RequestBody DeviceContactModelSaveReqVO createReqVO) {
+ return success(deviceContactModelService.createDeviceContactModel(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新采集设备模型-点位管理")
+ @PreAuthorize("@ss.hasPermission('iot:device-contact-model:update')")
+ public CommonResult updateDeviceContactModel(@Valid @RequestBody DeviceContactModelSaveReqVO updateReqVO) {
+ deviceContactModelService.updateDeviceContactModel(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除采集设备模型-点位管理")
+ @Parameter(name = "ids", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('iot:device-contact-model:delete')")
+ public CommonResult deleteDeviceContactModel(@RequestParam("ids") String ids) {
+
+ // 将逗号分隔的字符串转换为Long类型的List
+ List idList = Arrays.stream(ids.split(","))
+ .map(String::trim) // 去除可能存在的空格
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+
+ deviceContactModelService.deleteDeviceContactModel(idList);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得采集设备模型-点位管理")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('iot:device-contact-model:query')")
+ public CommonResult getDeviceContactModel(@RequestParam("id") Long id) {
+ DeviceContactModelDO deviceContactModel = deviceContactModelService.getDeviceContactModel(id);
+ return success(BeanUtils.toBean(deviceContactModel, DeviceContactModelRespVO.class));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得采集设备模型-点位管理分页")
+ @PreAuthorize("@ss.hasPermission('iot:device-contact-model:query')")
+ public CommonResult> getDeviceContactModelPage(@Valid DeviceContactModelPageReqVO pageReqVO) {
+ PageResult pageResult = deviceContactModelService.getDeviceContactModelPage(pageReqVO);
+ return success(BeanUtils.toBean(pageResult, DeviceContactModelRespVO.class));
+ }
+
+ @GetMapping("/export-excel")
+ @Operation(summary = "导出采集设备模型-点位管理 Excel")
+ @PreAuthorize("@ss.hasPermission('iot:device-contact-model:export')")
+ @ApiAccessLog(operateType = EXPORT)
+ public void exportDeviceContactModelExcel(@Valid DeviceContactModelPageReqVO pageReqVO,
+ HttpServletResponse response) throws IOException {
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+ List list = deviceContactModelService.getDeviceContactModelPage(pageReqVO).getList();
+ // 导出 Excel
+ ExcelUtils.write(response, "采集设备模型-点位管理.xls", "数据", DeviceContactModelRespVO.class,
+ BeanUtils.toBean(list, DeviceContactModelRespVO.class));
+ }
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/vo/DeviceContactModelPageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/vo/DeviceContactModelPageReqVO.java
new file mode 100644
index 0000000000..f13c632ffa
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/vo/DeviceContactModelPageReqVO.java
@@ -0,0 +1,54 @@
+package cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo;
+
+import lombok.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 采集设备模型-点位管理分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class DeviceContactModelPageReqVO extends PageParam {
+
+ @Schema(description = "id集合导出用")
+ private String ids;
+
+ @Schema(description = "设备Id")
+ private Long deviceId;
+
+ @Schema(description = "点位编码")
+ private String attributeCode;
+
+ @Schema(description = "点位名称", example = "王五")
+ private String attributeName;
+
+ @Schema(description = "点位类型", example = "1")
+ private String attributeType;
+
+ @Schema(description = "数据类型", example = "1")
+ private String dataType;
+
+ @Schema(description = "寄存器地址")
+ private String address;
+
+ @Schema(description = "单位")
+ private String dataUnit;
+
+ @Schema(description = "倍率")
+ private Double ratio;
+
+ @Schema(description = "备注", example = "你说的对")
+ private String remark;
+
+ @Schema(description = "采集设备模型id", example = "13862")
+ private Long deviceModelId;
+
+ @Schema(description = "创建时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] createTime;
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/vo/DeviceContactModelRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/vo/DeviceContactModelRespVO.java
new file mode 100644
index 0000000000..8e484ff4b4
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/vo/DeviceContactModelRespVO.java
@@ -0,0 +1,62 @@
+package cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+@Schema(description = "管理后台 - 采集设备模型-点位管理 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class DeviceContactModelRespVO {
+
+ @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "13209")
+// @ExcelProperty("ID")
+ private Long id;
+
+ @Schema(description = "点位编码", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("点位编码")
+ private String attributeCode;
+
+ @Schema(description = "点位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
+ @ExcelProperty("点位名称")
+ private String attributeName;
+
+ @Schema(description = "点位类型", example = "1")
+ @ExcelProperty("点位类型")
+ private String attributeType;
+
+ @Schema(description = "数据类型", example = "1")
+ @ExcelProperty("数据类型")
+ private String dataType;
+
+ @Schema(description = "寄存器地址")
+ @ExcelProperty("寄存器地址")
+ private String address;
+
+ @Schema(description = "单位")
+ @ExcelProperty("单位")
+ private String dataUnit;
+
+ @Schema(description = "倍率")
+ @ExcelProperty("倍率")
+ private Double ratio;
+
+ @Schema(description = "备注", example = "你说的对")
+ @ExcelProperty("备注")
+ private String remark;
+
+ @Schema(description = "采集设备模型id", requiredMode = Schema.RequiredMode.REQUIRED, example = "13862")
+ @ExcelProperty("采集设备模型id")
+ private Long deviceModelId;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+ @Schema(description = "排序", example = "1")
+ @ExcelProperty("排序")
+ private int sort;
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/vo/DeviceContactModelSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/vo/DeviceContactModelSaveReqVO.java
new file mode 100644
index 0000000000..d1c4dfe218
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicecontactmodel/vo/DeviceContactModelSaveReqVO.java
@@ -0,0 +1,47 @@
+package cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+import javax.validation.constraints.*;
+
+@Schema(description = "管理后台 - 采集设备模型-点位管理新增/修改 Request VO")
+@Data
+public class DeviceContactModelSaveReqVO {
+
+ @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "13209")
+ private Long id;
+
+ @Schema(description = "点位编码", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotEmpty(message = "点位编码不能为空")
+ private String attributeCode;
+
+ @Schema(description = "点位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
+ @NotEmpty(message = "点位名称不能为空")
+ private String attributeName;
+
+ @Schema(description = "点位类型", example = "1")
+ private String attributeType;
+
+ @Schema(description = "数据类型", example = "1")
+ private String dataType;
+
+ @Schema(description = "寄存器地址")
+ private String address;
+
+ @Schema(description = "单位")
+ private String dataUnit;
+
+ @Schema(description = "倍率")
+ private Double ratio;
+
+ @Schema(description = "备注", example = "你说的对")
+ private String remark;
+
+ @Schema(description = "采集设备模型id", requiredMode = Schema.RequiredMode.REQUIRED, example = "13862")
+ @NotNull(message = "采集设备模型id不能为空")
+ private Long deviceId;
+
+ @Schema(description = "排序", example = "2")
+ private int sort;
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/DeviceModelController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/DeviceModelController.java
index 98ba52b72c..55dca02e17 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/DeviceModelController.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/DeviceModelController.java
@@ -14,6 +14,7 @@ import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
+import java.util.stream.Collectors;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -56,10 +57,16 @@ public class DeviceModelController {
@DeleteMapping("/delete")
@Operation(summary = "删除采集设备模型")
- @Parameter(name = "id", description = "编号", required = true)
+ @Parameter(name = "ids", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('iot:device-model:delete')")
- public CommonResult deleteDeviceModel(@RequestParam("id") Long id) {
- deviceModelService.deleteDeviceModel(id);
+ public CommonResult deleteDeviceModel(@RequestParam("ids") String ids) {
+ // 将逗号分隔的字符串转换为Long类型的List
+ List idList = Arrays.stream(ids.split(","))
+ .map(String::trim) // 去除可能存在的空格
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+ deviceModelService.deleteDeviceModel(idList);
+
return success(true);
}
@@ -101,4 +108,13 @@ public class DeviceModelController {
}
+
+ @PostMapping("/copy")
+ @Operation(summary = "复制设备模型")
+ @PreAuthorize("@ss.hasPermission('iot:device-model:create')")
+ public CommonResult copyDevice(@RequestParam("id") Long id) {
+ return success(deviceModelService.copyDevice(id));
+ }
+
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelPageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelPageReqVO.java
index 81aaff7b38..1cf72c0d75 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelPageReqVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelPageReqVO.java
@@ -31,4 +31,7 @@ public class DeviceModelPageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
+ @Schema(description = "id集合导出用")
+ private String ids;
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelRespVO.java
index 3216c62aab..ee93cb7fe8 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelRespVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodel/vo/DeviceModelRespVO.java
@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.iot.controller.admin.devicemodel.vo;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
@@ -13,7 +14,7 @@ import com.alibaba.excel.annotation.*;
public class DeviceModelRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30028")
- @ExcelProperty("ID")
+// @ExcelProperty("ID")
private Long id;
@Schema(description = "分类编码", requiredMode = Schema.RequiredMode.REQUIRED)
@@ -34,6 +35,7 @@ public class DeviceModelRespVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
+ @ColumnWidth(20) // 设置此列的宽度为 20 个字符的宽度
private LocalDateTime createTime;
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/DeviceModelAttributeController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/DeviceModelAttributeController.java
index cc7a221a7a..fd27c9cf42 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/DeviceModelAttributeController.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/DeviceModelAttributeController.java
@@ -13,6 +13,7 @@ import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
+import java.util.stream.Collectors;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -55,10 +56,15 @@ public class DeviceModelAttributeController {
@DeleteMapping("/delete")
@Operation(summary = "删除采集设备模型-点位管理")
- @Parameter(name = "id", description = "编号", required = true)
+ @Parameter(name = "ids", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('iot:device-model-attribute:delete')")
- public CommonResult deleteDeviceModelAttribute(@RequestParam("id") Long id) {
- deviceModelAttributeService.deleteDeviceModelAttribute(id);
+ public CommonResult deleteDeviceModelAttribute(@RequestParam("ids") String ids) {
+ // 将逗号分隔的字符串转换为Long类型的List
+ List idList = Arrays.stream(ids.split(","))
+ .map(String::trim) // 去除可能存在的空格
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+ deviceModelAttributeService.deleteDeviceModelAttribute(idList);
return success(true);
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/vo/DeviceModelAttributePageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/vo/DeviceModelAttributePageReqVO.java
index 8cb01b5ebe..e55603f0ec 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/vo/DeviceModelAttributePageReqVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/vo/DeviceModelAttributePageReqVO.java
@@ -15,6 +15,9 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class DeviceModelAttributePageReqVO extends PageParam {
+ @Schema(description = "id")
+ private Long id;
+
@Schema(description = "点位编码")
private String attributeCode;
@@ -46,4 +49,7 @@ public class DeviceModelAttributePageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
+ @Schema(description = "id集合导出用")
+ private String ids;
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/vo/DeviceModelAttributeRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/vo/DeviceModelAttributeRespVO.java
index 01829d462d..75eca2e631 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/vo/DeviceModelAttributeRespVO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/devicemodelattribute/vo/DeviceModelAttributeRespVO.java
@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.iot.controller.admin.devicemodelattribute.vo;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
@@ -13,7 +14,7 @@ import com.alibaba.excel.annotation.*;
public class DeviceModelAttributeRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "18518")
- @ExcelProperty("ID")
+// @ExcelProperty("ID")
private Long id;
@Schema(description = "点位编码", requiredMode = Schema.RequiredMode.REQUIRED)
@@ -54,6 +55,7 @@ public class DeviceModelAttributeRespVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
+ @ColumnWidth(20) // 设置此列的宽度为 20 个字符的宽度
private LocalDateTime createTime;
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/DeviceDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/DeviceDO.java
index 06ec68026e..a0c01b6dc0 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/DeviceDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/DeviceDO.java
@@ -106,4 +106,6 @@ public class DeviceDO extends BaseDO {
* 密码
*/
private String password;
+
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/deviceattributetype/DeviceAttributeTypeDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/deviceattributetype/DeviceAttributeTypeDO.java
index 218584a235..ef5812ee11 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/deviceattributetype/DeviceAttributeTypeDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/deviceattributetype/DeviceAttributeTypeDO.java
@@ -39,5 +39,9 @@ public class DeviceAttributeTypeDO extends BaseDO {
* 备注
*/
private String remark;
+ /**
+ * 排序
+ */
+ private int sort;
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/devicemodelattribute/DeviceModelAttributeDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/devicemodelattribute/DeviceModelAttributeDO.java
index 660d63b7ad..887f78eea3 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/devicemodelattribute/DeviceModelAttributeDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/devicemodelattribute/DeviceModelAttributeDO.java
@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute;
+import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
@@ -23,45 +24,54 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
public class DeviceModelAttributeDO extends BaseDO {
/**
- * ID
+ *
*/
@TableId
private Long id;
/**
* 点位编码
*/
+ @Schema(description = "点位编码")
private String attributeCode;
/**
* 点位名称
*/
+ @Schema(description = "点位名称")
private String attributeName;
/**
* 点位类型
*/
+ @Schema(description = "点位类型")
private String attributeType;
/**
* 数据类型
*/
+ @Schema(description = "数据类型")
private String dataType;
/**
* 寄存器地址
*/
+ @Schema(description = "寄存器地址")
private String address;
/**
* 单位
*/
+ @Schema(description = "单位")
private String dataUnit;
/**
* 倍率
*/
+ @Schema(description = "倍率")
private Double ratio;
/**
* 备注
*/
+ @Schema(description = "备注")
private String remark;
/**
* 采集设备模型id
*/
+ @Schema(description = "采集设备模型id")
private Long deviceModelId;
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/devicecontactmodel/DeviceContactModelDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/devicecontactmodel/DeviceContactModelDO.java
new file mode 100644
index 0000000000..4e5855840c
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/devicecontactmodel/DeviceContactModelDO.java
@@ -0,0 +1,71 @@
+package cn.iocoder.yudao.module.iot.dal.devicecontactmodel;
+
+import lombok.*;
+import java.util.*;
+import java.time.LocalDateTime;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * 采集设备模型-点位管理 DO
+ *
+ * @author 内蒙必硕
+ */
+@TableName("iot_device_contact_model")
+@KeySequence("iot_device_contact_model_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DeviceContactModelDO extends BaseDO {
+
+ /**
+ * ID
+ */
+ @TableId
+ private Long id;
+ /**
+ * 点位编码
+ */
+ private String attributeCode;
+ /**
+ * 点位名称
+ */
+ private String attributeName;
+ /**
+ * 点位类型
+ */
+ private String attributeType;
+ /**
+ * 数据类型
+ */
+ private String dataType;
+ /**
+ * 寄存器地址
+ */
+ private String address;
+ /**
+ * 单位
+ */
+ private String dataUnit;
+ /**
+ * 倍率
+ */
+ private Double ratio;
+ /**
+ * 备注
+ */
+ private String remark;
+ /**
+ * 采集设备模型id
+ */
+ private Long deviceId;
+ /**
+ * 排序
+ */
+ private int sort;
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java
index 6989d880d8..2f23f9c655 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/DeviceMapper.java
@@ -6,9 +6,12 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DevicePageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
+import com.alibaba.excel.util.StringUtils;
import org.apache.ibatis.annotations.Mapper;
+import java.util.Arrays;
import java.util.List;
+import java.util.stream.Collectors;
/**
* 物联设备 Mapper
@@ -19,8 +22,9 @@ import java.util.List;
public interface DeviceMapper extends BaseMapperX {
default PageResult selectPage(DevicePageReqVO reqVO) {
- return selectPage(reqVO, new LambdaQueryWrapperX()
- .eqIfPresent(DeviceDO::getDeviceCode, reqVO.getDeviceCode())
+
+ LambdaQueryWrapperX deviceDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
+ deviceDOLambdaQueryWrapperX.likeIfPresent(DeviceDO::getDeviceCode, reqVO.getDeviceCode())
.likeIfPresent(DeviceDO::getDeviceName, reqVO.getDeviceName())
.eqIfPresent(DeviceDO::getDeviceType, reqVO.getDeviceType())
.eqIfPresent(DeviceDO::getStatus, reqVO.getStatus())
@@ -33,8 +37,22 @@ public interface DeviceMapper extends BaseMapperX {
.eqIfPresent(DeviceDO::getRemark, reqVO.getRemark())
.eqIfPresent(DeviceDO::getIsEnable, reqVO.getIsEnable())
.betweenIfPresent(DeviceDO::getCreateTime, reqVO.getCreateTime())
- .orderByDesc(DeviceDO::getId));
+ .orderByDesc(DeviceDO::getCreateTime);
+
+ // 单独处理 ids 条件
+ if (StringUtils.isNotBlank(reqVO.getIds())) {
+ List idList = Arrays.stream(reqVO.getIds().split(","))
+ .map(String::trim)
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+ deviceDOLambdaQueryWrapperX.in(DeviceDO::getId, idList);
+ }
+
+ PageResult deviceDOPageResult = selectPage(reqVO, deviceDOLambdaQueryWrapperX);
+
+ return deviceDOPageResult;
}
+
default PageResult selectPage(PageParam reqVO, Long gatewayId) {
return selectPage(reqVO, new LambdaQueryWrapperX()
.eq(DeviceDO::getGatewayId, gatewayId)
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/deviceattributetype/DeviceAttributeTypeMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/deviceattributetype/DeviceAttributeTypeMapper.java
index 3af6cc7719..a01f15cb23 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/deviceattributetype/DeviceAttributeTypeMapper.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/deviceattributetype/DeviceAttributeTypeMapper.java
@@ -1,12 +1,17 @@
package cn.iocoder.yudao.module.iot.dal.mysql.deviceattributetype;
import java.util.*;
+import java.util.stream.Collectors;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodel.DeviceModelDO;
+import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
+import com.alibaba.excel.util.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.iot.controller.admin.deviceattributetype.vo.*;
@@ -18,13 +23,29 @@ import cn.iocoder.yudao.module.iot.controller.admin.deviceattributetype.vo.*;
@Mapper
public interface DeviceAttributeTypeMapper extends BaseMapperX {
+
default PageResult selectPage(DeviceAttributeTypePageReqVO reqVO) {
- return selectPage(reqVO, new LambdaQueryWrapperX()
+
+
+ LambdaQueryWrapperX deviceAttributeTypeDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
+ deviceAttributeTypeDOLambdaQueryWrapperX
.eqIfPresent(DeviceAttributeTypeDO::getCode, reqVO.getCode())
.likeIfPresent(DeviceAttributeTypeDO::getName, reqVO.getName())
.eqIfPresent(DeviceAttributeTypeDO::getRemark, reqVO.getRemark())
.betweenIfPresent(DeviceAttributeTypeDO::getCreateTime, reqVO.getCreateTime())
- .orderByDesc(DeviceAttributeTypeDO::getId));
+ .orderByAsc(DeviceAttributeTypeDO::getSort);
+
+ if (StringUtils.isNotBlank(reqVO.getIds())) {
+ List idList = Arrays.stream(reqVO.getIds().split(","))
+ .map(String::trim)
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+ deviceAttributeTypeDOLambdaQueryWrapperX.in(DeviceAttributeTypeDO::getId, idList);
+ }
+
+
+ return selectPage(reqVO, deviceAttributeTypeDOLambdaQueryWrapperX);
+
}
default List select() {
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicecontactmodel/DeviceContactModelMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicecontactmodel/DeviceContactModelMapper.java
new file mode 100644
index 0000000000..9f5d5730eb
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicecontactmodel/DeviceContactModelMapper.java
@@ -0,0 +1,66 @@
+package cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.iot.controller.admin.devicemodelattribute.vo.DeviceModelAttributePageReqVO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
+import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
+import com.alibaba.excel.util.StringUtils;
+import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.*;
+
+/**
+ * 采集设备模型-点位管理 Mapper
+ *
+ * @author 内蒙必硕
+ */
+@Mapper
+public interface DeviceContactModelMapper extends BaseMapperX {
+
+ default PageResult selectPageById(PageParam reqVO, DeviceContactModelPageReqVO device) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ // 使用StringUtils.hasText()进行更严格的字符串非空判断
+ .like(device.getAttributeCode() != null && StringUtils.isNotBlank(device.getAttributeCode()), DeviceContactModelDO::getAttributeCode, device.getAttributeCode())
+ .like(device.getAttributeName() != null && StringUtils.isNotBlank(device.getAttributeName()), DeviceContactModelDO::getAttributeName, device.getAttributeName())
+ // 对于枚举或数值类型,使用Objects.nonNull()判断
+ .eq(Objects.nonNull(device.getAttributeType()), DeviceContactModelDO::getAttributeType, device.getAttributeType())
+ // 必要的条件(如deviceModelId)保留直接eq条件
+ .eq(DeviceContactModelDO::getDeviceId, device.getDeviceId())
+ .orderByAsc(DeviceContactModelDO::getSort));
+ }
+
+
+ default PageResult selectPage(DeviceContactModelPageReqVO reqVO) {
+
+ LambdaQueryWrapperX deviceContactModelDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
+ deviceContactModelDOLambdaQueryWrapperX.eqIfPresent(DeviceContactModelDO::getAttributeCode, reqVO.getAttributeCode())
+ .likeIfPresent(DeviceContactModelDO::getAttributeName, reqVO.getAttributeName())
+ .eqIfPresent(DeviceContactModelDO::getAttributeType, reqVO.getAttributeType())
+ .eqIfPresent(DeviceContactModelDO::getDataType, reqVO.getDataType())
+ .eqIfPresent(DeviceContactModelDO::getAddress, reqVO.getAddress())
+ .eqIfPresent(DeviceContactModelDO::getDataUnit, reqVO.getDataUnit())
+ .eqIfPresent(DeviceContactModelDO::getRatio, reqVO.getRatio())
+ .eqIfPresent(DeviceContactModelDO::getRemark, reqVO.getRemark())
+ .eqIfPresent(DeviceContactModelDO::getDeviceId, reqVO.getDeviceId())
+ .betweenIfPresent(DeviceContactModelDO::getCreateTime, reqVO.getCreateTime());
+
+ if (reqVO.getIds()!=null && StringUtils.isNotBlank(reqVO.getIds())) {
+ List idList = Arrays.stream(reqVO.getIds().split(","))
+ .map(String::trim)
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+ deviceContactModelDOLambdaQueryWrapperX.in(DeviceContactModelDO::getId, idList);
+ }
+
+ PageResult deviceContactModelDOPageResult = selectPage(reqVO, deviceContactModelDOLambdaQueryWrapperX);
+
+ return deviceContactModelDOPageResult;
+ }
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicemodelattribute/DeviceModelAttributeMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicemodelattribute/DeviceModelAttributeMapper.java
index bbeb59a938..f33cb9ad72 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicemodelattribute/DeviceModelAttributeMapper.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/devicemodelattribute/DeviceModelAttributeMapper.java
@@ -1,11 +1,16 @@
package cn.iocoder.yudao.module.iot.dal.mysql.devicemodelattribute;
import java.util.*;
+import java.util.stream.Collectors;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
+import com.alibaba.excel.util.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.iot.controller.admin.devicemodelattribute.vo.*;
@@ -17,9 +22,24 @@ import cn.iocoder.yudao.module.iot.controller.admin.devicemodelattribute.vo.*;
@Mapper
public interface DeviceModelAttributeMapper extends BaseMapperX {
- default PageResult selectPage(DeviceModelAttributePageReqVO reqVO) {
+
+ default PageResult selectPageById(PageParam reqVO, DeviceModelAttributePageReqVO device) {
return selectPage(reqVO, new LambdaQueryWrapperX()
- .eqIfPresent(DeviceModelAttributeDO::getAttributeCode, reqVO.getAttributeCode())
+ // 使用StringUtils.hasText()进行更严格的字符串非空判断
+ .like(StringUtils.isNotBlank(device.getAttributeCode()), DeviceModelAttributeDO::getAttributeCode, device.getAttributeCode())
+ .like(StringUtils.isNotBlank(device.getAttributeName()), DeviceModelAttributeDO::getAttributeName, device.getAttributeName())
+ // 对于枚举或数值类型,使用Objects.nonNull()判断
+ .eq(Objects.nonNull(device.getAttributeType()), DeviceModelAttributeDO::getAttributeType, device.getAttributeType())
+ // 必要的条件(如deviceModelId)保留直接eq条件
+ .eq(DeviceModelAttributeDO::getDeviceModelId, device.getDeviceModelId())
+ .orderByDesc(DeviceModelAttributeDO::getId));
+ }
+
+
+ default PageResult selectPage(DeviceModelAttributePageReqVO reqVO) {
+
+ LambdaQueryWrapperX deviceModelAttributeDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
+ deviceModelAttributeDOLambdaQueryWrapperX.eqIfPresent(DeviceModelAttributeDO::getAttributeCode, reqVO.getAttributeCode())
.likeIfPresent(DeviceModelAttributeDO::getAttributeName, reqVO.getAttributeName())
.eqIfPresent(DeviceModelAttributeDO::getAttributeType, reqVO.getAttributeType())
.eqIfPresent(DeviceModelAttributeDO::getDataType, reqVO.getDataType())
@@ -27,9 +47,22 @@ public interface DeviceModelAttributeMapper extends BaseMapperX idList = Arrays.stream(reqVO.getIds().split(","))
+ .map(String::trim)
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+ deviceModelAttributeDOLambdaQueryWrapperX.in(DeviceModelAttributeDO::getId,idList);
+ }
+
+ PageResult deviceModelAttributeDOPageResult = selectPage(reqVO, deviceModelAttributeDOLambdaQueryWrapperX);
+ return deviceModelAttributeDOPageResult;
+
}
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java
index b118dd5403..2530aa159e 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java
@@ -6,8 +6,12 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DevicePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceSaveReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.DeviceContactModelPageReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.devicemodelattribute.vo.DeviceModelAttributePageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
+import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
import javax.validation.Valid;
import java.util.Collection;
@@ -42,7 +46,7 @@ public interface DeviceService {
*
* @param id 编号
*/
- void deleteDevice(Long id);
+ void deleteDevice(List ids);
/**
* 获得物联设备
@@ -78,7 +82,7 @@ public interface DeviceService {
* @param deviceId 设备id
* @return 设备属性分页
*/
- PageResult getDeviceAttributePage(PageParam pageReqVO, Long deviceId);
+ PageResult getDeviceAttributePage(PageParam pageReqVO, DeviceContactModelPageReqVO deviceModelAttributePageReqVO);
/**
* 创建设备属性
@@ -111,5 +115,7 @@ public interface DeviceService {
DeviceAttributeDO getDeviceAttribute(Long id);
+ Boolean connectDevice(DeviceSaveReqVO createReqVO);
+ Long copyDevice(Long id);
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
index 6843ad5c92..bd8506372a 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
@@ -1,20 +1,33 @@
package cn.iocoder.yudao.module.iot.service.device;
import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.enums.DeviceConnectionStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.common.util.opc.OpcUtils;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DevicePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceSaveReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.DeviceContactModelPageReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.devicemodelattribute.vo.DeviceModelAttributePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.mqttdatarecord.vo.MqttDataRecordPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodel.DeviceModelDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.mqttdatarecord.MqttDataRecordDO;
+import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
+import cn.iocoder.yudao.module.iot.dal.mysql.deviceattributetype.DeviceAttributeTypeMapper;
+import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper;
+import cn.iocoder.yudao.module.iot.dal.mysql.devicemodel.DeviceModelMapper;
+import cn.iocoder.yudao.module.iot.dal.mysql.devicemodelattribute.DeviceModelAttributeMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.mqttdatarecord.MqttDataRecordMapper;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceAttributeDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceAttributeMapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -22,9 +35,7 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
@@ -43,9 +54,21 @@ public class DeviceServiceImpl implements DeviceService {
@Resource
private DeviceAttributeMapper deviceAttributeMapper;
+ @Resource
+ private DeviceModelMapper deviceModelMapper;
+
+
+ @Resource
+ private DeviceModelAttributeMapper deviceModelAttributeMapper;
+
+ @Resource
+ private DeviceContactModelMapper deviceContactModelMapper;
+
@Resource
private MqttDataRecordMapper mqttDataRecordMapper;
+
@Override
+ @Transactional(rollbackFor = Exception.class)
public Long createDevice(DeviceSaveReqVO createReqVO) {
if(StringUtils.isNotBlank(createReqVO.getReadTopic())){
DeviceDO temp = deviceMapper.selectByTopic(createReqVO.getReadTopic());
@@ -53,12 +76,34 @@ public class DeviceServiceImpl implements DeviceService {
throw exception(DEVICE_EXISTS);
}
}
+
+ DeviceModelDO deviceModelDO = deviceModelMapper.selectById(createReqVO.getDeviceModelId());
+
// 插入
DeviceDO device = BeanUtils.toBean(createReqVO, DeviceDO.class);
+ device.setProtocol(deviceModelDO != null ? deviceModelDO.getProtocol() : "");
deviceMapper.insert(device);
+
+ LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
+ lambdaQueryWrapper.eq(DeviceModelAttributeDO::getDeviceModelId,createReqVO.getDeviceModelId());
+ List deviceModelAttributeDOS = deviceModelAttributeMapper.selectList(lambdaQueryWrapper);
+
+ List contactModelList = new ArrayList<>();
+ for (DeviceModelAttributeDO attributeDO : deviceModelAttributeDOS) {
+ DeviceContactModelDO contactModel = new DeviceContactModelDO();
+ BeanUtils.copyProperties(attributeDO, contactModel);
+ contactModel.setId(null);
+ contactModel.setDeviceId(device.getId());
+ contactModel.setCreateTime(LocalDateTime.now());
+ contactModel.setUpdateTime(LocalDateTime.now());
+ contactModelList.add(contactModel);
+ }
+ deviceContactModelMapper.insertBatch(contactModelList);
+
// 返回
return device.getId();
}
+
//@Scheduled(cron="0/5 * * * * ? ") //每1秒执行一次
public void updateDeviceStatus(){
List list = deviceMapper.selectList();
@@ -91,14 +136,22 @@ public class DeviceServiceImpl implements DeviceService {
@Override
@Transactional(rollbackFor = Exception.class)
- public void deleteDevice(Long id) {
- // 校验存在
- validateDeviceExists(id);
- // 删除
- deviceMapper.deleteById(id);
+ public void deleteDevice(List ids) {
+ for (Long id : ids) {
+ // 校验存在
+ validateDeviceExists(id);
+// // 删除
+// deviceMapper.deleteById(id);
+ // 删除子表
+ deleteDeviceConcatByDeviceId(id);
+ }
+ deviceMapper.deleteByIds(ids);
+ }
- // 删除子表
- deleteDeviceAttributeByDeviceId(id);
+ private void deleteDeviceConcatByDeviceId(Long id) {
+ LambdaQueryWrapper deviceContactModelDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
+ deviceContactModelDOLambdaQueryWrapper.eq(DeviceContactModelDO::getDeviceId,id);
+ deviceContactModelMapper.delete(deviceContactModelDOLambdaQueryWrapper);
}
private void validateDeviceExists(Long id) {
@@ -131,8 +184,23 @@ public class DeviceServiceImpl implements DeviceService {
// ==================== 子表(设备属性) ====================
@Override
- public PageResult getDeviceAttributePage(PageParam pageReqVO, Long deviceId) {
- return deviceAttributeMapper.selectPage(pageReqVO, deviceId);
+ public PageResult getDeviceAttributePage(PageParam pageReqVO, DeviceContactModelPageReqVO deviceModelAttributePageReqVO) {
+ // 参数校验
+ if (deviceModelAttributePageReqVO.getDeviceId() == null) {
+ throw new IllegalArgumentException("关联设备模型ID不能为空");
+ }
+
+ // 查询设备信息,只查询一次
+ DeviceDO device = deviceMapper.selectById(deviceModelAttributePageReqVO.getDeviceId());
+ if (device == null) {
+ return new PageResult<>();
+ }
+ deviceModelAttributePageReqVO.setDeviceId(device.getId());
+ // 判断设备模型ID是否有效
+ PageResult deviceModelAttributeDOPageResult = deviceContactModelMapper.selectPageById(pageReqVO, deviceModelAttributePageReqVO);
+ return deviceModelAttributeDOPageResult;
+
+
}
@Override
@@ -162,6 +230,93 @@ public class DeviceServiceImpl implements DeviceService {
return deviceAttributeMapper.selectById(id);
}
+ @Override
+ public Boolean connectDevice(DeviceSaveReqVO createReqVO) {
+
+ // 前置校验
+ DeviceDO deviceDO = validateConnectRequest(createReqVO);
+
+ if (Objects.equals(createReqVO.getIsConnect(), DeviceConnectionStatusEnum.CONNECTED.getStatus())){
+ boolean connected = OpcUtils.connect(deviceDO.getUrl(),createReqVO.getUsername(),createReqVO.getPassword(),10);
+ if (connected){
+ deviceDO.setStatus(String.valueOf(DeviceConnectionStatusEnum.CONNECTED.getStatus()));
+ deviceMapper.updateById(deviceDO);
+ }else {
+ throw exception(OPC_CONNECT_FAILURE_DOES_NOT_EXIST);
+ }
+ }else if(Objects.equals(createReqVO.getIsConnect(), DeviceConnectionStatusEnum.DISCONNECTED.getStatus())){
+ boolean disconnect = OpcUtils.disconnect();
+ if (disconnect){
+ deviceDO.setStatus(String.valueOf(DeviceConnectionStatusEnum.DISCONNECTED.getStatus()));
+ deviceMapper.updateById(deviceDO);
+ }else {
+ throw exception(OPC_CLOSE_CONNECT_FAILURE);
+ }
+ }else {
+ throw exception(OPC_PARAMETER_DOES_NOT_EXIST);
+ }
+
+ return Boolean.TRUE;
+ }
+
+ private DeviceDO validateConnectRequest(DeviceSaveReqVO createReqVO) {
+ if(createReqVO.getId() == null){
+ throw exception(DEVICE_ID_DOES_NOT_EXIST);
+ }
+ DeviceDO deviceDO = deviceMapper.selectById(createReqVO.getId());
+ if (deviceDO == null){
+ throw exception(DEVICE_DOES_NOT_EXIST);
+
+ }
+ if (StringUtils.isBlank(deviceDO.getUrl())){
+ throw exception(ENDPOINT_DOES_NOT_EXIS);
+ }
+ if (StringUtils.isBlank(deviceDO.getUsername())){
+ throw exception(OPC_USERNAME_DOES_NOT_EXIST);
+ }
+ if (StringUtils.isBlank(deviceDO.getPassword())){
+ throw exception(OPC_PASSWORD_DOES_NOT_EXIST);
+ }
+ return deviceDO;
+ }
+
+ @Override
+ public Long copyDevice(Long id) {
+ if (id == null){
+ throw exception(DEVICE_ID_MODEL_NOT_EXISTS);
+ }
+ DeviceDO deviceDO = deviceMapper.selectById(id);
+ if(deviceDO == null){
+ throw exception(DEVICE_DOES_NOT_EXIST);
+ }
+ //复制实体类
+ DeviceDO newDevice = new DeviceDO();
+ BeanUtils.copyProperties(deviceDO, newDevice);
+ newDevice.setId(null);
+ Random random = new Random();
+ int randomNumber = random.nextInt(9000) + 1000;
+ newDevice.setDeviceCode(deviceDO.getDeviceCode()+ "-" + randomNumber);
+ newDevice.setDeviceName(deviceDO.getDeviceName() + "-副本");
+ deviceMapper.insert(newDevice);
+
+ //复制关联表
+ LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper();
+ lambdaQueryWrapper.eq(DeviceContactModelDO::getDeviceId,deviceDO.getId());
+ List deviceContactModelDOS = deviceContactModelMapper.selectList(lambdaQueryWrapper);
+
+
+ if (deviceContactModelDOS != null && !deviceContactModelDOS.isEmpty()){
+ for (DeviceContactModelDO deviceModelAttributeDOS : deviceContactModelDOS) {
+ deviceModelAttributeDOS.setId(null);
+ deviceModelAttributeDOS.setDeviceId(newDevice.getId());
+ }
+ deviceContactModelMapper.insertBatch(deviceContactModelDOS);
+ }
+
+ return newDevice.getId();
+
+ }
+
private void validateDeviceAttributeExists(Long id) {
if (deviceAttributeMapper.selectById(id) == null) {
throw exception(DEVICE_ATTRIBUTE_NOT_EXISTS);
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeService.java
index 3e7877538b..b28e978d4e 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeService.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeService.java
@@ -35,7 +35,7 @@ public interface DeviceAttributeTypeService {
*
* @param id 编号
*/
- void deleteDeviceAttributeType(Long id);
+ void deleteDeviceAttributeType( List ids);
/**
* 获得采集点分类
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeServiceImpl.java
index ac3d38fbfb..44ceac5edf 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeServiceImpl.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeServiceImpl.java
@@ -49,11 +49,14 @@ public class DeviceAttributeTypeServiceImpl implements DeviceAttributeTypeServic
}
@Override
- public void deleteDeviceAttributeType(Long id) {
- // 校验存在
- validateDeviceAttributeTypeExists(id);
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteDeviceAttributeType( List ids) {
+ for (Long id : ids) {
+ // 校验存在
+ validateDeviceAttributeTypeExists(id);
+ }
// 删除
- deviceAttributeTypeMapper.deleteById(id);
+ deviceAttributeTypeMapper.deleteByIds(ids);
}
private void validateDeviceAttributeTypeExists(Long id) {
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicecontactmodel/DeviceContactModelService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicecontactmodel/DeviceContactModelService.java
new file mode 100644
index 0000000000..642f073c25
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicecontactmodel/DeviceContactModelService.java
@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.module.iot.service.devicecontactmodel;
+
+import javax.validation.*;
+import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.*;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
+
+import java.util.List;
+
+/**
+ * 采集设备模型-点位管理 Service 接口
+ *
+ * @author 内蒙必硕
+ */
+public interface DeviceContactModelService {
+
+ /**
+ * 创建采集设备模型-点位管理
+ *
+ * @param createReqVO 创建信息
+ * @return 编号
+ */
+ Long createDeviceContactModel(@Valid DeviceContactModelSaveReqVO createReqVO);
+
+ /**
+ * 更新采集设备模型-点位管理
+ *
+ * @param updateReqVO 更新信息
+ */
+ void updateDeviceContactModel(@Valid DeviceContactModelSaveReqVO updateReqVO);
+
+ /**
+ * 删除采集设备模型-点位管理
+ *
+ * @param id 编号
+ */
+ void deleteDeviceContactModel(List id);
+
+ /**
+ * 获得采集设备模型-点位管理
+ *
+ * @param id 编号
+ * @return 采集设备模型-点位管理
+ */
+ DeviceContactModelDO getDeviceContactModel(Long id);
+
+ /**
+ * 获得采集设备模型-点位管理分页
+ *
+ * @param pageReqVO 分页查询
+ * @return 采集设备模型-点位管理分页
+ */
+ PageResult getDeviceContactModelPage(DeviceContactModelPageReqVO pageReqVO);
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicecontactmodel/DeviceContactModelServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicecontactmodel/DeviceContactModelServiceImpl.java
new file mode 100644
index 0000000000..92009d5576
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicecontactmodel/DeviceContactModelServiceImpl.java
@@ -0,0 +1,76 @@
+package cn.iocoder.yudao.module.iot.service.devicecontactmodel;
+
+import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+
+import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.*;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+
+import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper;
+
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.DEVICE_CONTACT_MODEL_NOT_EXISTS;
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+
+/**
+ * 采集设备模型-点位管理 Service 实现类
+ *
+ * @author 内蒙必硕
+ */
+@Service
+@Validated
+public class DeviceContactModelServiceImpl implements DeviceContactModelService {
+
+ @Resource
+ private DeviceContactModelMapper deviceContactModelMapper;
+
+ @Override
+ public Long createDeviceContactModel(DeviceContactModelSaveReqVO createReqVO) {
+ // 插入
+ DeviceContactModelDO deviceContactModel = BeanUtils.toBean(createReqVO, DeviceContactModelDO.class);
+ deviceContactModelMapper.insert(deviceContactModel);
+ // 返回
+ return deviceContactModel.getId();
+ }
+
+ @Override
+ public void updateDeviceContactModel(DeviceContactModelSaveReqVO updateReqVO) {
+ // 校验存在
+ validateDeviceContactModelExists(updateReqVO.getId());
+ // 更新
+ DeviceContactModelDO updateObj = BeanUtils.toBean(updateReqVO, DeviceContactModelDO.class);
+ deviceContactModelMapper.updateById(updateObj);
+ }
+
+ @Override
+ public void deleteDeviceContactModel(List ids) {
+ for (Long id : ids) {
+ // 校验存在
+ validateDeviceContactModelExists(id);
+ // 删除
+ deviceContactModelMapper.deleteById(id);
+ }
+ }
+
+ private void validateDeviceContactModelExists(Long id) {
+ if (deviceContactModelMapper.selectById(id) == null) {
+ throw exception(DEVICE_CONTACT_MODEL_NOT_EXISTS);
+ }
+ }
+
+ @Override
+ public DeviceContactModelDO getDeviceContactModel(Long id) {
+ DeviceContactModelDO deviceContactModelDO = deviceContactModelMapper.selectById(id);
+ return deviceContactModelDO;
+ }
+
+ @Override
+ public PageResult getDeviceContactModelPage(DeviceContactModelPageReqVO pageReqVO) {
+ return deviceContactModelMapper.selectPage(pageReqVO);
+ }
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodel/DeviceModelService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodel/DeviceModelService.java
index 52aba64a49..772af9a742 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodel/DeviceModelService.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodel/DeviceModelService.java
@@ -35,7 +35,7 @@ public interface DeviceModelService {
*
* @param id 编号
*/
- void deleteDeviceModel(Long id);
+ void deleteDeviceModel(List idList);
/**
* 获得采集设备模型
@@ -58,4 +58,11 @@ public interface DeviceModelService {
* @return 采集设备模型列表
*/
List getDeviceModelList();
+
+ /**
+ * 复制设备模型
+ *
+ * @return 复制设备模型
+ */
+ Long copyDevice(Long id);
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodel/DeviceModelServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodel/DeviceModelServiceImpl.java
index 3778d5eb4e..2d0bf36ec8 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodel/DeviceModelServiceImpl.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodel/DeviceModelServiceImpl.java
@@ -1,11 +1,18 @@
package cn.iocoder.yudao.module.iot.service.devicemodel;
+import cn.hutool.core.bean.BeanUtil;
+import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
+import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
+import cn.iocoder.yudao.module.iot.dal.mysql.devicemodelattribute.DeviceModelAttributeMapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
+import java.lang.invoke.LambdaConversionException;
import java.util.*;
import cn.iocoder.yudao.module.iot.controller.admin.devicemodel.vo.*;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodel.DeviceModelDO;
@@ -30,6 +37,12 @@ public class DeviceModelServiceImpl implements DeviceModelService {
@Resource
private DeviceModelMapper deviceModelMapper;
+ @Resource
+ private DeviceMapper deviceMapper;
+
+ @Resource
+ private DeviceModelAttributeMapper deviceModelAttributeMapper;
+
@Override
public Long createDeviceModel(DeviceModelSaveReqVO createReqVO) {
// 插入
@@ -49,11 +62,23 @@ public class DeviceModelServiceImpl implements DeviceModelService {
}
@Override
- public void deleteDeviceModel(Long id) {
- // 校验存在
- validateDeviceModelExists(id);
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteDeviceModel(List idList ) {
+
+ for (Long id : idList) {
+ // 校验存在
+ validateDeviceModelExists(id);
+ //删除附属子表
+ deleteModelAttribute(id);
+ }
// 删除
- deviceModelMapper.deleteById(id);
+ deviceModelMapper.deleteByIds(idList);
+ }
+
+ private void deleteModelAttribute(Long id) {
+ LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
+ lambdaQueryWrapper.eq(DeviceModelAttributeDO::getDeviceModelId,id);
+ deviceModelAttributeMapper.delete(lambdaQueryWrapper);
}
private void validateDeviceModelExists(Long id) {
@@ -77,4 +102,41 @@ public class DeviceModelServiceImpl implements DeviceModelService {
return deviceModelMapper.selectList();
}
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Long copyDevice(Long id) {
+ if (id == null){
+ throw new RuntimeException("采集设备模型Id不能为空");
+ }
+ DeviceModelDO deviceModelDO = deviceModelMapper.selectById(id);
+ if(deviceModelDO == null){
+ throw new RuntimeException("该采集设备模型不存在!");
+ }
+ //复制实体类
+ DeviceModelDO newDeviceMode = new DeviceModelDO();
+ BeanUtils.copyProperties(deviceModelDO, newDeviceMode);
+ newDeviceMode.setId(null);
+ Random random = new Random();
+ int randomNumber = random.nextInt(9000) + 1000;
+ newDeviceMode.setCode(deviceModelDO.getCode()+ "-" + randomNumber);
+ newDeviceMode.setName(deviceModelDO.getName() + "-副本");
+ deviceModelMapper.insert(newDeviceMode);
+
+ //复制关联表
+ LambdaQueryWrapper lambdaConversionException = new LambdaQueryWrapper();
+ lambdaConversionException.eq(DeviceModelAttributeDO::getDeviceModelId,deviceModelDO.getId());
+ List deviceModelAttributeDOS = deviceModelAttributeMapper.selectList(lambdaConversionException);
+
+
+ if (deviceModelAttributeDOS != null && !deviceModelAttributeDOS.isEmpty()){
+ for (DeviceModelAttributeDO deviceModelAttributeDO : deviceModelAttributeDOS) {
+ deviceModelAttributeDO.setId(null);
+ deviceModelAttributeDO.setDeviceModelId(newDeviceMode.getId());
+ }
+ deviceModelAttributeMapper.insertBatch(deviceModelAttributeDOS);
+ }
+
+ return newDeviceMode.getId();
+ }
+
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeService.java
index 001de9ebb6..59bf320a49 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeService.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeService.java
@@ -34,7 +34,7 @@ public interface DeviceModelAttributeService {
*
* @param id 编号
*/
- void deleteDeviceModelAttribute(Long id);
+ void deleteDeviceModelAttribute(List idList );
/**
* 获得采集设备模型-点位管理
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeServiceImpl.java
index 3cece0fd8c..7a1d794afd 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeServiceImpl.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeServiceImpl.java
@@ -50,11 +50,14 @@ public class DeviceModelAttributeServiceImpl implements DeviceModelAttributeServ
}
@Override
- public void deleteDeviceModelAttribute(Long id) {
- // 校验存在
- validateDeviceModelAttributeExists(id);
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteDeviceModelAttribute(List idList) {
+ for (Long id : idList) {
+ // 校验存在
+ validateDeviceModelAttributeExists(id);
+ }
// 删除
- deviceModelAttributeMapper.deleteById(id);
+ deviceModelAttributeMapper.deleteByIds(idList);
}
private void validateDeviceModelAttributeExists(Long id) {
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java
index 51608c9342..8618fc582b 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java
@@ -91,7 +91,7 @@ public class DeviceServiceImplTest extends BaseDbUnitTest {
Long id = dbDevice.getId();
// 调用
- deviceService.deleteDevice(id);
+ deviceService.deleteDevice(Collections.singletonList(id));
// 校验数据不存在了
assertNull(deviceMapper.selectById(id));
}
@@ -102,7 +102,7 @@ public class DeviceServiceImplTest extends BaseDbUnitTest {
Long id = randomLongId();
// 调用, 并断言异常
- assertServiceException(() -> deviceService.deleteDevice(id), DEVICE_NOT_EXISTS);
+ assertServiceException(() -> deviceService.deleteDevice(Collections.singletonList(id)), DEVICE_NOT_EXISTS);
}
@Test