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