Merge branch 'feature/iot' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/iot

This commit is contained in:
alwayssuper
2025-07-03 07:43:14 +08:00
200 changed files with 4888 additions and 3246 deletions

View File

@@ -7,7 +7,6 @@
<version>${revision}</version>
</parent>
<modules>
<module>yudao-module-iot-api</module>
<module>yudao-module-iot-biz</module>
<module>yudao-module-iot-core</module>
<module>yudao-module-iot-gateway</module>

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yudao-module-iot</artifactId>
<groupId>cn.iocoder.boot</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-iot-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<!-- TODO 芋艿:需要在整理下,特别是 PF4J -->
<description>
物联网 模块 API暴露给其它模块调用
</description>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.pf4j</groupId> &lt;!&ndash; PF4J内置插件机制 &ndash;&gt;-->
<!-- <artifactId>pf4j-spring</artifactId>-->
<!-- </dependency>-->
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.Map;
/**
* IoT 设备【事件】上报 Request DTO
*
* @author 芋道源码
*/
@Data
public class IotDeviceEventReportReqDTO extends IotDeviceUpstreamAbstractReqDTO {
/**
* 事件标识
*/
@NotEmpty(message = "事件标识不能为空")
private String identifier;
/**
* 事件参数
*/
private Map<String, Object> params;
}

View File

@@ -1,22 +0,0 @@
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.Map;
/**
* IoT 设备【属性】上报 Request DTO
*
* @author 芋道源码
*/
@Data
public class IotDevicePropertyReportReqDTO extends IotDeviceUpstreamAbstractReqDTO {
/**
* 属性参数
*/
@NotEmpty(message = "属性参数不能为空")
private Map<String, Object> properties;
}

View File

@@ -1,45 +0,0 @@
package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* IoT 设备上行的抽象 Request DTO
*
* @author 芋道源码
*/
@Data
public abstract class IotDeviceUpstreamAbstractReqDTO {
/**
* 请求编号
*/
private String requestId;
/**
* 插件实例的进程编号
*/
private String processId;
/**
* 产品标识
*/
@NotEmpty(message = "产品标识不能为空")
private String productKey;
/**
* 设备名称
*/
@NotEmpty(message = "设备名称不能为空")
private String deviceName;
/**
* 上报时间
*/
@JsonSerialize(using = TimestampLocalDateTimeSerializer.class) // 解决 iot plugins 序列化 LocalDateTime 是数组,导致无法解析的问题
private LocalDateTime reportTime;
}

View File

@@ -1,35 +0,0 @@
package cn.iocoder.yudao.module.iot.enums.ota;
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* IoT OTA 升级任务的范围枚举
*
* @author haohao
*/
@RequiredArgsConstructor
@Getter
public enum IotOtaUpgradeTaskStatusEnum implements ArrayValuable<Integer> {
IN_PROGRESS(10), // 进行中:升级中
COMPLETED(20), // 已完成:已结束,全部升级完成
INCOMPLETE(21), // 未完成:已结束,部分升级完成
CANCELED(30),; // 已取消:一般是主动取消任务
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotOtaUpgradeTaskStatusEnum::getStatus).toArray(Integer[]::new);
/**
* 范围
*/
private final Integer status;
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -1,42 +0,0 @@
package cn.iocoder.yudao.module.iot.enums.rule;
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* IoT 数据桥接的类型枚举
*
* @author 芋道源码
*/
@RequiredArgsConstructor
@Getter
public enum IotDataBridgeTypeEnum implements ArrayValuable<Integer> {
HTTP(1, "HTTP"),
TCP(2, "TCP"),
WEBSOCKET(3, "WEBSOCKET"),
MQTT(10, "MQTT"),
DATABASE(20, "DATABASE"),
REDIS_STREAM(21, "REDIS_STREAM"),
ROCKETMQ(30, "ROCKETMQ"),
RABBITMQ(31, "RABBITMQ"),
KAFKA(32, "KAFKA");
private final Integer type;
private final String name;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDataBridgeTypeEnum::getType).toArray(Integer[]::new);
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -1,30 +0,0 @@
package cn.iocoder.yudao.module.iot.enums.rule;
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* IoT 场景流转的触发类型枚举
*
* @author 芋道源码
*/
@RequiredArgsConstructor
@Getter
public enum IotRuleSceneTriggerTypeEnum implements ArrayValuable<Integer> {
DEVICE(1), // 设备触发
TIMER(2); // 定时触发
private final Integer type;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotRuleSceneTriggerTypeEnum::getType).toArray(Integer[]::new);
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -23,11 +23,6 @@
<artifactId>yudao-module-system</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-iot-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-iot-core</artifactId>

View File

