kkk-ops 1 month ago
commit f322430719

@ -67,6 +67,7 @@
<bizlog-sdk.version>3.0.6</bizlog-sdk.version>
<netty.version>4.1.113.Final</netty.version>
<mqtt.version>1.2.5</mqtt.version>
<opc.version>0.6.9</opc.version>
<!-- 三方云服务相关 -->
<commons-io.version>2.17.0</commons-io.version>
<commons-compress.version>1.27.1</commons-compress.version>
@ -567,6 +568,12 @@
<version>${jsoup.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.milo</groupId>
<artifactId>sdk-client</artifactId>
<version>${opc.version}</version>
</dependency>
<!-- 三方云服务相关 -->
<dependency>
<groupId>com.amazonaws</groupId>

@ -138,6 +138,11 @@
<artifactId>easy-trans-anno</artifactId> <!-- 默认引入的原因,方便 xxx-module-api 包使用 -->
</dependency>
<dependency>
<groupId>org.eclipse.milo</groupId>
<artifactId>sdk-client</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>

@ -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;
}
}

@ -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, "未知错误");

@ -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<EndpointDescription> 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();
}
}));
}
}

@ -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, "连接关闭参数不存在");
}

@ -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<Boolean> deleteDevice(@RequestParam("id") Long id) {
deviceService.deleteDevice(id);
public CommonResult<Boolean> deleteDevice(@RequestParam("ids") String ids) {
// 将逗号分隔的字符串转换为Long类型的List
List<Long> 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<Boolean> connectDevice(@RequestBody DeviceSaveReqVO createReqVO) {
return success(deviceService.connectDevice(createReqVO));
}
@PostMapping("/copy")
@Operation(summary = "复制设备")
// @PreAuthorize("@ss.hasPermission('iot:device-model:create')")
public CommonResult<Long> 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<PageResult<DeviceAttributeDO>> getDeviceAttributePage(PageParam pageReqVO,
@RequestParam("deviceId") Long deviceId) {
return success(deviceService.getDeviceAttributePage(pageReqVO, deviceId));
public CommonResult<PageResult<DeviceContactModelDO>> getDeviceAttributePage(PageParam pageParam, DeviceContactModelPageReqVO deviceModelAttributePageReqVO) {
return success(deviceService.getDeviceAttributePage(pageParam, deviceModelAttributePageReqVO));
}
@PostMapping("/device-attribute/create")

@ -74,4 +74,7 @@ public class DevicePageReqVO extends PageParam {
@Schema(description = "密码", example = "1234")
private String password;
@Schema(description = "id集合导出用")
private String ids;
}

@ -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")

@ -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;
}

@ -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<Boolean> deleteDeviceAttributeType(@RequestParam("id") Long id) {
deviceAttributeTypeService.deleteDeviceAttributeType(id);
public CommonResult<Boolean> deleteDeviceAttributeType(@RequestParam("ids") String ids) {
// 将逗号分隔的字符串转换为Long类型的List
List<Long> idList = Arrays.stream(ids.split(","))
.map(String::trim) // 去除可能存在的空格
.map(Long::valueOf)
.collect(Collectors.toList());
deviceAttributeTypeService.deleteDeviceAttributeType(idList);
return success(true);
}

@ -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;
}

@ -32,4 +32,9 @@ public class DeviceAttributeTypeRespVO {
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "排序", example = "1")
// @ExcelProperty("排序")
private int sort;
}

@ -23,4 +23,8 @@ public class DeviceAttributeTypeSaveReqVO {
@Schema(description = "备注", example = "随便")
private String remark;
@Schema(description = "排序",example = "2")
private int sort;
}

@ -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<Long> createDeviceContactModel(@Valid @RequestBody DeviceContactModelSaveReqVO createReqVO) {
return success(deviceContactModelService.createDeviceContactModel(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新采集设备模型-点位管理")
@PreAuthorize("@ss.hasPermission('iot:device-contact-model:update')")
public CommonResult<Boolean> 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<Boolean> deleteDeviceContactModel(@RequestParam("ids") String ids) {
// 将逗号分隔的字符串转换为Long类型的List
List<Long> 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<DeviceContactModelRespVO> 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<PageResult<DeviceContactModelRespVO>> getDeviceContactModelPage(@Valid DeviceContactModelPageReqVO pageReqVO) {
PageResult<DeviceContactModelDO> 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<DeviceContactModelDO> list = deviceContactModelService.getDeviceContactModelPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "采集设备模型-点位管理.xls", "数据", DeviceContactModelRespVO.class,
BeanUtils.toBean(list, DeviceContactModelRespVO.class));
}
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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<Boolean> deleteDeviceModel(@RequestParam("id") Long id) {
deviceModelService.deleteDeviceModel(id);
public CommonResult<Boolean> deleteDeviceModel(@RequestParam("ids") String ids) {
// 将逗号分隔的字符串转换为Long类型的List
List<Long> 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<Long> copyDevice(@RequestParam("id") Long id) {
return success(deviceModelService.copyDevice(id));
}
}

@ -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;
}

@ -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;
}

@ -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<Boolean> deleteDeviceModelAttribute(@RequestParam("id") Long id) {
deviceModelAttributeService.deleteDeviceModelAttribute(id);
public CommonResult<Boolean> deleteDeviceModelAttribute(@RequestParam("ids") String ids) {
// 将逗号分隔的字符串转换为Long类型的List
List<Long> idList = Arrays.stream(ids.split(","))
.map(String::trim) // 去除可能存在的空格
.map(Long::valueOf)
.collect(Collectors.toList());
deviceModelAttributeService.deleteDeviceModelAttribute(idList);
return success(true);
}

@ -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;
}

@ -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;
}

@ -106,4 +106,6 @@ public class DeviceDO extends BaseDO {
*
*/
private String password;
}

@ -39,5 +39,9 @@ public class DeviceAttributeTypeDO extends BaseDO {
*
*/
private String remark;
/**
*
*/
private int sort;
}

@ -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;
}

@ -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;
}