@@ -0,0 +1,105 @@
package cn.iocoder.yudao.module.iot.controller.admin.alert;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config.IotAlertConfigPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config.IotAlertConfigRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config.IotAlertConfigSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO;
import cn.iocoder.yudao.module.iot.service.alert.IotAlertConfigService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
@Tag(name = "管理后台 - IoT 告警配置")
@RestController
@RequestMapping("/iot/alert-config")
@Validated
public class IotAlertConfigController {
@Resource
private IotAlertConfigService alertConfigService;
@Resource
private AdminUserApi adminUserApi;
@PostMapping("/create")
@Operation(summary = "创建告警配置")
@PreAuthorize("@ss.hasPermission('iot:alert-config:create')")
public CommonResult<Long> createAlertConfig(@Valid @RequestBody IotAlertConfigSaveReqVO createReqVO) {
return success(alertConfigService.createAlertConfig(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新告警配置")
@PreAuthorize("@ss.hasPermission('iot:alert-config:update')")
public CommonResult<Boolean> updateAlertConfig(@Valid @RequestBody IotAlertConfigSaveReqVO updateReqVO) {
alertConfigService.updateAlertConfig(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除告警配置")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('iot:alert-config:delete')")
public CommonResult<Boolean> deleteAlertConfig(@RequestParam("id") Long id) {
alertConfigService.deleteAlertConfig(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得告警配置")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('iot:alert-config:query')")
public CommonResult<IotAlertConfigRespVO> getAlertConfig(@RequestParam("id") Long id) {
IotAlertConfigDO alertConfig = alertConfigService.getAlertConfig(id);
return success(BeanUtils.toBean(alertConfig, IotAlertConfigRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得告警配置分页")
@PreAuthorize("@ss.hasPermission('iot:alert-config:query')")
public CommonResult<PageResult<IotAlertConfigRespVO>> getAlertConfigPage(@Valid IotAlertConfigPageReqVO pageReqVO) {
PageResult<IotAlertConfigDO> pageResult = alertConfigService.getAlertConfigPage(pageReqVO);
// 转换返回
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSetByFlatMap(pageResult.getList(), config -> config.getReceiveUserIds().stream()));
return success(BeanUtils.toBean(pageResult, IotAlertConfigRespVO.class, vo -> {
vo.setReceiveUserNames(vo.getReceiveUserIds().stream()
.map(userMap::get)
.filter(Objects::nonNull)
.map(AdminUserRespDTO::getNickname)
.collect(Collectors.toList()));
}));
}
@GetMapping("/simple-list")
@Operation(summary = "获得告警配置简单列表", description = "只包含被开启的告警配置,主要用于前端的下拉选项")
@PreAuthorize("@ss.hasPermission('iot:alert-config:query')")
public CommonResult<List<IotAlertConfigRespVO>> getAlertConfigSimpleList() {
List<IotAlertConfigDO> list = alertConfigService.getAlertConfigListByStatus(CommonStatusEnum.ENABLE.getStatus());
return success(convertList(list, config -> // 只返回 id、name 字段
new IotAlertConfigRespVO().setId(config.getId()).setName(config.getName())));
}
}

View File

@@ -0,0 +1,57 @@
package cn.iocoder.yudao.module.iot.controller.admin.alert;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordProcessReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO;
import cn.iocoder.yudao.module.iot.service.alert.IotAlertRecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static java.util.Collections.singleton;
@Tag(name = "管理后台 - IoT 告警记录")
@RestController
@RequestMapping("/iot/alert-record")
@Validated
public class IotAlertRecordController {
@Resource
private IotAlertRecordService alertRecordService;
@GetMapping("/get")
@Operation(summary = "获得告警记录")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('iot:alert-record:query')")
public CommonResult<IotAlertRecordRespVO> getAlertRecord(@RequestParam("id") Long id) {
IotAlertRecordDO alertRecord = alertRecordService.getAlertRecord(id);
return success(BeanUtils.toBean(alertRecord, IotAlertRecordRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得告警记录分页")
@PreAuthorize("@ss.hasPermission('iot:alert-record:query')")
public CommonResult<PageResult<IotAlertRecordRespVO>> getAlertRecordPage(@Valid IotAlertRecordPageReqVO pageReqVO) {
PageResult<IotAlertRecordDO> pageResult = alertRecordService.getAlertRecordPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, IotAlertRecordRespVO.class));
}
@PutMapping("/process")
@Operation(summary = "处理告警记录")
@PreAuthorize("@ss.hasPermission('iot:alert-record:process')")
public CommonResult<Boolean> processAlertRecord(@Valid @RequestBody IotAlertRecordProcessReqVO processReqVO) {
alertRecordService.processAlertRecordList(singleton(processReqVO.getId()), processReqVO.getProcessRemark());
return success(true);
}
}

View File

@@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
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 = "管理后台 - IoT 告警配置分页 Request VO")
@Data
public class IotAlertConfigPageReqVO extends PageParam {
@Schema(description = "配置名称", example = "赵六")
private String name;
@Schema(description = "配置状态", example = "1")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - IoT 告警配置 Response VO")
@Data
public class IotAlertConfigRespVO {
@Schema(description = "配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3566")
private Long id;
@Schema(description = "配置名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
private String name;
@Schema(description = "配置描述", example = "你猜")
private String description;
@Schema(description = "告警级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer level;
@Schema(description = "配置状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "关联的场景联动规则编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
private List<Long> sceneRuleIds;
@Schema(description = "接收的用户编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "100,200")
private List<Long> receiveUserIds;
@Schema(description = "接收的用户名称数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三,李四")
private List<String> receiveUserNames;
@Schema(description = "接收的类型数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
private List<Integer> receiveTypes;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - IoT 告警配置新增/修改 Request VO")
@Data
public class IotAlertConfigSaveReqVO {
@Schema(description = "配置编号", example = "3566")
private Long id;
@Schema(description = "配置名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
@NotEmpty(message = "配置名称不能为空")
private String name;
@Schema(description = "配置描述", example = "你猜")
private String description;
@Schema(description = "告警级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "告警级别不能为空")
private Integer level;
@Schema(description = "配置状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "配置状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
@Schema(description = "关联的场景联动规则编号数组")
@NotEmpty(message = "关联的场景联动规则编号数组不能为空")
private List<Long> sceneRuleIds;
@Schema(description = "接收的用户编号数组")
@NotEmpty(message = "接收的用户编号数组不能为空")
private List<Long> receiveUserIds;
@Schema(description = "接收的类型数组")
@NotEmpty(message = "接收的类型数组不能为空")
private List<Integer> receiveTypes;
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
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 = "管理后台 - IoT 告警记录分页 Request VO")
@Data
public class IotAlertRecordPageReqVO extends PageParam {
@Schema(description = "告警配置编号", example = "29320")
private Long configId;
@Schema(description = "告警级别", example = "1")
private Integer level;
@Schema(description = "产品编号", example = "2050")
private Long productId;
@Schema(description = "设备编号", example = "21727")
private String deviceId;
@Schema(description = "是否处理", example = "true")
private Boolean processStatus;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - IoT 告警记录处理 Request VO")
@Data
public class IotAlertRecordProcessReqVO {
@Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "记录编号不能为空")
private Long id;
@Schema(description = "处理结果(备注)", requiredMode = Schema.RequiredMode.REQUIRED, example = "已处理告警,问题已解决")
private String processRemark;
}

View File

@@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - IoT 告警记录 Response VO")
@Data
public class IotAlertRecordRespVO {
@Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "19904")
private Long id;
@Schema(description = "告警配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29320")
private Long configId;
@Schema(description = "告警名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
private String configName;
@Schema(description = "告警级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer configLevel;
@Schema(description = "产品编号", example = "2050")
private Long productId;
@Schema(description = "设备编号", example = "21727")
private Long deviceId;
@Schema(description = "触发的设备消息")
private IotDeviceMessage deviceMessage;
@Schema(description = "是否处理", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Boolean processStatus;
@Schema(description = "处理结果(备注)", example = "你说的对")
private String processRemark;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@@ -9,9 +9,9 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceMessageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
@@ -38,8 +38,6 @@ public class IotDeviceController {
@Resource
private IotDeviceService deviceService;
@Resource
private IotDeviceMessageService deviceMessageService;
@PostMapping("/create")
@Operation(summary = "创建设备")
@@ -124,12 +122,17 @@ public class IotDeviceController {
@GetMapping("/simple-list")
@Operation(summary = "获取设备的精简信息列表", description = "主要用于前端的下拉选项")
@Parameter(name = "deviceType", description = "设备类型", example = "1")
public CommonResult<List<IotDeviceRespVO>> getSimpleDeviceList(
@RequestParam(value = "deviceType", required = false) Integer deviceType) {
List<IotDeviceDO> list = deviceService.getDeviceListByDeviceType(deviceType);
return success(convertList(list, device -> // 只返回 id、name 字段
new IotDeviceRespVO().setId(device.getId()).setDeviceName(device.getDeviceName())));
@Parameters({
@Parameter(name = "deviceType", description = "设备类型", example = "1"),
@Parameter(name = "productId", description = "产品编号", example = "1024")
})
public CommonResult<List<IotDeviceRespVO>> getDeviceSimpleList(
@RequestParam(value = "deviceType", required = false) Integer deviceType,
@RequestParam(value = "productId", required = false) Long productId) {
List<IotDeviceDO> list = deviceService.getDeviceListByCondition(deviceType, productId);
return success(convertList(list, device -> // 只返回 id、name、productId 字段
new IotDeviceRespVO().setId(device.getId()).setDeviceName(device.getDeviceName())
.setProductId(device.getProductId())));
}
@PostMapping("/import")

View File

@@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyDetailRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyHistoryListReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;

View File

@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo.property;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDataSpecs;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@@ -3,12 +3,14 @@ package cn.iocoder.yudao.module.iot.controller.admin.ota;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareCreateReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwarePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareCreateReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwareUpdateReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.service.ota.IotOtaFirmwareService;
import cn.iocoder.yudao.module.iot.service.product.IotProductService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
@@ -21,12 +23,14 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - IoT OTA 固件")
@RestController
@RequestMapping("/iot/ota-firmware")
@RequestMapping("/iot/ota/firmware")
@Validated
public class IotOtaFirmwareController {
@Resource
private IotOtaFirmwareService otaFirmwareService;
@Resource
private IotProductService productService;
@PostMapping("/create")
@Operation(summary = "创建 OTA 固件")
@@ -47,8 +51,16 @@ public class IotOtaFirmwareController {
@Operation(summary = "获得 OTA 固件")
@PreAuthorize("@ss.hasPermission('iot:ota-firmware:query')")
public CommonResult<IotOtaFirmwareRespVO> getOtaFirmware(@RequestParam("id") Long id) {
IotOtaFirmwareDO otaFirmware = otaFirmwareService.getOtaFirmware(id);
return success(BeanUtils.toBean(otaFirmware, IotOtaFirmwareRespVO.class));
IotOtaFirmwareDO firmware = otaFirmwareService.getOtaFirmware(id);
if (firmware == null) {
return success(null);
}
return success(BeanUtils.toBean(firmware, IotOtaFirmwareRespVO.class, o -> {
IotProductDO product = productService.getProduct(firmware.getProductId());
if (product != null) {
o.setProductName(product.getName());
}
}));
}
@GetMapping("/page")

View File

@@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.IotOtaTaskPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.IotOtaTaskRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.IotOtaTaskCreateReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskDO;
import cn.iocoder.yudao.module.iot.service.ota.IotOtaTaskService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - IoT OTA 升级任务")
@RestController
@RequestMapping("/iot/ota/task")
@Validated
public class IotOtaTaskController {
@Resource
private IotOtaTaskService otaTaskService;
@PostMapping("/create")
@Operation(summary = "创建 OTA 升级任务")
@PreAuthorize(value = "@ss.hasPermission('iot:ota-task:create')")
public CommonResult<Long> createOtaTask(@Valid @RequestBody IotOtaTaskCreateReqVO createReqVO) {
return success(otaTaskService.createOtaTask(createReqVO));
}
@PostMapping("/cancel")
@Operation(summary = "取消 OTA 升级任务")
@Parameter(name = "id", description = "升级任务编号", required = true)
@PreAuthorize(value = "@ss.hasPermission('iot:ota-task:cancel')")
public CommonResult<Boolean> cancelOtaTask(@RequestParam("id") Long id) {
otaTaskService.cancelOtaTask(id);
return success(true);
}
@GetMapping("/page")
@Operation(summary = "获得 OTA 升级任务分页")
@PreAuthorize(value = "@ss.hasPermission('iot:ota-task:query')")
public CommonResult<PageResult<IotOtaTaskRespVO>> getOtaTaskPage(@Valid IotOtaTaskPageReqVO pageReqVO) {
PageResult<IotOtaTaskDO> pageResult = otaTaskService.getOtaTaskPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, IotOtaTaskRespVO.class));
}
@GetMapping("/get")
@Operation(summary = "获得 OTA 升级任务")
@Parameter(name = "id", description = "升级任务编号", required = true, example = "1024")
@PreAuthorize(value = "@ss.hasPermission('iot:ota-task:query')")
public CommonResult<IotOtaTaskRespVO> getOtaTask(@RequestParam("id") Long id) {
IotOtaTaskDO upgradeTask = otaTaskService.getOtaTask(id);
return success(BeanUtils.toBean(upgradeTask, IotOtaTaskRespVO.class));
}
}

View File

@@ -0,0 +1,93 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskRecordDO;
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
import cn.iocoder.yudao.module.iot.service.ota.IotOtaFirmwareService;
import cn.iocoder.yudao.module.iot.service.ota.IotOtaTaskRecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.hutool.core.collection.CollUtil;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - IoT OTA 升级任务记录")
@RestController
@RequestMapping("/iot/ota/task/record")
@Validated
public class IotOtaTaskRecordController {
@Resource
private IotOtaTaskRecordService otaTaskRecordService;
@Resource
private IotDeviceService deviceService;
@Resource
private IotOtaFirmwareService otaFirmwareService;
@GetMapping("/get-status-statistics")
@Operation(summary = "获得 OTA 升级记录状态统计")
@Parameters({
@Parameter(name = "firmwareId", description = "固件编号", example = "1024"),
@Parameter(name = "taskId", description = "升级任务编号", example = "2048")
})
@PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')")
public CommonResult<Map<Integer, Long>> getOtaTaskRecordStatusStatistics(
@RequestParam(value = "firmwareId", required = false) Long firmwareId,
@RequestParam(value = "taskId", required = false) Long taskId) {
return success(otaTaskRecordService.getOtaTaskRecordStatusStatistics(firmwareId, taskId));
}
@GetMapping("/page")
@Operation(summary = "获得 OTA 升级记录分页")
@PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')")
public CommonResult<PageResult<IotOtaTaskRecordRespVO>> getOtaTaskRecordPage(
@Valid IotOtaTaskRecordPageReqVO pageReqVO) {
PageResult<IotOtaTaskRecordDO> pageResult = otaTaskRecordService.getOtaTaskRecordPage(pageReqVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return success(PageResult.empty());
}
// 批量查询固件信息
Map<Long, IotOtaFirmwareDO> firmwareMap = otaFirmwareService.getOtaFirmwareMap(
convertSet(pageResult.getList(), IotOtaTaskRecordDO::getFromFirmwareId));
Map<Long, IotDeviceDO> deviceMap = deviceService.getDeviceMap(
convertSet(pageResult.getList(), IotOtaTaskRecordDO::getDeviceId));
// 转换为响应 VO
return success(BeanUtils.toBean(pageResult, IotOtaTaskRecordRespVO.class, (vo) -> {
MapUtils.findAndThen(firmwareMap, vo.getFromFirmwareId(), firmware ->
vo.setFromFirmwareVersion(firmware.getVersion()));
MapUtils.findAndThen(deviceMap, vo.getDeviceId(), device ->
vo.setDeviceName(device.getDeviceName()));
}));
}
@GetMapping("/get")
@Operation(summary = "获得 OTA 升级记录")
@PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')")
@Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")
public CommonResult<IotOtaTaskRecordRespVO> getOtaTaskRecord(@RequestParam("id") Long id) {
IotOtaTaskRecordDO upgradeRecord = otaTaskRecordService.getOtaTaskRecord(id);
return success(BeanUtils.toBean(upgradeRecord, IotOtaTaskRecordRespVO.class));
}
}

View File

@@ -1,75 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.record.IotOtaUpgradeRecordPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.record.IotOtaUpgradeRecordRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaUpgradeRecordDO;
import cn.iocoder.yudao.module.iot.service.ota.IotOtaUpgradeRecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - IoT OTA 升级记录")
@RestController
@RequestMapping("/iot/ota-upgrade-record")
@Validated
public class IotOtaUpgradeRecordController {
@Resource
private IotOtaUpgradeRecordService upgradeRecordService;
@GetMapping("/get-statistics")
@Operation(summary = "固件升级设备统计")
@PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")
@Parameter(name = "firmwareId", description = "固件编号", required = true, example = "1024")
public CommonResult<Map<Integer, Long>> getOtaUpgradeRecordStatistics(@RequestParam(value = "firmwareId") Long firmwareId) {
return success(upgradeRecordService.getOtaUpgradeRecordStatistics(firmwareId));
}
@GetMapping("/get-count")
@Operation(summary = "获得升级记录分页 tab 数量")
@PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")
public CommonResult<Map<Integer, Long>> getOtaUpgradeRecordCount(
@Valid IotOtaUpgradeRecordPageReqVO pageReqVO) {
return success(upgradeRecordService.getOtaUpgradeRecordCount(pageReqVO));
}
@GetMapping("/page")
@Operation(summary = "获得升级记录分页")
@PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")
public CommonResult<PageResult<IotOtaUpgradeRecordRespVO>> getUpgradeRecordPage(
@Valid IotOtaUpgradeRecordPageReqVO pageReqVO) {
PageResult<IotOtaUpgradeRecordDO> pageResult = upgradeRecordService.getUpgradeRecordPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, IotOtaUpgradeRecordRespVO.class));
}
@GetMapping("/get")
@Operation(summary = "获得升级记录")
@PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')")
@Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")
public CommonResult<IotOtaUpgradeRecordRespVO> getUpgradeRecord(@RequestParam("id") Long id) {
IotOtaUpgradeRecordDO upgradeRecord = upgradeRecordService.getUpgradeRecord(id);
return success(BeanUtils.toBean(upgradeRecord, IotOtaUpgradeRecordRespVO.class));
}
@PutMapping("/retry")
@Operation(summary = "重试升级记录")
@PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:retry')")
@Parameter(name = "id", description = "升级记录编号", required = true, example = "1024")
public CommonResult<Boolean> retryUpgradeRecord(@RequestParam("id") Long id) {
upgradeRecordService.retryUpgradeRecord(id);
return success(true);
}
}

View File

@@ -1,64 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task.IotOtaUpgradeTaskPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task.IotOtaUpgradeTaskRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task.IotOtaUpgradeTaskSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaUpgradeTaskDO;
import cn.iocoder.yudao.module.iot.service.ota.IotOtaUpgradeTaskService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - IoT OTA 升级任务")
@RestController
@RequestMapping("/iot/ota-upgrade-task")
@Validated
public class IotOtaUpgradeTaskController {
@Resource
private IotOtaUpgradeTaskService upgradeTaskService;
@PostMapping("/create")
@Operation(summary = "创建升级任务")
@PreAuthorize(value = "@ss.hasPermission('iot:ota-upgrade-task:create')")
public CommonResult<Long> createUpgradeTask(@Valid @RequestBody IotOtaUpgradeTaskSaveReqVO createReqVO) {
return success(upgradeTaskService.createUpgradeTask(createReqVO));
}
@PostMapping("/cancel")
@Operation(summary = "取消升级任务")
@Parameter(name = "id", description = "升级任务编号", required = true)
@PreAuthorize(value = "@ss.hasPermission('iot:ota-upgrade-task:cancel')")
public CommonResult<Boolean> cancelUpgradeTask(@RequestParam("id") Long id) {
upgradeTaskService.cancelUpgradeTask(id);
return success(true);
}
@GetMapping("/page")
@Operation(summary = "获得升级任务分页")
@PreAuthorize(value = "@ss.hasPermission('iot:ota-upgrade-task:query')")
public CommonResult<PageResult<IotOtaUpgradeTaskRespVO>> getUpgradeTaskPage(@Valid IotOtaUpgradeTaskPageReqVO pageReqVO) {
PageResult<IotOtaUpgradeTaskDO> pageResult = upgradeTaskService.getUpgradeTaskPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, IotOtaUpgradeTaskRespVO.class));
}
@GetMapping("/get")
@Operation(summary = "获得升级任务")
@Parameter(name = "id", description = "升级任务编号", required = true, example = "1024")
@PreAuthorize(value = "@ss.hasPermission('iot:ota-upgrade-task:query')")
public CommonResult<IotOtaUpgradeTaskRespVO> getUpgradeTask(@RequestParam("id") Long id) {
IotOtaUpgradeTaskDO upgradeTask = upgradeTaskService.getUpgradeTask(id);
return success(BeanUtils.toBean(upgradeTask, IotOtaUpgradeTaskRespVO.class));
}
}

View File

@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
@Schema(description = "管理后台 - IoT OTA 固件创建 Request VO")
@Data
@@ -22,17 +23,11 @@ public class IotOtaFirmwareCreateReqVO {
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "产品编号不能为空")
private String productId;
private Long productId;
@Schema(description = "签名方式", example = "MD5")
// TODO @li是不是必传哈
private String signMethod;
@Schema(description = "固件文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/yudao-firmware.zip")
@Schema(description = "固件文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.zip")
@NotEmpty(message = "固件文件 URL 不能为空")
@URL(message = "固件文件 URL 格式错误")
private String fileUrl;
@Schema(description = "自定义信息,建议使用 JSON 格式", example = "{\"key1\":\"value1\",\"key2\":\"value2\"}")
private String information;
}

View File

@@ -3,21 +3,24 @@ package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
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;
@Data
@Schema(description = "管理后台 - IoT OTA 固件分页 Request VO")
@Data
public class IotOtaFirmwarePageReqVO extends PageParam {
/**
* 固件名称
*/
@Schema(description = "固件名称", example = "智能开关固件")
private String name;
/**
* 产品标识
*/
@Schema(description = "产品标识", example = "1024")
private String productId;
@Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -1,83 +1,49 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import com.fhs.core.trans.anno.Trans;
import com.fhs.core.trans.constant.TransType;
import com.fhs.core.trans.vo.VO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
import java.time.LocalDateTime;
@Schema(description = "管理后台 - IoT OTA 固件 Response VO")
@Data
public class IotOtaFirmwareRespVO implements VO {
/**
* 固件编号
*/
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
/**
* 固件名称
*/
@Schema(description = "固件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "OTA固件")
@Schema(description = "固件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "OTA 固件")
private String name;
/**
* 固件描述
*/
@Schema(description = "固件描述")
private String description;
/**
* 版本号
*/
@Schema(description = "版本号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0.0")
private String version;
/**
* 产品编号
* <p>
* 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO#getId()}
*/
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@Trans(type = TransType.SIMPLE, target = IotProductDO.class, fields = {"name"}, refs = {"productName"})
private String productId;
/**
* 产品标识
* <p>
* 冗余 {@link cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO#getProductKey()}
*/
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "iot-product-key")
private String productKey;
/**
* 产品名称
*/
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "OTA产品")
private Long productId;
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "智能设备")
private String productName;
/**
* 签名方式
* <p>
* 例如说MD5、SHA256
*/
@Schema(description = "签名方式", example = "MD5")
private String signMethod;
/**
* 固件文件签名
*/
@Schema(description = "固件文件签名", example = "1024")
private String fileSign;
/**
* 固件文件大小
*/
@Schema(description = "固件文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/firmware.bin")
private String fileUrl;
@Schema(description = "固件文件大小", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long fileSize;
/**
* 固件文件 URL
*/
@Schema(description = "固件文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
private String fileUrl;
/**
* 自定义信息,建议使用 JSON 格式
*/
@Schema(description = "自定义信息,建议使用 JSON 格式")
private String information;
@Schema(description = "固件文件签名算法", example = "MD5")
private String fileDigestAlgorithm;
@Schema(description = "固件文件签名结果", example = "d41d8cd98f00b204e9800998ecf8427e")
private String fileDigestValue;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime updateTime;
}

View File

@@ -1,7 +1,6 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@@ -13,9 +12,7 @@ public class IotOtaFirmwareUpdateReqVO {
@NotNull(message = "固件编号不能为空")
private Long id;
// TODO @liname 是不是可以飞必传哈
@Schema(description = "固件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "智能开关固件")
@NotEmpty(message = "固件名称不能为空")
@Schema(description = "固件名称", example = "智能开关固件")
private String name;
@Schema(description = "固件描述", example = "某品牌型号固件,测试用")

View File

@@ -1,9 +1,7 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task;
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
import cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeTaskScopeEnum;
import cn.iocoder.yudao.module.iot.enums.ota.IotOtaTaskDeviceScopeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
@@ -11,51 +9,29 @@ import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - IoT OTA 升级任务创建 Request VO")
@Data
@Schema(description = "管理后台 - IoT OTA 升级任务创建/修改 Request VO")
public class IotOtaUpgradeTaskSaveReqVO {
public class IotOtaTaskCreateReqVO {
// TODO @li已经有注解不用重复注释
// TODO @li @Schema 写在参数校验前面先有定义其他的也检查下
/**
* 任务名称
*/
@NotEmpty(message = "任务名称不能为空")
@Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "升级任务")
private String name;
/**
* 任务描述
*/
@Schema(description = "任务描述", example = "升级任务")
private String description;
/**
* 固件编号
* <p>
* 关联 {@link IotOtaFirmwareDO#getId()}
*/
@NotNull(message = "固件编号不能为空")
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "固件编号不能为空")
private Long firmwareId;
/**
* 升级范围
* <p>
* 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeTaskScopeEnum}
*/
@NotNull(message = "升级范围不能为空")
@InEnum(value = IotOtaUpgradeTaskScopeEnum.class)
@Schema(description = "升级范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer scope;
@NotNull(message = "升级范围不能为空")
@InEnum(value = IotOtaTaskDeviceScopeEnum.class)
private Integer deviceScope;
/**
* 选中的设备编号数组
* <p>
* 关联 {@link IotDeviceDO#getId()}
*/
@Schema(description = "选中的设备编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3,4]")
@Schema(description = "选中的设备编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
private List<Long> deviceIds;
// TODO @li如果 deviceScope 等于 2 deviceIds 校验非空
}

View File

@@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - IoT OTA 升级任务分页 Request VO")
@Data
public class IotOtaTaskPageReqVO extends PageParam {
@Schema(description = "任务名称", example = "升级任务")
private String name;
@Schema(description = "固件编号", example = "1024")
private Long firmwareId;
}

View File

@@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task;
import com.fhs.core.trans.vo.VO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - IoT OTA 升级任务 Response VO")
@Data
public class IotOtaTaskRespVO implements VO {
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "升级任务")
private String name;
@Schema(description = "任务描述", example = "升级任务")
private String description;
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long firmwareId;
@Schema(description = "任务状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private Integer status;
@Schema(description = "升级范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer deviceScope;
@Schema(description = "设备总共数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer deviceTotalCount;
@Schema(description = "设备成功数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "66")
private Integer deviceSuccessCount;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-08 07:30:00")
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.enums.ota.IotOtaTaskRecordStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - IoT OTA 升级记录分页 Request VO")
@Data
public class IotOtaTaskRecordPageReqVO extends PageParam {
@Schema(description = "升级任务编号", example = "1024")
private Long taskId;
@Schema(description = "升级记录状态", example = "5")
@InEnum(IotOtaTaskRecordStatusEnum.class)
private Integer status;
}

View File

@@ -0,0 +1,48 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - IoT OTA 升级任务记录 Response VO")
@Data
public class IotOtaTaskRecordRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long firmwareId;
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
private Long taskId;
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long deviceId;
@Schema(description = "设备名称", example = "智能开关")
private String deviceName;
@Schema(description = "来源的固件编号", example = "1023")
private Long fromFirmwareId;
@Schema(description = "来源固件版本", example = "1.0.0")
private String fromFirmwareVersion;
@Schema(description = "升级状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "升级进度,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
private Integer progress;
@Schema(description = "升级进度描述", example = "正在下载固件...")
private String description;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime updateTime;
}

View File

@@ -1,30 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.record;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
@Schema(description = "管理后台 - IoT OTA 升级记录分页 Request VO")
public class IotOtaUpgradeRecordPageReqVO extends PageParam {
// TODO @li已经有注解不用重复注释
/**
* 升级任务编号字段。
* <p>
* 该字段用于标识升级任务的唯一编号,不能为空。
*/
@Schema(description = "升级任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "升级任务编号不能为空")
private Long taskId;
/**
* 设备标识字段。
* <p>
* 该字段用于标识设备的名称,通常用于区分不同的设备。
*/
@Schema(description = "设备标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "摄像头A1-1")
private String deviceName;
}

View File

@@ -1,108 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.record;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceMessageDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaUpgradeTaskDO;
import com.fhs.core.trans.anno.Trans;
import com.fhs.core.trans.constant.TransType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@Schema(description = "管理后台 - IoT OTA 升级记录 Response VO")
public class IotOtaUpgradeRecordRespVO {
/**
* 升级记录编号
*/
@Schema(description = "升级记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
/**
* 固件编号
* <p>
* 关联 {@link IotOtaFirmwareDO#getId()}
*/
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@Trans(type = TransType.SIMPLE, target = IotOtaFirmwareDO.class, fields = {"version"}, refs = {"firmwareVersion"})
private Long firmwareId;
/**
* 固件版本
*/
@Schema(description = "固件版本", requiredMode = Schema.RequiredMode.REQUIRED, example = "v1.0.0")
private String firmwareVersion;
/**
* 任务编号
* <p>
* 关联 {@link IotOtaUpgradeTaskDO#getId()}
*/
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long taskId;
/**
* 产品标识
* <p>
* 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO#getId()}
*/
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "iot")
private String productKey;
/**
* 设备名称
* <p>
* 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO#getId()}
*/
@Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "iot")
private String deviceName;
/**
* 设备编号
* <p>
* 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO#getId()}
*/
@Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String deviceId;
/**
* 来源的固件编号
* <p>
* 关联 {@link IotDeviceDO#getFirmwareId()}
*/
@Schema(description = "来源的固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@Trans(type = TransType.SIMPLE, target = IotOtaFirmwareDO.class, fields = {"version"}, refs = {"fromFirmwareVersion"})
private Long fromFirmwareId;
/**
* 来源的固件版本
*/
@Schema(description = "来源的固件版本", requiredMode = Schema.RequiredMode.REQUIRED, example = "v1.0.0")
private String fromFirmwareVersion;
/**
* 升级状态
* <p>
* 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeRecordStatusEnum}
*/
@Schema(description = "升级状态", requiredMode = Schema.RequiredMode.REQUIRED, allowableValues = {"0", "10", "20", "30", "40", "50"})
private Integer status;
/**
* 升级进度,百分比
*/
@Schema(description = "升级进度,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private Integer progress;
/**
* 升级进度描述
* <p>
* 注意,只记录设备最后一次的升级进度描述
* 如果想看历史记录,可以查看 {@link IotDeviceMessageDO} 设备日志
*/
@Schema(description = "升级进度描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private String description;
/**
* 升级开始时间
*/
@Schema(description = "升级开始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-08 07:30:00")
private LocalDateTime startTime;
/**
* 升级结束时间
*/
@Schema(description = "升级结束时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-08 07:30:00")
private LocalDateTime endTime;
}

View File

@@ -1,25 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
@Schema(description = "管理后台 - IoT OTA 升级任务分页 Request VO")
public class IotOtaUpgradeTaskPageReqVO extends PageParam {
/**
* 任务名称字段,用于描述任务的名称
*/
@Schema(description = "任务名称", example = "升级任务")
private String name;
/**
* 固件编号字段,用于唯一标识固件,不能为空
*/
@NotNull(message = "固件编号不能为空")
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long firmwareId;
}

View File

@@ -1,82 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.upgrade.task;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
import com.fhs.core.trans.vo.VO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
@Schema(description = "管理后台 - IoT OTA 升级任务 Response VO")
public class IotOtaUpgradeTaskRespVO implements VO {
/**
* 任务编号
*/
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
/**
* 任务名称
*/
@Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "升级任务")
private String name;
/**
* 任务描述
*/
@Schema(description = "任务描述", example = "升级任务")
private String description;
/**
* 固件编号
* <p>
* 关联 {@link IotOtaFirmwareDO#getId()}
*/
@Schema(description = "固件编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long firmwareId;
/**
* 任务状态
* <p>
* 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeTaskStatusEnum}
*/
@Schema(description = "任务状态", requiredMode = Schema.RequiredMode.REQUIRED, allowableValues = {"10", "20", "21", "30"})
private Integer status;
/**
* 任务状态名称
*/
@Schema(description = "任务状态名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "进行中")
private String statusName;
/**
* 升级范围
* <p>
* 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeTaskScopeEnum}
*/
@Schema(description = "升级范围", requiredMode = Schema.RequiredMode.REQUIRED, allowableValues = {"1", "2"})
private Integer scope;
/**
* 设备数量
*/
@Schema(description = "设备数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long deviceCount;
/**
* 选中的设备编号数组
* <p>
* 关联 {@link IotDeviceDO#getId()}
*/
@Schema(description = "选中的设备编号数组", example = "1024")
private List<Long> deviceIds;
/**
* 选中的设备名字数组
* <p>
* 关联 {@link IotDeviceDO#getDeviceName()}
*/
@Schema(description = "选中的设备名字数组", example = "1024")
private List<String> deviceNames;
/**
* 创建时间
*/
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-08 07:30:00")
private LocalDateTime createTime;
}

View File

@@ -143,7 +143,7 @@ public class IotProductController {
@GetMapping("/simple-list")
@Operation(summary = "获取产品的精简信息列表", description = "主要用于前端的下拉选项")
public CommonResult<List<IotProductRespVO>> getSimpleProductList() {
public CommonResult<List<IotProductRespVO>> getProductSimpleList() {
List<IotProductDO> list = productService.getProductList();
return success(convertList(list, product -> // 只返回 id、name 字段
new IotProductRespVO().setId(product.getId()).setName(product.getName())

View File

@@ -1,84 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgeRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgeSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO;
import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@Tag(name = "管理后台 - IoT 数据桥梁")
@RestController
@RequestMapping("/iot/data-bridge")
@Validated
public class IotDataBridgeController {
@Resource
private IotDataBridgeService dataBridgeService;
@PostMapping("/create")
@Operation(summary = "创建数据桥梁")
@PreAuthorize("@ss.hasPermission('iot:data-bridge:create')")
public CommonResult<Long> createDataBridge(@Valid @RequestBody IotDataBridgeSaveReqVO createReqVO) {
return success(dataBridgeService.createDataBridge(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新数据桥梁")
@PreAuthorize("@ss.hasPermission('iot:data-bridge:update')")
public CommonResult<Boolean> updateDataBridge(@Valid @RequestBody IotDataBridgeSaveReqVO updateReqVO) {
dataBridgeService.updateDataBridge(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除数据桥梁")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('iot:data-bridge:delete')")
public CommonResult<Boolean> deleteDataBridge(@RequestParam("id") Long id) {
dataBridgeService.deleteDataBridge(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得数据桥梁")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('iot:data-bridge:query')")
public CommonResult<IotDataBridgeRespVO> getDataBridge(@RequestParam("id") Long id) {
IotDataBridgeDO dataBridge = dataBridgeService.getDataBridge(id);
return success(BeanUtils.toBean(dataBridge, IotDataBridgeRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得数据桥梁分页")
@PreAuthorize("@ss.hasPermission('iot:data-bridge:query')")
public CommonResult<PageResult<IotDataBridgeRespVO>> getDataBridgePage(@Valid IotDataBridgePageReqVO pageReqVO) {
PageResult<IotDataBridgeDO> pageResult = dataBridgeService.getDataBridgePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, IotDataBridgeRespVO.class));
}
@GetMapping("/simple-list")
@Operation(summary = "获取数据桥梁的精简信息列表", description = "主要用于前端的下拉选项")
public CommonResult<List<IotDataBridgeRespVO>> getSimpleDataBridgeList() {
List<IotDataBridgeDO> list = dataBridgeService.getDataBridgeList(CommonStatusEnum.ENABLE.getStatus());
return success(convertList(list, dataBridge -> // 只返回 id、name 字段
new IotDataBridgeRespVO().setId(dataBridge.getId()).setName(dataBridge.getName())));
}
}

View File

@@ -0,0 +1,72 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.rule.IotDataRulePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.rule.IotDataRuleRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.rule.IotDataRuleSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataRuleDO;
import cn.iocoder.yudao.module.iot.service.rule.data.IotDataRuleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - IoT 数据流转规则")
@RestController
@RequestMapping("/iot/data-rule")
@Validated
public class IotDataRuleController {
@Resource
private IotDataRuleService dataRuleService;
@PostMapping("/create")
@Operation(summary = "创建数据流转规则")
@PreAuthorize("@ss.hasPermission('iot:data-rule:create')")
public CommonResult<Long> createDataRule(@Valid @RequestBody IotDataRuleSaveReqVO createReqVO) {
return success(dataRuleService.createDataRule(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新数据流转规则")
@PreAuthorize("@ss.hasPermission('iot:data-rule:update')")
public CommonResult<Boolean> updateDataRule(@Valid @RequestBody IotDataRuleSaveReqVO updateReqVO) {
dataRuleService.updateDataRule(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除数据流转规则")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('iot:data-rule:delete')")
public CommonResult<Boolean> deleteDataRule(@RequestParam("id") Long id) {
dataRuleService.deleteDataRule(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得数据流转规则")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('iot:data-rule:query')")
public CommonResult<IotDataRuleRespVO> getDataRule(@RequestParam("id") Long id) {
IotDataRuleDO dataRule = dataRuleService.getDataRule(id);
return success(BeanUtils.toBean(dataRule, IotDataRuleRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得数据流转规则分页")
@PreAuthorize("@ss.hasPermission('iot:data-rule:query')")
public CommonResult<PageResult<IotDataRuleRespVO>> getDataRulePage(@Valid IotDataRulePageReqVO pageReqVO) {
PageResult<IotDataRuleDO> pageResult = dataRuleService.getDataRulePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, IotDataRuleRespVO.class));
}
}

View File

@@ -0,0 +1,84 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.sink.IotDataSinkPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.sink.IotDataSinkRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.sink.IotDataSinkSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataSinkDO;
import cn.iocoder.yudao.module.iot.service.rule.data.IotDataSinkService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@Tag(name = "管理后台 - IoT 数据流转目的")
@RestController
@RequestMapping("/iot/data-sink")
@Validated
public class IotDataSinkController {
@Resource
private IotDataSinkService dataSinkService;
@PostMapping("/create")
@Operation(summary = "创建数据目的")
@PreAuthorize("@ss.hasPermission('iot:data-sink:create')")
public CommonResult<Long> createDataSink(@Valid @RequestBody IotDataSinkSaveReqVO createReqVO) {
return success(dataSinkService.createDataSink(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新数据目的")
@PreAuthorize("@ss.hasPermission('iot:data-sink:update')")
public CommonResult<Boolean> updateDataSink(@Valid @RequestBody IotDataSinkSaveReqVO updateReqVO) {
dataSinkService.updateDataSink(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除数据目的")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('iot:data-sink:delete')")
public CommonResult<Boolean> deleteDataSink(@RequestParam("id") Long id) {
dataSinkService.deleteDataSink(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得数据目的")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('iot:data-sink:query')")
public CommonResult<IotDataSinkRespVO> getDataSink(@RequestParam("id") Long id) {
IotDataSinkDO sink = dataSinkService.getDataSink(id);
return success(BeanUtils.toBean(sink, IotDataSinkRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得数据目的分页")
@PreAuthorize("@ss.hasPermission('iot:data-sink:query')")
public CommonResult<PageResult<IotDataSinkRespVO>> getDataSinkPage(@Valid IotDataSinkPageReqVO pageReqVO) {
PageResult<IotDataSinkDO> pageResult = dataSinkService.getDataSinkPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, IotDataSinkRespVO.class));
}
@GetMapping("/simple-list")
@Operation(summary = "获取数据目的的精简信息列表", description = "主要用于前端的下拉选项")
public CommonResult<List<IotDataSinkRespVO>> getDataSinkSimpleList() {
List<IotDataSinkDO> list = dataSinkService.getDataSinkListByStatus(CommonStatusEnum.ENABLE.getStatus());
return success(convertList(list, sink -> // 只返回 id、name 字段
new IotDataSinkRespVO().setId(sink.getId()).setName(sink.getName())));
}
}

View File

@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -7,7 +8,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePa
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
import cn.iocoder.yudao.module.iot.service.rule.IotRuleSceneService;
import cn.iocoder.yudao.module.iot.service.rule.scene.IotRuleSceneService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -18,7 +19,10 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@Tag(name = "管理后台 - IoT 场景联动")
@RestController
@@ -70,6 +74,14 @@ public class IotRuleSceneController {
return success(BeanUtils.toBean(pageResult, IotRuleSceneRespVO.class));
}
@GetMapping("/simple-list")
@Operation(summary = "获取场景联动的精简信息列表", description = "主要用于前端的下拉选项")
public CommonResult<List<IotRuleSceneRespVO>> getRuleSceneSimpleList() {
List<IotRuleSceneDO> list = ruleSceneService.getRuleSceneListByStatus(CommonStatusEnum.ENABLE.getStatus());
return success(convertList(list, scene -> // 只返回 id、name 字段
new IotRuleSceneRespVO().setId(scene.getId()).setName(scene.getName())));
}
@GetMapping("/test")
@PermitAll
public void test() {

View File

@@ -0,0 +1 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data;

View File

@@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.rule;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
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 = "管理后台 - IoT 数据流转规则分页 Request VO")
@Data
public class IotDataRulePageReqVO extends PageParam {
@Schema(description = "数据流转规则名称", example = "芋艿")
private String name;
@Schema(description = "数据流转规则状态", example = "1")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.rule;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataRuleDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - IoT 数据流转规则 Response VO")
@Data
public class IotDataRuleRespVO {
@Schema(description = "数据流转规则编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8540")
private Long id;
@Schema(description = "数据流转规则名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
private String name;
@Schema(description = "数据流转规则描述", example = "你猜")
private String description;
@Schema(description = "数据流转规则状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "数据源配置数组", requiredMode = Schema.RequiredMode.REQUIRED)
private List<IotDataRuleDO.SourceConfig> sourceConfigs;
@Schema(description = "数据目的编号数组", requiredMode = Schema.RequiredMode.REQUIRED)
private List<Long> sinkIds;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.rule;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataRuleDO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - IoT 数据流转规则新增/修改 Request VO")
@Data
public class IotDataRuleSaveReqVO {
@Schema(description = "数据流转规则编号", example = "8540")
private Long id;
@Schema(description = "数据流转规则名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@NotEmpty(message = "数据流转规则名称不能为空")
private String name;
@Schema(description = "数据流转规则描述", example = "你猜")
private String description;
@Schema(description = "数据流转规则状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "数据流转规则状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
@Schema(description = "数据源配置数组", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "数据源配置数组不能为空")
private List<IotDataRuleDO.SourceConfig> sourceConfigs;
@Schema(description = "数据目的编号数组", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "数据目的编号数组不能为空")
private List<Long> sinkIds;
}

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge;
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.sink;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
@@ -11,14 +11,14 @@ import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - IoT 数据桥梁分页 Request VO")
@Schema(description = "管理后台 - IoT 数据流转目的分页 Request VO")
@Data
public class IotDataBridgePageReqVO extends PageParam {
public class IotDataSinkPageReqVO extends PageParam {
@Schema(description = "桥梁名称", example = "赵六")
@Schema(description = "数据目的名称", example = "赵六")
private String name;
@Schema(description = "桥梁状态", example = "1")
@Schema(description = "数据目的状态", example = "2")
@InEnum(CommonStatusEnum.class)
private Integer status;

View File

@@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.sink;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotAbstractDataSinkConfig;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - IoT 数据流转目的 Response VO")
@Data
public class IotDataSinkRespVO {
@Schema(description = "数据目的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18564")
private Long id;
@Schema(description = "数据目的名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
private String name;
@Schema(description = "数据目的描述", example = "随便")
private String description;
@Schema(description = "数据目的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "数据目的类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer type;
@Schema(description = "数据目的配置")
private IotAbstractDataSinkConfig config;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.sink;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotAbstractDataSinkConfig;
import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - IoT 数据流转目的新增/修改 Request VO")
@Data
public class IotDataSinkSaveReqVO {
@Schema(description = "数据目的编号", example = "18564")
private Long id;
@Schema(description = "数据目的名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
@NotEmpty(message = "数据目的名称不能为空")
private String name;
@Schema(description = "数据目的描述", example = "随便")
private String description;
@Schema(description = "数据目的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "数据目的状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
@Schema(description = "数据目的类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "数据目的类型不能为空")
@InEnum(IotDataSinkTypeEnum.class)
private Integer type;
@Schema(description = "数据目的配置")
@NotNull(message = "数据目的配置不能为空")
private IotAbstractDataSinkConfig config;
}

View File

@@ -1,37 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeAbstractConfig;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - IoT 数据桥梁 Response VO")
@Data
public class IotDataBridgeRespVO {
@Schema(description = "桥梁编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18564")
private Long id;
@Schema(description = "桥梁名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
private String name;
@Schema(description = "桥梁描述", example = "随便")
private String description;
@Schema(description = "桥梁状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "桥梁方向", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer direction;
@Schema(description = "桥梁类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer type;
@Schema(description = "桥梁配置")
private IotDataBridgeAbstractConfig config;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@@ -1,46 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeAbstractConfig;
import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeDirectionEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - IoT 数据桥梁新增/修改 Request VO")
@Data
public class IotDataBridgeSaveReqVO {
@Schema(description = "桥梁编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18564")
private Long id;
@Schema(description = "桥梁名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
@NotEmpty(message = "桥梁名称不能为空")
private String name;
@Schema(description = "桥梁描述", example = "随便")
private String description;
@Schema(description = "桥梁状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "桥梁状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
@Schema(description = "桥梁方向", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "桥梁方向不能为空")
@InEnum(IotDataBridgeDirectionEnum.class)
private Integer direction;
@Schema(description = "桥梁类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "桥梁类型不能为空")
@InEnum(IotDataBridgeTypeEnum.class)
private Integer type;
@Schema(description = "桥梁配置")
@NotNull(message = "桥梁配置不能为空")
private IotDataBridgeAbstractConfig config;
}

View File

@@ -1,35 +0,0 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config;
import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data;
/**
* IoT IotDataBridgeConfig 抽象类
*
* 用于表示数据桥梁配置数据的通用类型,根据具体的 "type" 字段动态映射到对应的子类
* 提供多态支持,适用于不同类型的数据结构序列化和反序列化场景。
*
* @author HUIHUI
*/
@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = IotDataBridgeHttpConfig.class, name = "1"),
@JsonSubTypes.Type(value = IotDataBridgeMqttConfig.class, name = "10"),
@JsonSubTypes.Type(value = IotDataBridgeRedisStreamConfig.class, name = "21"),
@JsonSubTypes.Type(value = IotDataBridgeRocketMQConfig.class, name = "30"),
@JsonSubTypes.Type(value = IotDataBridgeRabbitMQConfig.class, name = "31"),
@JsonSubTypes.Type(value = IotDataBridgeKafkaMQConfig.class, name = "32"),
})
public abstract class IotDataBridgeAbstractConfig {
/**
* 配置类型
*
* 枚举 {@link IotDataBridgeTypeEnum#getType()}
*/
private String type;
}

View File

@@ -1,14 +1,15 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.*;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum;
import cn.iocoder.yudao.module.iot.service.product.IotProductService;
import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService;
import com.google.common.base.Objects;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -32,6 +33,8 @@ public class IotThingModelController {
@Resource
private IotThingModelService thingModelService;
@Resource
private IotProductService productService;
@PostMapping("/create")
@Operation(summary = "创建产品物模型")
@@ -71,23 +74,21 @@ public class IotThingModelController {
@Parameter(name = "productId", description = "产品 ID", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('iot:thing-model:query')")
public CommonResult<IotThingModelTSLRespVO> getThingModelTsl(@RequestParam("productId") Long productId) {
IotThingModelTSLRespVO tslRespVO = new IotThingModelTSLRespVO();
// TODO @puhui999是不是要先查询产品哈原因是万一没配置物模型但是产品已经有了
// 1. 获得产品所有物模型定义
List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductId(productId);
if (CollUtil.isEmpty(thingModels)) {
return success(tslRespVO);
// 1. 获得产品
IotProductDO product = productService.getProduct(productId);
if (product == null) {
return success(null);
}
// 2. 设置公共部分参数
IotThingModelDO thingModel = thingModels.get(0);
tslRespVO.setProductId(thingModel.getProductId()).setProductKey(thingModel.getProductKey());
IotThingModelTSLRespVO tslRespVO = new IotThingModelTSLRespVO()
.setProductId(product.getId()).setProductKey(product.getProductKey());
// 2. 获得物模型定义
List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductId(productId);
tslRespVO.setProperties(convertList(filterList(thingModels, item ->
ObjUtil.equal(IotThingModelTypeEnum.PROPERTY.getType(), item.getType())), IotThingModelDO::getProperty));
tslRespVO.setServices(convertList(filterList(thingModels, item ->
ObjUtil.equal(IotThingModelTypeEnum.SERVICE.getType(), item.getType())), IotThingModelDO::getService));
tslRespVO.setEvents(convertList(filterList(thingModels, item ->
ObjUtil.equal(IotThingModelTypeEnum.EVENT.getType(), item.getType())), IotThingModelDO::getEvent));
Objects.equal(IotThingModelTypeEnum.PROPERTY.getType(), item.getType())), IotThingModelDO::getProperty))
.setServices(convertList(filterList(thingModels, item ->
Objects.equal(IotThingModelTypeEnum.SERVICE.getType(), item.getType())), IotThingModelDO::getService))
.setEvents(convertList(filterList(thingModels, item ->
Objects.equal(IotThingModelTypeEnum.EVENT.getType(), item.getType())), IotThingModelDO::getEvent));
return success(tslRespVO);
}

View File

@@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelService;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@@ -1,9 +1,9 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelService;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;

View File

@@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelService;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@@ -12,7 +12,7 @@ import java.util.List;
@Data
public class IotThingModelTSLRespVO {
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long productId;
@Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor")

View File

@@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.iot.convert.thingmodel;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelService;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum;

View File

@@ -1,14 +1,21 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.rule;
package cn.iocoder.yudao.module.iot.dal.dataobject.alert;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.iot.enums.rule.IotAlertConfigReceiveTypeEnum;
import cn.iocoder.yudao.framework.mybatis.core.type.IntegerListTypeHandler;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
import cn.iocoder.yudao.module.iot.enums.DictTypeConstants;
import cn.iocoder.yudao.module.iot.enums.alert.IotAlertReceiveTypeEnum;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@@ -17,13 +24,13 @@ import java.util.List;
*
* @author 芋道源码
*/
@TableName("iot_alert_config")
@TableName(value = "iot_alert_config", autoResultMap = true)
@KeySequence("iot_alert_config_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IotAlertConfig extends BaseDO {
public class IotAlertConfigDO extends BaseDO {
/**
* 配置编号
@@ -41,37 +48,37 @@ public class IotAlertConfig extends BaseDO {
/**
* 配置状态
*
* TODO 数据字典
* 字典 {@link DictTypeConstants#ALERT_LEVEL}
*/
private Integer level;
/**
* 配置状态
*
* 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 关联的规则场景编号数组
* 关联的场景联动规则编号数组
*
* 关联 {@link IotRuleSceneDO#getId()}
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<Long> ruleSceneIds;
@TableField(typeHandler = LongListTypeHandler.class)
private List<Long> sceneRuleIds;
/**
* 接收的用户编号数组
*
* 关联 {@link AdminUserRespDTO#getId()}
*/
@TableField(typeHandler = JacksonTypeHandler.class)
@TableField(typeHandler = LongListTypeHandler.class)
private List<Long> receiveUserIds;
/**
* 接收的类型数组
*
* 枚举 {@link IotAlertConfigReceiveTypeEnum}
* 枚举 {@link IotAlertReceiveTypeEnum}
*/
@TableField(typeHandler = JacksonTypeHandler.class)
@TableField(typeHandler = IntegerListTypeHandler.class)
private List<Integer> receiveTypes;
}

View File

@@ -1,11 +1,13 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.rule;
package cn.iocoder.yudao.module.iot.dal.dataobject.alert;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.AllArgsConstructor;
@@ -18,7 +20,7 @@ import lombok.NoArgsConstructor;
*
* @author 芋道源码
*/
@TableName("iot_alert_record")
@TableName(value = "iot_alert_record", autoResultMap = true)
@KeySequence("iot_alert_record_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@Builder
@@ -29,47 +31,54 @@ public class IotAlertRecordDO extends BaseDO {
/**
* 记录编号
*/
@TableField
@TableId
private Long id;
/**
* 告警名称
*
* 冗余 {@link IotAlertConfig#getName()}
* 冗余 {@link IotAlertConfigDO#getId()}
*/
private Long configId;
/**
* 告警名称
*
* 冗余 {@link IotAlertConfig#getName()}
* 冗余 {@link IotAlertConfigDO#getName()}
*/
private String name;
private String configName;
/**
* 告警级别
*
* 冗余 {@link IotAlertConfigDO#getLevel()}
* 字典 {@link cn.iocoder.yudao.module.iot.enums.DictTypeConstants#ALERT_LEVEL}
*/
private Integer configLevel;
/**
* 场景规则编号
*
* 关联 {@link IotRuleSceneDO#getId()}
*/
private Long sceneRuleId;
/**
* 产品标识
* 产品编号
*
* 关联 {@link IotProductDO#getProductKey()} ()}
* 关联 {@link IotProductDO#getId()}
*/
private String productKey;
private Long productId;
/**
* 设备名称
* 设备编号
*
* 冗余 {@link IotDeviceDO#getDeviceName()}
* 关联 {@link IotDeviceDO#getId()}
*/
private String deviceName;
// TODO @芋艿有没更好的方式
private Long deviceId;
/**
* 触发的设备消息
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private IotDeviceMessage deviceMessage;
// TODO @芋艿换成枚举枚举对应 ApiErrorLogProcessStatusEnum
/**
* 处理状态
*
* true - 已处理
* false - 未处理
* 是否处理
*/
private Boolean processStatus;
/**

View File

@@ -28,6 +28,11 @@ import java.util.Set;
@AllArgsConstructor
public class IotDeviceDO extends TenantBaseDO {
/**
* 设备编号 - 全部设备
*/
public static final Long DEVICE_ID_ALL = 0L;
/**
* 设备 ID主键自增
*/
@@ -112,7 +117,7 @@ public class IotDeviceDO extends TenantBaseDO {
*
* 关联 {@link IotOtaFirmwareDO#getId()}
*/
private String firmwareId;
private Long firmwareId;
/**
* 设备密钥,用于设备认证

View File

@@ -1,10 +1,14 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.ota;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* IoT OTA 固件 DO
@@ -24,14 +28,14 @@ public class IotOtaFirmwareDO extends BaseDO {
/**
* 固件编号
*/
@TableField
@TableId
private Long id;
/**
* 固件名称
*/
private String name;
/**
* 固件版本
* 固件描述
*/
private String description;
/**
@@ -44,37 +48,25 @@ public class IotOtaFirmwareDO extends BaseDO {
*
* 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO#getId()}
*/
// TODO @li帮我改成 Long 哈,写错了
private String productId;
/**
* 产品标识
*
* 冗余 {@link cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO#getProductKey()}
*/
private String productKey;
private Long productId;
/**
* 签名方式
*
* 例如说MD5、SHA256
* 固件文件 URL
*/
private String signMethod;
/**
* 固件文件签名
*/
private String fileSign;
private String fileUrl;
/**
* 固件文件大小
*/
private Long fileSize;
/**
* 固件文件 URL
* 固件文件签名算法
*
* 枚举 {@link DigestAlgorithm},目前只使用 MD5
*/
private String fileUrl;
private String fileDigestAlgorithm;
/**
* 自定义信息,建议使用 JSON 格式
* 固件文件签名结果
*/
private String information;
private String fileDigestValue;
}

View File

@@ -0,0 +1,70 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.ota;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.iot.enums.ota.IotOtaTaskDeviceScopeEnum;
import cn.iocoder.yudao.module.iot.enums.ota.IotOtaTaskStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* IoT OTA 升级任务 DO
*
* @author 芋道源码
*/
@TableName(value = "iot_ota_task", autoResultMap = true)
@KeySequence("iot_ota_task_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IotOtaTaskDO extends BaseDO {
/**
* 任务编号
*/
@TableId
private Long id;
/**
* 任务名称
*/
private String name;
/**
* 任务描述
*/
private String description;
/**
* 固件编号
* <p>
* 关联 {@link IotOtaFirmwareDO#getId()}
*/
private Long firmwareId;
/**
* 任务状态
* <p>
* 关联 {@link IotOtaTaskStatusEnum}
*/
private Integer status;
/**
* 设备升级范围
* <p>
* 关联 {@link IotOtaTaskDeviceScopeEnum}
*/
private Integer deviceScope;
/**
* 设备总数数量
*/
private Integer deviceTotalCount;
/**
* 设备成功数量
*/
private Integer deviceSuccessCount;
}

View File

@@ -3,25 +3,27 @@ package cn.iocoder.yudao.module.iot.dal.dataobject.ota;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceMessageDO;
import cn.iocoder.yudao.module.iot.enums.ota.IotOtaTaskRecordStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* IoT OTA 升级记录 DO
* IoT OTA 升级任务记录 DO
*
* @author 芋道源码
*/
@TableName(value = "iot_ota_upgrade_record", autoResultMap = true)
@KeySequence("iot_ota_upgrade_record_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@TableName(value = "iot_ota_task_record", autoResultMap = true)
@KeySequence("iot_ota_task_record_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IotOtaUpgradeRecordDO extends BaseDO {
public class IotOtaTaskRecordDO extends BaseDO {
@TableId
private Long id;
@@ -35,28 +37,16 @@ public class IotOtaUpgradeRecordDO extends BaseDO {
/**
* 任务编号
*
* 关联 {@link IotOtaUpgradeTaskDO#getId()}
* 关联 {@link IotOtaTaskDO#getId()}
*/
private Long taskId;
/**
* 产品标识
*
* 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO#getId()}
*/
private String productKey;
/**
* 设备名称
*
* 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO#getId()}
*/
private String deviceName;
/**
* 设备编号
*
* 关联 {@link cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO#getId()}
* 关联 {@link IotDeviceDO#getId()}
*/
private String deviceId;
private Long deviceId;
/**
* 来源的固件编号
*
@@ -67,7 +57,7 @@ public class IotOtaUpgradeRecordDO extends BaseDO {
/**
* 升级状态
*
* 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeRecordStatusEnum}
* 关联 {@link IotOtaTaskRecordStatusEnum}
*/
private Integer status;
/**
@@ -81,13 +71,5 @@ public class IotOtaUpgradeRecordDO extends BaseDO {
* 如果想看历史记录可以查看 {@link IotDeviceMessageDO} 设备日志
*/
private String description;
/**
* 升级开始时间
*/
private LocalDateTime startTime;
/**
* 升级结束时间
*/
private LocalDateTime endTime;
}

View File

@@ -1,72 +0,0 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.ota;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.util.List;
/**
* IoT OTA 升级任务 DO
*
* @author 芋道源码
*/
@TableName(value = "iot_ota_upgrade_task", autoResultMap = true)
@KeySequence("iot_ota_upgrade_task_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IotOtaUpgradeTaskDO extends BaseDO {
/**
* 任务编号
*/
@TableField
private Long id;
/**
* 任务名称
*/
private String name;
/**
* 任务描述
*/
private String description;
/**
* 固件编号
* <p>
* 关联 {@link IotOtaFirmwareDO#getId()}
*/
private Long firmwareId;
/**
* 任务状态
* <p>
* 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeTaskStatusEnum}
*/
private Integer status;
/**
* 升级范围
* <p>
* 关联 {@link cn.iocoder.yudao.module.iot.enums.ota.IotOtaUpgradeTaskScopeEnum}
*/
private Integer scope;
/**
* 设备数量
*/
private Long deviceCount;
/**
* 选中的设备编号数组
* <p>
* 关联 {@link IotDeviceDO#getId()}
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<Long> deviceIds;
}

View File

@@ -0,0 +1,109 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.rule;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* IoT 数据流转规则 DO
*
* 监听 {@link SourceConfig} 数据源,转发到 {@link IotDataSinkDO} 数据目的
*
* @author 芋道源码
*/
@TableName(value = "iot_data_rule", autoResultMap = true)
@KeySequence("iot_data_rule_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IotDataRuleDO extends BaseDO {
/**
* 数据流转规格编号
*/
private Long id;
/**
* 数据流转规格名称
*/
private String name;
/**
* 数据流转规格描述
*/
private String description;
/**
* 数据流转规格状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 数据源配置数组
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<SourceConfig> sourceConfigs;
/**
* 数据目的编号数组
*
* 关联 {@link IotDataSinkDO#getId()}
*/
@TableField(typeHandler = LongListTypeHandler.class)
private List<Long> sinkIds;
// TODO @芋艿:未来考虑使用 groovy支持数据处理
/**
* 数据源配置
*/
@Data
public static class SourceConfig {
/**
* 消息方法
*
* 枚举 {@link IotDeviceMessageMethodEnum} 中的 upstream 上行部分
*/
@NotEmpty(message = "消息方法不能为空")
private String method;
/**
* 产品编号
*
* 关联 {@link IotProductDO#getId()}
*/
private Long productId;
/**
* 设备编号
*
* 关联 {@link IotDeviceDO#getId()}
* 特殊:如果为 {@link IotDeviceDO#DEVICE_ID_ALL} 时,则是全部设备
*/
@NotEmpty(message = "设备编号不能为空")
private Long deviceId;
/**
* 标识符
*
* 1. 物模型时,对应:{@link IotThingModelDO#getIdentifier()}
*/
private String identifier;
}
}

View File

@@ -2,66 +2,61 @@ package cn.iocoder.yudao.module.iot.dal.dataobject.rule;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeAbstractConfig;
import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeDirectionEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotAbstractDataSinkConfig;
import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* IoT 数据桥梁 DO
* IoT 数据流转目的 DO
*
* @author 芋道源码
*/
@TableName(value = "iot_data_bridge", autoResultMap = true)
@TableName(value = "iot_data_sink", autoResultMap = true)
@KeySequence("iot_data_bridge_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IotDataBridgeDO extends BaseDO {
public class IotDataSinkDO extends BaseDO {
/**
* 桥梁编号
* 数据流转目的编号
*/
@TableId
private Long id;
/**
* 桥梁名称
* 数据流转目的名称
*/
private String name;
/**
* 桥梁描述
* 数据流转目的描述
*/
private String description;
/**
* 桥梁状态
* 数据流转目的状态
*
* 枚举 {@link CommonStatusEnum}
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 桥梁方向
*
* 枚举 {@link IotDataBridgeDirectionEnum}
*/
private Integer direction;
/**
* 桥梁类型
* 数据流转目的类型
*
* 枚举 {@link IotDataBridgeTypeEnum}
* 枚举 {@link IotDataSinkTypeEnum}
*/
private Integer type;
/**
* 桥梁配置
* 数据流转目的配置
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private IotDataBridgeAbstractConfig config;
private IotAbstractDataSinkConfig config;
}

View File

@@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerConditionParameterOperatorEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneConditionOperatorEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
@@ -22,8 +22,9 @@ import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
// TODO @芋艿:优化注释;
/**
* IoT 场景联动 DO
* IoT 场景联动规则 DO
*
* @author 芋道源码
*/
@@ -163,7 +164,7 @@ public class IotRuleSceneDO extends TenantBaseDO {
/**
* 操作符
*
* 枚举 {@link IotRuleSceneTriggerConditionParameterOperatorEnum}
* 枚举 {@link IotRuleSceneConditionOperatorEnum}
*/
private String operator;
@@ -171,7 +172,7 @@ public class IotRuleSceneDO extends TenantBaseDO {
* 比较值
*
* 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。
* 例如说,{@link IotRuleSceneTriggerConditionParameterOperatorEnum#IN}、{@link IotRuleSceneTriggerConditionParameterOperatorEnum#BETWEEN}
* 例如说,{@link IotRuleSceneConditionOperatorEnum#IN}、{@link IotRuleSceneConditionOperatorEnum#BETWEEN}
*/
private String value;
@@ -193,18 +194,10 @@ public class IotRuleSceneDO extends TenantBaseDO {
/**
* 设备控制
*
* 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DEVICE_CONTROL} 时
* 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DEVICE_PROPERTY_SET} 时
*/
private ActionDeviceControl deviceControl;
/**
* 数据桥接编号
*
* 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DATA_BRIDGE} 时
* 关联:{@link IotDataBridgeDO#getId()}
*/
private Long dataBridgeId;
}
/**

View File

@@ -0,0 +1,240 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.rule;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneConditionOperatorEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneConditionTypeEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
// TODO @puhui999还是在 IotRuleSceneDO 里搞,这里主要可以看到变化字段哈。
/**
* IoT 场景联动 DO
*
* 基于 {@link Trigger} 触发 {@link Action}
*
* @author 芋道源码
*/
@TableName(value = "iot_scene_rule", autoResultMap = true)
@KeySequence("iot_scene_rule_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IotSceneRuleDO extends TenantBaseDO {
/**
* 场景联动编号
*/
@TableId
private Long id;
/**
* 场景联动名称
*/
private String name;
/**
* 场景联动描述
*/
private String description;
/**
* 场景联动状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 场景定义配置
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<Trigger> triggers;
/**
* 场景动作配置
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<Action> actions;
/**
* 场景定义配置
*/
@Data
public static class Trigger {
// ========== 事件部分 ==========
/**
* 场景事件类型
*
* 枚举 {@link IotRuleSceneTriggerTypeEnum}
* 1. {@link IotRuleSceneTriggerTypeEnum#DEVICE_STATE_UPDATE} 时operator 非空,并且 value 为在线状态
* 2. {@link IotRuleSceneTriggerTypeEnum#DEVICE_PROPERTY_POST}
* {@link IotRuleSceneTriggerTypeEnum#DEVICE_EVENT_POST} 时identifier、operator 非空,并且 value 为属性值
* 3. {@link IotRuleSceneTriggerTypeEnum#DEVICE_EVENT_POST}
* {@link IotRuleSceneTriggerTypeEnum#DEVICE_SERVICE_INVOKE} 时identifier 非空,但是 operator、value 为空
* 4. {@link IotRuleSceneTriggerTypeEnum#TIMER} 时conditions 非空,并且设备无关(无需 productId、deviceId 字段)
*/
private Integer type;
/**
* 产品编号
*
* 关联 {@link IotProductDO#getId()}
*/
private Long productId;
/**
* 设备编号
*
* 关联 {@link IotDeviceDO#getId()}
* 特殊:如果为 {@link IotDeviceDO#DEVICE_ID_ALL} 时,则是全部设备
*/
private Long deviceId;
/**
* 物模型标识符
*
* 对应:{@link IotThingModelDO#getIdentifier()}
*/
private String identifier;
/**
* 操作符
*
* 枚举 {@link IotRuleSceneConditionOperatorEnum}
*/
private String operator;
/**
* 参数(属性值、在线状态)
*
* 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。
* 例如说,{@link IotRuleSceneConditionOperatorEnum#IN}、{@link IotRuleSceneConditionOperatorEnum#BETWEEN}
*/
private String value;
/**
* CRON 表达式
*/
private String cronExpression;
// ========== 条件部分 ==========
/**
* 触发条件分组(状态条件分组)的数组
*
* 第一层 List分组与分组之间是“或”的关系
* 第二层 List条件与条件之间是“且”的关系
*/
private List<List<TriggerCondition>> conditionGroups;
}
/**
* 触发条件(状态条件)
*/
@Data
public static class TriggerCondition {
/**
* 触发条件类型
*
* 枚举 {@link IotRuleSceneConditionTypeEnum}
* 1. {@link IotRuleSceneConditionTypeEnum#DEVICE_STATE} 时operator 非空,并且 value 为在线状态
* 2. {@link IotRuleSceneConditionTypeEnum#DEVICE_PROPERTY} 时identifier、operator 非空,并且 value 为属性值
* 3. {@link IotRuleSceneConditionTypeEnum#CURRENT_TIME} 时operator 非空(使用 DATE_TIME_ 和 TIME_ 部分),并且 value 非空
*/
private Integer type;
/**
* 产品编号
*
* 关联 {@link IotProductDO#getId()}
*/
private Long productId;
/**
* 设备编号
*
* 关联 {@link IotDeviceDO#getId()}
*/
private Long deviceId;
/**
* 标识符(属性)
*
* 关联 {@link IotThingModelDO#getIdentifier()}
*/
private String identifier;
/**
* 操作符
*
* 枚举 {@link IotRuleSceneConditionOperatorEnum}
*/
private String operator;
/**
* 参数
*
* 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。
* 例如说,{@link IotRuleSceneConditionOperatorEnum#IN}、{@link IotRuleSceneConditionOperatorEnum#BETWEEN}
*/
private String param;
}
/**
* 场景动作配置
*/
@Data
public static class Action {
/**
* 执行类型
*
* 枚举 {@link IotRuleSceneActionTypeEnum}
* 1. {@link IotRuleSceneActionTypeEnum#DEVICE_PROPERTY_SET} 时params 非空
* {@link IotRuleSceneActionTypeEnum#DEVICE_SERVICE_INVOKE} 时params 非空
* 2. {@link IotRuleSceneActionTypeEnum#ALERT_TRIGGER} 时alertConfigId 为空,因为是 {@link IotAlertConfigDO} 里面关联它
* 3. {@link IotRuleSceneActionTypeEnum#ALERT_RECOVER} 时alertConfigId 非空
*/
private Integer type;
/**
* 产品编号
*
* 关联 {@link IotProductDO#getId()}
*/
private Long productId;
/**
* 设备编号
*
* 关联 {@link IotDeviceDO#getId()}
*/
private Long deviceId;
/**
* 请求参数
*
* 一般来说,对应 {@link IotDeviceMessage#getParams()} 请求参数
*/
private Object params;
/**
* 告警配置编号
*
* 关联 {@link IotAlertConfigDO#getId()}
*/
private Long alertConfigId;
}
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.rule.config;
import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data;
/**
* IoT IotDataBridgeConfig 抽象类
*
* 用于表示数据目的配置数据的通用类型,根据具体的 "type" 字段动态映射到对应的子类
* 提供多态支持,适用于不同类型的数据结构序列化和反序列化场景。
*
* @author HUIHUI
*/
@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = IotDataSinkHttpConfig.class, name = "1"),
@JsonSubTypes.Type(value = IotDataSinkMqttConfig.class, name = "10"),
@JsonSubTypes.Type(value = IotDataSinkRedisStreamConfig.class, name = "21"),
@JsonSubTypes.Type(value = IotDataSinkRocketMQConfig.class, name = "30"),
@JsonSubTypes.Type(value = IotDataSinkRabbitMQConfig.class, name = "31"),
@JsonSubTypes.Type(value = IotDataSinkKafkaConfig.class, name = "32"),
})
public abstract class IotAbstractDataSinkConfig {
/**
* 配置类型
*
* 枚举 {@link IotDataSinkTypeEnum#getType()}
*/
private String type;
}

View File

@@ -1,16 +1,16 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config;
package cn.iocoder.yudao.module.iot.dal.dataobject.rule.config;
import lombok.Data;
import java.util.Map;
/**
* IoT HTTP 配置 {@link IotDataBridgeAbstractConfig} 实现类
* IoT HTTP 配置 {@link IotAbstractDataSinkConfig} 实现类
*
* @author HUIHUI
*/
@Data
public class IotDataBridgeHttpConfig extends IotDataBridgeAbstractConfig {
public class IotDataSinkHttpConfig extends IotAbstractDataSinkConfig {
/**
* 请求 URL

View File

@@ -1,14 +1,14 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config;
package cn.iocoder.yudao.module.iot.dal.dataobject.rule.config;
import lombok.Data;
/**
* IoT Kafka 配置 {@link IotDataBridgeAbstractConfig} 实现类
* IoT Kafka 配置 {@link IotAbstractDataSinkConfig} 实现类
*
* @author HUIHUI
*/
@Data
public class IotDataBridgeKafkaMQConfig extends IotDataBridgeAbstractConfig {
public class IotDataSinkKafkaConfig extends IotAbstractDataSinkConfig {
/**
* Kafka 服务器地址

View File

@@ -1,14 +1,14 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config;
package cn.iocoder.yudao.module.iot.dal.dataobject.rule.config;
import lombok.Data;
/**
* IoT MQTT 配置 {@link IotDataBridgeAbstractConfig} 实现类
* IoT MQTT 配置 {@link IotAbstractDataSinkConfig} 实现类
*
* @author HUIHUI
*/
@Data
public class IotDataBridgeMqttConfig extends IotDataBridgeAbstractConfig {
public class IotDataSinkMqttConfig extends IotAbstractDataSinkConfig {
/**
* MQTT 服务器地址

View File

@@ -1,14 +1,14 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config;
package cn.iocoder.yudao.module.iot.dal.dataobject.rule.config;
import lombok.Data;
/**
* IoT RabbitMQ 配置 {@link IotDataBridgeAbstractConfig} 实现类
* IoT RabbitMQ 配置 {@link IotAbstractDataSinkConfig} 实现类
*
* @author HUIHUI
*/
@Data
public class IotDataBridgeRabbitMQConfig extends IotDataBridgeAbstractConfig {
public class IotDataSinkRabbitMQConfig extends IotAbstractDataSinkConfig {
/**
* RabbitMQ 服务器地址

View File

@@ -1,14 +1,14 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config;
package cn.iocoder.yudao.module.iot.dal.dataobject.rule.config;
import lombok.Data;
/**
* IoT Redis Stream 配置 {@link IotDataBridgeAbstractConfig} 实现类
* IoT Redis Stream 配置 {@link IotAbstractDataSinkConfig} 实现类
*
* @author HUIHUI
*/
@Data
public class IotDataBridgeRedisStreamConfig extends IotDataBridgeAbstractConfig {
public class IotDataSinkRedisStreamConfig extends IotAbstractDataSinkConfig {
/**
* Redis 服务器地址

View File

@@ -1,14 +1,14 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config;
package cn.iocoder.yudao.module.iot.dal.dataobject.rule.config;
import lombok.Data;
/**
* IoT RocketMQ 配置 {@link IotDataBridgeAbstractConfig} 实现类
* IoT RocketMQ 配置 {@link IotAbstractDataSinkConfig} 实现类
*
* @author HUIHUI
*/
@Data
public class IotDataBridgeRocketMQConfig extends IotDataBridgeAbstractConfig {
public class IotDataSinkRocketMQConfig extends IotAbstractDataSinkConfig {
/**
* RocketMQ 名称服务器地址

View File

@@ -1,9 +1,9 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelService;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model;
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelServiceEventTypeEnum;
@@ -9,6 +9,7 @@ import lombok.Data;
import java.util.List;
// TODO @puhui999感觉这个是不是放到 dal 里会好点讨论下先不改哈
/**
* IoT 物模型中的事件
*

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model;
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDataSpecs;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelParamDirectionEnum;
import jakarta.validation.constraints.NotEmpty;

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model;
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType.ThingModelDataSpecs;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelAccessModeEnum;
import jakarta.validation.constraints.NotEmpty;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model;
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelServiceCallTypeEnum;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType;
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.validation.Valid;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType;
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.validation.constraints.NotEmpty;
@@ -10,7 +10,7 @@ import lombok.EqualsAndHashCode;
/**
* IoT 物模型数据类型为布尔型或枚举型的 DataSpec 定义
*
* 数据类型取值为 bool enum
* 数据类型取值为 bool enum
*
* @author HUIHUI
*/

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType;
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@@ -7,8 +7,8 @@ import lombok.Data;
/**
* IoT ThingModelDataSpecs 抽象类
*
* 用于表示物模型数据的通用类型根据具体的 "dataType" 字段动态映射到对应的子类
* 提供多态支持适用于不同类型的数据结构序列化和反序列化场景
* 用于表示物模型数据的通用类型根据具体的 "dataType" 字段动态映射到对应的子类
* 提供多态支持适用于不同类型的数据结构序列化和反序列化场景
*
* @author HUIHUI
*/

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType;
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.validation.constraints.Max;
@@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode;
/**
* IoT 物模型数据类型为时间型或文本型的 DataSpec 定义
*
* 数据类型取值为 date text
* 数据类型取值为 date text
*
* @author HUIHUI
*/
@@ -18,13 +18,14 @@ import lombok.EqualsAndHashCode;
public class ThingModelDateOrTextDataSpecs extends ThingModelDataSpecs {
/**
* 数据长度单位为字节取值不能超过 2048
* dataType text 需传入该参数
* 数据长度单位为字节取值不能超过 2048
*
* dataType text 需传入该参数
*/
@Max(value = 2048, message = "数据长度不能超过 2048")
private Integer length;
/**
* 默认值可选参数用于存储默认值
* 默认值可选参数用于存储默认值
*/
private String defaultValue;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType;
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.validation.constraints.NotEmpty;
@@ -9,7 +9,7 @@ import lombok.EqualsAndHashCode;
/**
* IoT 物模型数据类型为数值的 DataSpec 定义
*
* 数据类型取值为 intfloat double
* 数据类型取值为 intfloat double
*
* @author HUIHUI
*/
@@ -19,37 +19,37 @@ import lombok.EqualsAndHashCode;
public class ThingModelNumericDataSpec extends ThingModelDataSpecs {
/**
* 最大值需转为字符串类型值必须与 dataType 类型一致
* 最大值需转为字符串类型值必须与 dataType 类型一致
*/
@NotEmpty(message = "最大值不能为空")
@Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "最大值必须为数值类型")
private String max;
/**
* 最小值需转为字符串类型值必须与 dataType 类型一致
* 最小值需转为字符串类型值必须与 dataType 类型一致
*/
@NotEmpty(message = "最小值不能为空")
@Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "最小值必须为数值类型")
private String min;
/**
* 步长需转为字符串类型值必须与 dataType 类型一致
* 步长需转为字符串类型值必须与 dataType 类型一致
*/
@NotEmpty(message = "步长不能为空")
@Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "步长必须为数值类型")
private String step;
/**
* 精度 dataType float double 时可选传入
* 精度 dataType float double 时可选传入
*/
private String precise;
/**
* 默认值可传入用于存储的默认值
* 默认值可传入用于存储的默认值
*/
private String defaultValue;
/**
* 单位的符号
* 单位的符号
*/
private String unit;
/**
* 单位的名称
* 单位的名称
*/
private String unitName;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType;
package cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.dataType;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelAccessModeEnum;

View File

@@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.iot.dal.mysql.alert;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.config.IotAlertConfigPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* IoT 告警配置 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface IotAlertConfigMapper extends BaseMapperX<IotAlertConfigDO> {
default PageResult<IotAlertConfigDO> selectPage(IotAlertConfigPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<IotAlertConfigDO>()
.likeIfPresent(IotAlertConfigDO::getName, reqVO.getName())
.eqIfPresent(IotAlertConfigDO::getStatus, reqVO.getStatus())
.betweenIfPresent(IotAlertConfigDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(IotAlertConfigDO::getId));
}
default List<IotAlertConfigDO> selectListByStatus(Integer status) {
return selectList(IotAlertConfigDO::getStatus, status);
}
default List<IotAlertConfigDO> selectListBySceneRuleIdAndStatus(Long sceneRuleId, Integer status) {
return selectList(new LambdaQueryWrapperX<IotAlertConfigDO>()
.eq(IotAlertConfigDO::getStatus, status)
.apply(MyBatisUtils.findInSet("scene_rule_id", sceneRuleId)));
}
}

View File

@@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.iot.dal.mysql.alert;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.alert.vo.recrod.IotAlertRecordPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
import java.util.List;
/**
* IoT 告警记录 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface IotAlertRecordMapper extends BaseMapperX<IotAlertRecordDO> {
default PageResult<IotAlertRecordDO> selectPage(IotAlertRecordPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<IotAlertRecordDO>()
.eqIfPresent(IotAlertRecordDO::getConfigId, reqVO.getConfigId())
.eqIfPresent(IotAlertRecordDO::getConfigLevel, reqVO.getLevel())
.eqIfPresent(IotAlertRecordDO::getProductId, reqVO.getProductId())
.eqIfPresent(IotAlertRecordDO::getDeviceId, reqVO.getDeviceId())
.eqIfPresent(IotAlertRecordDO::getProcessStatus, reqVO.getProcessStatus())
.betweenIfPresent(IotAlertRecordDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(IotAlertRecordDO::getId));
}
default List<IotAlertRecordDO> selectListBySceneRuleId(Long sceneRuleId, Long deviceId, Boolean processStatus) {
return selectList(new LambdaQueryWrapperX<IotAlertRecordDO>()
.eq(IotAlertRecordDO::getSceneRuleId, sceneRuleId)
.eqIfPresent(IotAlertRecordDO::getDeviceId, deviceId)
.eqIfPresent(IotAlertRecordDO::getProcessStatus, processStatus)
.orderByDesc(IotAlertRecordDO::getId));
}
default int updateList(Collection<Long> ids, IotAlertRecordDO updateObj) {
return update(updateObj, new LambdaUpdateWrapper<IotAlertRecordDO>()
.in(IotAlertRecordDO::getId, ids));
}
}

View File

@@ -6,13 +6,15 @@ 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.device.IotDevicePageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Nullable;
import org.apache.ibatis.annotations.Mapper;
import javax.annotation.Nullable;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* IoT 设备 Mapper
@@ -50,8 +52,11 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> {
return selectCount(IotDeviceDO::getProductId, productId);
}
default List<IotDeviceDO> selectListByDeviceType(Integer deviceType) {
return selectList(IotDeviceDO::getDeviceType, deviceType);
default List<IotDeviceDO> selectListByCondition(@Nullable Integer deviceType,
@Nullable Long productId) {
return selectList(new LambdaQueryWrapperX<IotDeviceDO>()
.eqIfPresent(IotDeviceDO::getDeviceType, deviceType)
.eqIfPresent(IotDeviceDO::getProductId, productId));
}
default List<IotDeviceDO> selectListByState(Integer state) {
@@ -78,20 +83,38 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> {
.in(IotDeviceDO::getDeviceName, deviceNames));
}
/**
* 查询指定产品下各状态的设备数量
*
* @return 设备数量统计列表
*/
// TODO @super通过 mybatis-plus 来写哈,然后返回 Map 貌似就行了?!
List<Map<String, Object>> selectDeviceCountMapByProductId();
default IotDeviceDO selectBySerialNumber(String serialNumber) {
return selectOne(IotDeviceDO::getSerialNumber, serialNumber);
}
/**
* 查询指定产品下的设备数量
*
* @return 产品编号 -> 设备数量的映射
*/
default Map<Long, Integer> selectDeviceCountMapByProductId() {
List<Map<String, Object>> result = selectMaps(new QueryWrapper<IotDeviceDO>()
.select("product_id AS productId", "COUNT(1) AS deviceCount")
.groupBy("product_id"));
return result.stream().collect(Collectors.toMap(
map -> Long.valueOf(map.get("productId").toString()),
map -> Integer.valueOf(map.get("deviceCount").toString())
));
}
// TODO @super通过 mybatis-plus 来写哈,然后返回 Map 貌似就行了?!
/**
* 查询各个状态下的设备数量
*
* @return 设备数量统计列表
* @return 设备状态 -> 设备数量的映射
*/
List<Map<String, Object>> selectDeviceCountGroupByState();
default Map<Integer, Long> selectDeviceCountGroupByState() {
List<Map<String, Object>> result = selectMaps(new QueryWrapper<IotDeviceDO>()
.select("state", "COUNT(1) AS deviceCount")
.groupBy("state"));
return result.stream().collect(Collectors.toMap(
map -> Integer.valueOf(map.get("state").toString()),
map -> Long.valueOf(map.get("deviceCount").toString())
));
}
}

View File

@@ -7,34 +7,19 @@ import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.firmware.IotOtaFirmwa
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
// TODO @li参考 IotOtaUpgradeRecordMapper 的写法
@Mapper
public interface IotOtaFirmwareMapper extends BaseMapperX<IotOtaFirmwareDO> {
/**
* 根据产品ID和固件版本号查询固件信息列表。
*
* @param productId 产品ID用于筛选固件信息。
* @param version 固件版本号,用于筛选固件信息。
* @return 返回符合条件的固件信息列表。
*/
default List<IotOtaFirmwareDO> selectByProductIdAndVersion(String productId, String version) {
return selectList(IotOtaFirmwareDO::getProductId, productId,
default IotOtaFirmwareDO selectByProductIdAndVersion(Long productId, String version) {
return selectOne(IotOtaFirmwareDO::getProductId, productId,
IotOtaFirmwareDO::getVersion, version);
}
/**
* 分页查询固件信息支持根据名称和产品ID进行筛选并按创建时间降序排列。
*
* @param pageReqVO 分页查询请求对象,包含分页参数和筛选条件。
* @return 返回分页查询结果,包含符合条件的固件信息列表。
*/
default PageResult<IotOtaFirmwareDO> selectPage(IotOtaFirmwarePageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<IotOtaFirmwareDO>()
.likeIfPresent(IotOtaFirmwareDO::getName, pageReqVO.getName())
.eqIfPresent(IotOtaFirmwareDO::getProductId, pageReqVO.getProductId())
.betweenIfPresent(IotOtaFirmwareDO::getCreateTime, pageReqVO.getCreateTime())
.orderByDesc(IotOtaFirmwareDO::getCreateTime));
}

View File

@@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.iot.dal.mysql.ota;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.ota.vo.task.IotOtaTaskPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface IotOtaTaskMapper extends BaseMapperX<IotOtaTaskDO> {
default IotOtaTaskDO selectByFirmwareIdAndName(Long firmwareId, String name) {
return selectOne(IotOtaTaskDO::getFirmwareId, firmwareId,
IotOtaTaskDO::getName, name);
}
default PageResult<IotOtaTaskDO> selectUpgradeTaskPage(IotOtaTaskPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<IotOtaTaskDO>()
.eqIfPresent(IotOtaTaskDO::getFirmwareId, pageReqVO.getFirmwareId())
.likeIfPresent(IotOtaTaskDO::getName, pageReqVO.getName()));
}
}

View File

@@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.iot.dal.mysql.ota;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.ota.vo.task.record.IotOtaTaskRecordPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskRecordDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import java.util.Set;
@Mapper
public interface IotOtaTaskRecordMapper extends BaseMapperX<IotOtaTaskRecordDO> {
default List<IotOtaTaskRecordDO> selectListByFirmwareIdAndTaskId(Long firmwareId, Long taskId) {
return selectList(new LambdaQueryWrapperX<IotOtaTaskRecordDO>()
.eqIfPresent(IotOtaTaskRecordDO::getFirmwareId, firmwareId)
.eqIfPresent(IotOtaTaskRecordDO::getTaskId, taskId)
.select(IotOtaTaskRecordDO::getDeviceId, IotOtaTaskRecordDO::getStatus));
}
default PageResult<IotOtaTaskRecordDO> selectPage(IotOtaTaskRecordPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<IotOtaTaskRecordDO>()
.eqIfPresent(IotOtaTaskRecordDO::getTaskId, pageReqVO.getTaskId())
.eqIfPresent(IotOtaTaskRecordDO::getStatus, pageReqVO.getStatus()));
}
default void updateByTaskIdAndStatus(Long taskId, Integer fromStatus, IotOtaTaskRecordDO updateRecord) {
update(updateRecord, new LambdaUpdateWrapper<IotOtaTaskRecordDO>()
.eq(IotOtaTaskRecordDO::getTaskId, taskId)
.eq(IotOtaTaskRecordDO::getStatus, fromStatus));
}
default List<IotOtaTaskRecordDO> selectListByDeviceIdAndStatus(Set<Long> deviceIds, Set<Integer> statuses) {
return selectList(new LambdaQueryWrapperX<IotOtaTaskRecordDO>()
.inIfPresent(IotOtaTaskRecordDO::getDeviceId, deviceIds)
.inIfPresent(IotOtaTaskRecordDO::getStatus, statuses));
}
}

View File

@@ -1,159 +0,0 @@
package cn.iocoder.yudao.module.iot.dal.mysql.ota;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.ota.vo.upgrade.record.IotOtaUpgradeRecordPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaUpgradeRecordDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
@Mapper
public interface IotOtaUpgradeRecordMapper extends BaseMapperX<IotOtaUpgradeRecordDO> {
// TODO @liselectByFirmwareIdAndTaskIdAndDeviceId让方法自解释
/**
* 根据条件查询单个OTA升级记录
*
* @param firmwareId 固件ID可选参数用于筛选固件ID匹配的记录
* @param taskId 任务ID可选参数用于筛选任务ID匹配的记录
* @param deviceId 设备ID可选参数用于筛选设备ID匹配的记录
* @return 返回符合条件的单个OTA升级记录如果不存在则返回null
*/
default IotOtaUpgradeRecordDO selectByConditions(Long firmwareId, Long taskId, String deviceId) {
// 使用LambdaQueryWrapperX构建查询条件根据传入的参数动态添加查询条件
return selectOne(new LambdaQueryWrapperX<IotOtaUpgradeRecordDO>()
.eqIfPresent(IotOtaUpgradeRecordDO::getFirmwareId, firmwareId)
.eqIfPresent(IotOtaUpgradeRecordDO::getTaskId, taskId)
.eqIfPresent(IotOtaUpgradeRecordDO::getDeviceId, deviceId));
}
// TODO @li这个是不是 groupby status 就 ok 拉?
/**
* 根据任务ID和设备名称查询OTA升级记录的状态统计信息。
* 该函数通过SQL查询统计不同状态0到5的记录数量并返回一个包含统计结果的Map列表。
*
* @param taskId 任务ID用于筛选特定任务的OTA升级记录。
* @param deviceName 设备名称支持模糊查询用于筛选特定设备的OTA升级记录。
* @return 返回一个Map列表每个Map包含不同状态0到5的记录数量。
*/
@Select("select count(case when status = 0 then 1 else 0) as `0` " +
"count(case when status = 1 then 1 else 0) as `1` " +
"count(case when status = 2 then 1 else 0) as `2` " +
"count(case when status = 3 then 1 else 0) as `3` " +
"count(case when status = 4 then 1 else 0) as `4` " +
"count(case when status = 5 then 1 else 0) as `5` " +
"from iot_ota_upgrade_record " +
"where task_id = #{taskId} " +
"and device_name like concat('%', #{deviceName}, '%') " +
"and status = #{status}")
List<Map<String, Object>> selectOtaUpgradeRecordCount(@Param("taskId") Long taskId,
@Param("deviceName") String deviceName);
/**
* 根据固件ID查询OTA升级记录的状态统计信息。
* 该函数通过SQL查询统计不同状态0到5的记录数量并返回一个包含统计结果的Map列表。
*
* @param firmwareId 固件ID用于筛选特定固件的OTA升级记录。
* @return 返回一个Map列表每个Map包含不同状态0到5的记录数量。
*/
@Select("select count(case when status = 0 then 1 else 0) as `0` " +
"count(case when status = 1 then 1 else 0) as `1` " +
"count(case when status = 2 then 1 else 0) as `2` " +
"count(case when status = 3 then 1 else 0) as `3` " +
"count(case when status = 4 then 1 else 0) as `4` " +
"count(case when status = 5 then 1 else 0) as `5` " +
"from iot_ota_upgrade_record " +
"where firmware_id = #{firmwareId}")
List<Map<String, Object>> selectOtaUpgradeRecordStatistics(Long firmwareId);
// TODO @li这里的注释可以去掉哈
/**
* 根据分页查询条件获取 OTA升级记录的分页结果
*
* @param pageReqVO 分页查询请求参数包含设备名称、任务ID等查询条件
* @return 返回分页查询结果,包含符合条件的 OTA升级记录列表
*/
// TODO @liselectPage 就 ok 拉。
default PageResult<IotOtaUpgradeRecordDO> selectUpgradeRecordPage(IotOtaUpgradeRecordPageReqVO pageReqVO) {
// TODO @li这里的注释可以去掉哈然后下面的“如果”。。。也没必要注释
// 使用LambdaQueryWrapperX构建查询条件并根据请求参数动态添加查询条件
return selectPage(pageReqVO, new LambdaQueryWrapperX<IotOtaUpgradeRecordDO>()
.likeIfPresent(IotOtaUpgradeRecordDO::getDeviceName, pageReqVO.getDeviceName()) // 如果设备名称存在,则添加模糊查询条件
.eqIfPresent(IotOtaUpgradeRecordDO::getTaskId, pageReqVO.getTaskId())); // 如果任务ID存在则添加等值查询条件
}
// TODO @li这里的注释可以去掉哈
/**
* 根据任务ID和状态更新升级记录的状态
* <p>
* 该函数用于将符合指定任务ID和状态的升级记录的状态更新为新的状态。
*
* @param setStatus 要设置的新状态值类型为Integer
* @param taskId 要更新的升级记录对应的任务ID类型为Long
* @param whereStatus 用于筛选升级记录的当前状态值类型为Integer
*/
// TODO @li改成 updateByTaskIdAndStatus(taskId, status, IotOtaUpgradeRecordDO) 更通用一些。
default void updateUpgradeRecordStatusByTaskIdAndStatus(Integer setStatus, Long taskId, Integer whereStatus) {
// 使用LambdaUpdateWrapper构建更新条件将指定状态的记录更新为指定状态
update(new LambdaUpdateWrapper<IotOtaUpgradeRecordDO>()
.set(IotOtaUpgradeRecordDO::getStatus, setStatus)
.eq(IotOtaUpgradeRecordDO::getTaskId, taskId)
.eq(IotOtaUpgradeRecordDO::getStatus, whereStatus)
);
}
// TODO @li参考上面的建议调整下这个方法
/**
* 根据状态查询符合条件的升级记录列表
* <p>
* 该函数使用LambdaQueryWrapperX构建查询条件查询指定状态的升级记录。
*
* @param state 升级记录的状态,用于筛选符合条件的记录
* @return 返回符合指定状态的升级记录列表类型为List<IotOtaUpgradeRecordDO>
*/
default List<IotOtaUpgradeRecordDO> selectUpgradeRecordListByState(Integer state) {
// 使用LambdaQueryWrapperX构建查询条件根据状态查询符合条件的升级记录
return selectList(new LambdaQueryWrapperX<IotOtaUpgradeRecordDO>()
.eq(IotOtaUpgradeRecordDO::getStatus, state));
}
// TODO @li参考上面的建议调整下这个方法
/**
* 更新升级记录状态
* <p>
* 该函数用于批量更新指定ID列表中的升级记录状态。通过传入的ID列表和状态值使用LambdaUpdateWrapper构建更新条件
* 并执行更新操作。
*
* @param ids 需要更新的升级记录ID列表类型为List<Long>。传入的ID列表中的记录将被更新。
* @param status 要更新的状态值类型为Integer。该值将被设置到符合条件的升级记录中。
*/
default void updateUpgradeRecordStatus(List<Long> ids, Integer status) {
// 使用LambdaUpdateWrapper构建更新条件设置状态字段并根据ID列表进行筛选
update(new LambdaUpdateWrapper<IotOtaUpgradeRecordDO>()
.set(IotOtaUpgradeRecordDO::getStatus, status)
.in(IotOtaUpgradeRecordDO::getId, ids)
);
}
// TODO @li参考上面的建议调整下这个方法
/**
* 根据任务ID查询升级记录列表
* <p>
* 该函数通过任务ID查询符合条件的升级记录并返回查询结果列表。
*
* @param taskId 任务ID用于筛选升级记录
* @return 返回符合条件的升级记录列表,若未找到则返回空列表
*/
default List<IotOtaUpgradeRecordDO> selectUpgradeRecordListByTaskId(Long taskId) {
// 使用LambdaQueryWrapperX构建查询条件根据任务ID查询符合条件的升级记录
return selectList(new LambdaQueryWrapperX<IotOtaUpgradeRecordDO>()
.eq(IotOtaUpgradeRecordDO::getTaskId, taskId));
}
}

View File

@@ -1,57 +0,0 @@
package cn.iocoder.yudao.module.iot.dal.mysql.ota;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.ota.vo.upgrade.task.IotOtaUpgradeTaskPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaUpgradeTaskDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* OTA 升级任务Mapper
*
* @author Shelly
*/
@Mapper
public interface IotOtaUpgradeTaskMapper extends BaseMapperX<IotOtaUpgradeTaskDO> {
/**
* 根据固件ID和任务名称查询升级任务列表。
*
* @param firmwareId 固件ID用于筛选升级任务
* @param name 任务名称,用于筛选升级任务
* @return 符合条件的升级任务列表
*/
default List<IotOtaUpgradeTaskDO> selectByFirmwareIdAndName(Long firmwareId, String name) {
return selectList(new LambdaQueryWrapperX<IotOtaUpgradeTaskDO>()
.eqIfPresent(IotOtaUpgradeTaskDO::getFirmwareId, firmwareId)
.eqIfPresent(IotOtaUpgradeTaskDO::getName, name));
}
/**
* 分页查询升级任务列表支持根据固件ID和任务名称进行筛选。
*
* @param pageReqVO 分页查询请求对象,包含分页参数和筛选条件
* @return 分页结果,包含符合条件的升级任务列表
*/
default PageResult<IotOtaUpgradeTaskDO> selectUpgradeTaskPage(IotOtaUpgradeTaskPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<IotOtaUpgradeTaskDO>()
.eqIfPresent(IotOtaUpgradeTaskDO::getFirmwareId, pageReqVO.getFirmwareId())
.likeIfPresent(IotOtaUpgradeTaskDO::getName, pageReqVO.getName()));
}
/**
* 根据任务状态查询升级任务列表
* <p>
* 该函数通过传入的任务状态,查询数据库中符合条件的升级任务列表。
*
* @param status 任务状态,用于筛选升级任务的状态值
* @return 返回符合条件的升级任务列表,列表中的每个元素为 IotOtaUpgradeTaskDO 对象
*/
default List<IotOtaUpgradeTaskDO> selectUpgradeTaskByState(Integer status) {
return selectList(IotOtaUpgradeTaskDO::getStatus, status);
}
}

View File

@@ -1,34 +0,0 @@
package cn.iocoder.yudao.module.iot.dal.mysql.rule;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.rule.vo.databridge.IotDataBridgePageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* IoT 数据桥梁 Mapper
*
* @author HUIHUI
*/
@Mapper
public interface IotDataBridgeMapper extends BaseMapperX<IotDataBridgeDO> {
default PageResult<IotDataBridgeDO> selectPage(IotDataBridgePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<IotDataBridgeDO>()
.likeIfPresent(IotDataBridgeDO::getName, reqVO.getName())
.eqIfPresent(IotDataBridgeDO::getStatus, reqVO.getStatus())
.betweenIfPresent(IotDataBridgeDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(IotDataBridgeDO::getId));
}
default List<IotDataBridgeDO> selectList(Integer status) {
return selectList(new LambdaQueryWrapperX<IotDataBridgeDO>()
.eqIfPresent(IotDataBridgeDO::getStatus, status)
.orderByDesc(IotDataBridgeDO::getId));
}
}

View File

@@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.iot.dal.mysql.rule;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.rule.IotDataRulePageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataRuleDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* IoT 数据流转规则 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface IotDataRuleMapper extends BaseMapperX<IotDataRuleDO> {
default PageResult<IotDataRuleDO> selectPage(IotDataRulePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<IotDataRuleDO>()
.likeIfPresent(IotDataRuleDO::getName, reqVO.getName())
.eqIfPresent(IotDataRuleDO::getStatus, reqVO.getStatus())
.betweenIfPresent(IotDataRuleDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(IotDataRuleDO::getId));
}
default List<IotDataRuleDO> selectListBySinkId(Long sinkId) {
return selectList(new LambdaQueryWrapperX<IotDataRuleDO>()
.apply(MyBatisUtils.findInSet("sink_ids", sinkId)));
}
default List<IotDataRuleDO> selectListByStatus(Integer status) {
return selectList(IotDataRuleDO::getStatus, status);
}
}

View File

@@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.iot.dal.mysql.rule;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.rule.vo.data.sink.IotDataSinkPageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataSinkDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* IoT 数据流转目的 Mapper
*
* @author HUIHUI
*/
@Mapper
public interface IotDataSinkMapper extends BaseMapperX<IotDataSinkDO> {
default PageResult<IotDataSinkDO> selectPage(IotDataSinkPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<IotDataSinkDO>()
.likeIfPresent(IotDataSinkDO::getName, reqVO.getName())
.eqIfPresent(IotDataSinkDO::getStatus, reqVO.getStatus())
.betweenIfPresent(IotDataSinkDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(IotDataSinkDO::getId));
}
default List<IotDataSinkDO> selectListByStatus(Integer status) {
return selectList(IotDataSinkDO::getStatus, status);
}
}

View File

@@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePa
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* IoT 场景联动 Mapper
*
@@ -24,4 +26,8 @@ public interface IotRuleSceneMapper extends BaseMapperX<IotRuleSceneDO> {
.orderByDesc(IotRuleSceneDO::getId));
}
default List<IotRuleSceneDO> selectListByStatus(Integer status) {
return selectList(IotRuleSceneDO::getStatus, status);
}
}

View File

@@ -25,8 +25,6 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> {
.likeIfPresent(IotThingModelDO::getName, reqVO.getName())
.eqIfPresent(IotThingModelDO::getType, reqVO.getType())
.eqIfPresent(IotThingModelDO::getProductId, reqVO.getProductId())
// TODO @芋艿:看看要不要加枚举
.notIn(IotThingModelDO::getIdentifier, "get", "set", "post")
.orderByDesc(IotThingModelDO::getId));
}
@@ -36,8 +34,6 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> {
.likeIfPresent(IotThingModelDO::getName, reqVO.getName())
.eqIfPresent(IotThingModelDO::getType, reqVO.getType())
.eqIfPresent(IotThingModelDO::getProductId, reqVO.getProductId())
// TODO @芋艿:看看要不要加枚举
.notIn(IotThingModelDO::getIdentifier, "get", "set", "post")
.orderByDesc(IotThingModelDO::getId));
}
@@ -61,15 +57,6 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> {
IotThingModelDO::getType, type);
}
default List<IotThingModelDO> selectListByProductIdAndIdentifiersAndTypes(Long productId,
List<String> identifiers,
List<Integer> types) {
return selectList(new LambdaQueryWrapperX<IotThingModelDO>()
.eq(IotThingModelDO::getProductId, productId)
.in(IotThingModelDO::getIdentifier, identifiers)
.in(IotThingModelDO::getType, types));
}
default IotThingModelDO selectByProductIdAndName(Long productId, String name) {
return selectOne(IotThingModelDO::getProductId, productId,
IotThingModelDO::getName, name);

Some files were not shown because too many files have changed in this diff Show More