@ -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<DeviceDO> {
default PageResult<DeviceDO> selectPage(DevicePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<DeviceDO>()
.eqIfPresent(DeviceDO::getDeviceCode, reqVO.getDeviceCode())
LambdaQueryWrapperX<DeviceDO> 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<DeviceDO> {
.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<Long> idList = Arrays.stream(reqVO.getIds().split(","))
.map(String::trim)
.map(Long::valueOf)
.collect(Collectors.toList());
deviceDOLambdaQueryWrapperX.in(DeviceDO::getId, idList);
}
PageResult<DeviceDO> deviceDOPageResult = selectPage(reqVO, deviceDOLambdaQueryWrapperX);
return deviceDOPageResult;
}
default PageResult<DeviceDO> selectPage(PageParam reqVO, Long gatewayId) {
return selectPage(reqVO, new LambdaQueryWrapperX<DeviceDO>()
.eq(DeviceDO::getGatewayId, gatewayId)

@ -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<DeviceAttributeTypeDO> {
default PageResult<DeviceAttributeTypeDO> selectPage(DeviceAttributeTypePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<DeviceAttributeTypeDO>()
LambdaQueryWrapperX<DeviceAttributeTypeDO> 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<Long> 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<DeviceAttributeTypeDO> select() {

@ -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<DeviceContactModelDO> {
default PageResult<DeviceContactModelDO> selectPageById(PageParam reqVO, DeviceContactModelPageReqVO device) {
return selectPage(reqVO, new LambdaQueryWrapperX<DeviceContactModelDO>()
// 使用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<DeviceContactModelDO> selectPage(DeviceContactModelPageReqVO reqVO) {
LambdaQueryWrapperX<DeviceContactModelDO> 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<Long> idList = Arrays.stream(reqVO.getIds().split(","))
.map(String::trim)
.map(Long::valueOf)
.collect(Collectors.toList());
deviceContactModelDOLambdaQueryWrapperX.in(DeviceContactModelDO::getId, idList);
}
PageResult<DeviceContactModelDO> deviceContactModelDOPageResult = selectPage(reqVO, deviceContactModelDOLambdaQueryWrapperX);
return deviceContactModelDOPageResult;
}
}

@ -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<DeviceModelAttributeDO> {
default PageResult<DeviceModelAttributeDO> selectPage(DeviceModelAttributePageReqVO reqVO) {
default PageResult<DeviceModelAttributeDO> selectPageById(PageParam reqVO, DeviceModelAttributePageReqVO device) {
return selectPage(reqVO, new LambdaQueryWrapperX<DeviceModelAttributeDO>()
.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<DeviceModelAttributeDO> selectPage(DeviceModelAttributePageReqVO reqVO) {
LambdaQueryWrapperX<DeviceModelAttributeDO> 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<DeviceModelAttri
.eqIfPresent(DeviceModelAttributeDO::getDataUnit, reqVO.getDataUnit())
.eqIfPresent(DeviceModelAttributeDO::getRatio, reqVO.getRatio())
.eqIfPresent(DeviceModelAttributeDO::getRemark, reqVO.getRemark())
.eqIfPresent(DeviceModelAttributeDO::getDeviceModelId, reqVO.getDeviceModelId())
.eqIfPresent(DeviceModelAttributeDO::getDeviceModelId, reqVO.getId())
.betweenIfPresent(DeviceModelAttributeDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(DeviceModelAttributeDO::getId));
.orderByDesc(DeviceModelAttributeDO::getCreateTime);
if(reqVO.getIds() !=null && StringUtils.isNotBlank(reqVO.getIds())){
List<Long> idList = Arrays.stream(reqVO.getIds().split(","))
.map(String::trim)
.map(Long::valueOf)
.collect(Collectors.toList());
deviceModelAttributeDOLambdaQueryWrapperX.in(DeviceModelAttributeDO::getId,idList);
}
PageResult<DeviceModelAttributeDO> deviceModelAttributeDOPageResult = selectPage(reqVO, deviceModelAttributeDOLambdaQueryWrapperX);
return deviceModelAttributeDOPageResult;
}
}

@ -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<Long> ids);
/**
*
@ -78,7 +82,7 @@ public interface DeviceService {
* @param deviceId id
* @return
*/
PageResult<DeviceAttributeDO> getDeviceAttributePage(PageParam pageReqVO, Long deviceId);
PageResult<DeviceContactModelDO> getDeviceAttributePage(PageParam pageReqVO, DeviceContactModelPageReqVO deviceModelAttributePageReqVO);
/**
*
@ -111,5 +115,7 @@ public interface DeviceService {
DeviceAttributeDO getDeviceAttribute(Long id);
Boolean connectDevice(DeviceSaveReqVO createReqVO);
Long copyDevice(Long id);
}

@ -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<DeviceModelAttributeDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(DeviceModelAttributeDO::getDeviceModelId,createReqVO.getDeviceModelId());
List<DeviceModelAttributeDO> deviceModelAttributeDOS = deviceModelAttributeMapper.selectList(lambdaQueryWrapper);
List<DeviceContactModelDO> 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<DeviceDO> 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<Long> ids) {
for (Long id : ids) {
// 校验存在
validateDeviceExists(id);
// // 删除
// deviceMapper.deleteById(id);
// 删除子表
deleteDeviceConcatByDeviceId(id);
}
deviceMapper.deleteByIds(ids);
}
// 删除子表
deleteDeviceAttributeByDeviceId(id);
private void deleteDeviceConcatByDeviceId(Long id) {
LambdaQueryWrapper<DeviceContactModelDO> 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<DeviceAttributeDO> getDeviceAttributePage(PageParam pageReqVO, Long deviceId) {
return deviceAttributeMapper.selectPage(pageReqVO, deviceId);
public PageResult<DeviceContactModelDO> 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<DeviceContactModelDO> 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<DeviceContactModelDO> lambdaQueryWrapper = new LambdaQueryWrapper();
lambdaQueryWrapper.eq(DeviceContactModelDO::getDeviceId,deviceDO.getId());
List<DeviceContactModelDO> 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);

@ -35,7 +35,7 @@ public interface DeviceAttributeTypeService {
*
* @param id
*/
void deleteDeviceAttributeType(Long id);
void deleteDeviceAttributeType( List<Long> ids);
/**
*

@ -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<Long> ids) {
for (Long id : ids) {
// 校验存在
validateDeviceAttributeTypeExists(id);
}
// 删除
deviceAttributeTypeMapper.deleteById(id);
deviceAttributeTypeMapper.deleteByIds(ids);
}
private void validateDeviceAttributeTypeExists(Long id) {

@ -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<Long> id);
/**
* -
*
* @param id
* @return -
*/
DeviceContactModelDO getDeviceContactModel(Long id);
/**
* -
*
* @param pageReqVO
* @return -
*/
PageResult<DeviceContactModelDO> getDeviceContactModelPage(DeviceContactModelPageReqVO pageReqVO);
}

@ -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<Long> 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<DeviceContactModelDO> getDeviceContactModelPage(DeviceContactModelPageReqVO pageReqVO) {
return deviceContactModelMapper.selectPage(pageReqVO);
}
}

@ -35,7 +35,7 @@ public interface DeviceModelService {
*
* @param id
*/
void deleteDeviceModel(Long id);
void deleteDeviceModel(List<Long> idList);
/**
*
@ -58,4 +58,11 @@ public interface DeviceModelService {
* @return
*/
List<DeviceModelDO> getDeviceModelList();
/**
*
*
* @return
*/
Long copyDevice(Long id);
}

@ -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<Long> idList ) {
for (Long id : idList) {
// 校验存在
validateDeviceModelExists(id);
//删除附属子表
deleteModelAttribute(id);
}
// 删除
deviceModelMapper.deleteById(id);
deviceModelMapper.deleteByIds(idList);
}
private void deleteModelAttribute(Long id) {
LambdaQueryWrapper<DeviceModelAttributeDO> 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<DeviceModelAttributeDO> lambdaConversionException = new LambdaQueryWrapper();
lambdaConversionException.eq(DeviceModelAttributeDO::getDeviceModelId,deviceModelDO.getId());
List<DeviceModelAttributeDO> 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();
}
}

@ -34,7 +34,7 @@ public interface DeviceModelAttributeService {
*
* @param id
*/
void deleteDeviceModelAttribute(Long id);
void deleteDeviceModelAttribute(List<Long> idList );
/**
* -

@ -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<Long> idList) {
for (Long id : idList) {
// 校验存在
validateDeviceModelAttributeExists(id);
}
// 删除
deviceModelAttributeMapper.deleteById(id);
deviceModelAttributeMapper.deleteByIds(idList);
}
private void validateDeviceModelAttributeExists(Long id) {

@ -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

Loading…
Cancel
Save