From ecf6a4a8463d416dc5a6b8b1d143458f4b98dd89 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 1 Jul 2025 22:10:29 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E3=80=90IoT=20=E7=89=A9=E8=81=94?= =?UTF-8?q?=E7=BD=91=E3=80=91=E5=A2=9E=E5=8A=A0=20OTA=20=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/ota/IotOtaTaskRecordController.java | 38 ++-- .../ota/vo/task/IotOtaTaskCreateReqVO.java | 2 + .../record/IotOtaTaskRecordPageReqVO.java | 7 +- .../task/record/IotOtaTaskRecordRespVO.java | 14 -- .../dal/dataobject/device/IotDeviceDO.java | 2 +- .../iot/dal/dataobject/ota/IotOtaTaskDO.java | 2 +- .../dataobject/ota/IotOtaTaskRecordDO.java | 15 +- .../dal/mysql/ota/IotOtaFirmwareMapper.java | 13 +- .../iot/dal/mysql/ota/IotOtaTaskMapper.java | 14 +- .../dal/mysql/ota/IotOtaTaskRecordMapper.java | 41 ++++ .../mysql/ota/IotOtaUpgradeRecordMapper.java | 111 ----------- .../module/iot/enums/DictTypeConstants.java | 3 + .../module/iot/enums/ErrorCodeConstants.java | 23 ++- .../enums/ota/IotOtaTaskRecordStatusEnum.java | 14 ++ .../iot/service/device/IotDeviceService.java | 17 +- .../service/device/IotDeviceServiceImpl.java | 14 +- .../service/ota/IotOtaFirmwareService.java | 2 +- .../ota/IotOtaFirmwareServiceImpl.java | 28 ++- .../service/ota/IotOtaTaskRecordService.java | 60 +++--- .../ota/IotOtaTaskRecordServiceImpl.java | 183 +++++------------- .../iot/service/ota/IotOtaTaskService.java | 2 +- .../service/ota/IotOtaTaskServiceImpl.java | 120 ++++++------ .../rule/data/IotDataRuleServiceImpl.java | 2 +- 23 files changed, 278 insertions(+), 449 deletions(-) create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaTaskRecordMapper.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaUpgradeRecordMapper.java diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaTaskRecordController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaTaskRecordController.java index e2b8d0aa48..1110ff8f49 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaTaskRecordController.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaTaskRecordController.java @@ -9,12 +9,16 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskRecordDO; 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.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +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; @@ -22,31 +26,29 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @Tag(name = "管理后台 - IoT OTA 升级任务记录") @RestController -@RequestMapping("/iot/ota/task-record") +@RequestMapping("/iot/ota/task/record") @Validated public class IotOtaTaskRecordController { @Resource private IotOtaTaskRecordService otaTaskRecordService; - @GetMapping("/get-statistics") - @Operation(summary = "固件升级设备统计") + @GetMapping("/get-status-count") + @Operation(summary = "获得 OTA 升级记录状态统计") + @Parameters({ + @Parameter(name = "firmwareId", description = "固件编号", example = "1024"), + @Parameter(name = "taskId", description = "升级任务编号", example = "2048") + }) @PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')") - @Parameter(name = "firmwareId", description = "固件编号", required = true, example = "1024") - public CommonResult> getOtaTaskRecordStatistics(@RequestParam(value = "firmwareId") Long firmwareId) { - return success(otaTaskRecordService.getOtaTaskRecordStatistics(firmwareId)); - } - - @GetMapping("/get-count") - @Operation(summary = "获得升级记录分页 tab 数量") - @PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')") - public CommonResult> getOtaTaskRecordCount(@Valid IotOtaTaskRecordPageReqVO pageReqVO) { - return success(otaTaskRecordService.getOtaTaskRecordCount(pageReqVO)); + public CommonResult> getOtaTaskRecordStatusCountMap( + @RequestParam(value = "firmwareId", required = false) Long firmwareId, + @RequestParam(value = "taskId", required = false) Long taskId) { + return success(otaTaskRecordService.getOtaTaskRecordStatusCountMap(firmwareId, taskId)); } @GetMapping("/page") - @Operation(summary = "获得升级记录分页") - @PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')") + @Operation(summary = "获得 OTA 升级记录分页") + @PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')") public CommonResult> getOtaTaskRecordPage( @Valid IotOtaTaskRecordPageReqVO pageReqVO) { PageResult pageResult = otaTaskRecordService.getOtaTaskRecordPage(pageReqVO); @@ -54,8 +56,8 @@ public class IotOtaTaskRecordController { } @GetMapping("/get") - @Operation(summary = "获得升级记录") - @PreAuthorize("@ss.hasPermission('iot:ota-upgrade-record:query')") + @Operation(summary = "获得 OTA 升级记录") + @PreAuthorize("@ss.hasPermission('iot:ota-task-record:query')") @Parameter(name = "id", description = "升级记录编号", required = true, example = "1024") public CommonResult getOtaTaskRecord(@RequestParam("id") Long id) { IotOtaTaskRecordDO upgradeRecord = otaTaskRecordService.getOtaTaskRecord(id); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/IotOtaTaskCreateReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/IotOtaTaskCreateReqVO.java index 853e10c548..65bc07c1bf 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/IotOtaTaskCreateReqVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/IotOtaTaskCreateReqVO.java @@ -32,4 +32,6 @@ public class IotOtaTaskCreateReqVO { @Schema(description = "选中的设备编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3") private List deviceIds; + // TODO @li:如果 deviceScope 等于 2 时,deviceIds 校验非空; + } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/record/IotOtaTaskRecordPageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/record/IotOtaTaskRecordPageReqVO.java index f6d1cf18be..839a8b06d8 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/record/IotOtaTaskRecordPageReqVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/record/IotOtaTaskRecordPageReqVO.java @@ -2,19 +2,16 @@ package cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.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; @Schema(description = "管理后台 - IoT OTA 升级记录分页 Request VO") @Data public class IotOtaTaskRecordPageReqVO extends PageParam { - // TODO @芋艿:分页条件字段梳理; - @Schema(description = "升级任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - @NotNull(message = "升级任务编号不能为空") + @Schema(description = "升级任务编号", example = "1024") private Long taskId; - @Schema(description = "设备标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "摄像头A1-1") + @Schema(description = "设备标识", example = "摄像头A1-1") private String deviceName; } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/record/IotOtaTaskRecordRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/record/IotOtaTaskRecordRespVO.java index ff28c68e7a..4de8204f0b 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/record/IotOtaTaskRecordRespVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/task/record/IotOtaTaskRecordRespVO.java @@ -3,8 +3,6 @@ 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 { @@ -23,12 +21,6 @@ public class IotOtaTaskRecordRespVO { @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Long taskId; - @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "iot") - private String productKey; - - @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "iot") - private String deviceName; - @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private String deviceId; @@ -47,10 +39,4 @@ public class IotOtaTaskRecordRespVO { @Schema(description = "升级进度描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") private String description; - @Schema(description = "升级开始时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime startTime; - - @Schema(description = "升级结束时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime endTime; - } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDO.java index 987c6b55ee..3ceb30b18c 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDO.java @@ -117,7 +117,7 @@ public class IotDeviceDO extends TenantBaseDO { * * 关联 {@link IotOtaFirmwareDO#getId()} */ - private String firmwareId; + private Long firmwareId; /** * 设备密钥,用于设备认证 diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/ota/IotOtaTaskDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/ota/IotOtaTaskDO.java index d2452950af..4c9124b89f 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/ota/IotOtaTaskDO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/ota/IotOtaTaskDO.java @@ -61,7 +61,7 @@ public class IotOtaTaskDO extends BaseDO { /** * 设备总数数量 */ - private Long deviceTotalCount; + private Integer deviceTotalCount; /** * 设备成功数量 */ diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/ota/IotOtaTaskRecordDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/ota/IotOtaTaskRecordDO.java index 8cd0173396..28b4ca6734 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/ota/IotOtaTaskRecordDO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/ota/IotOtaTaskRecordDO.java @@ -7,9 +7,10 @@ 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 @@ -70,13 +71,5 @@ public class IotOtaTaskRecordDO extends BaseDO { * 如果想看历史记录,可以查看 {@link IotDeviceMessageDO} 设备日志 */ private String description; - /** - * 升级开始时间 - */ - private LocalDateTime startTime; - /** - * 升级结束时间 - */ - private LocalDateTime endTime; } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaFirmwareMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaFirmwareMapper.java index 86288674c1..fea6272d40 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaFirmwareMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaFirmwareMapper.java @@ -7,20 +7,11 @@ 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; - @Mapper public interface IotOtaFirmwareMapper extends BaseMapperX { - /** - * 根据产品ID和固件版本号查询固件信息列表。 - * - * @param productId 产品ID,用于筛选固件信息。 - * @param version 固件版本号,用于筛选固件信息。 - * @return 返回符合条件的固件信息列表。 - */ - default List selectByProductIdAndVersion(Long productId, String version) { - return selectList(IotOtaFirmwareDO::getProductId, productId, + default IotOtaFirmwareDO selectByProductIdAndVersion(Long productId, String version) { + return selectOne(IotOtaFirmwareDO::getProductId, productId, IotOtaFirmwareDO::getVersion, version); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaTaskMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaTaskMapper.java index f89fdf79e2..a792dd3cc3 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaTaskMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaTaskMapper.java @@ -7,20 +7,12 @@ import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.IotOtaTaskPageRe import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskDO; import org.apache.ibatis.annotations.Mapper; -import java.util.List; - -/** - * OTA 升级任务 Mapper - * - * @author Shelly - */ @Mapper public interface IotOtaTaskMapper extends BaseMapperX { - default List selectByFirmwareIdAndName(Long firmwareId, String name) { - return selectList(new LambdaQueryWrapperX() - .eqIfPresent(IotOtaTaskDO::getFirmwareId, firmwareId) - .eqIfPresent(IotOtaTaskDO::getName, name)); + default IotOtaTaskDO selectByFirmwareIdAndName(Long firmwareId, String name) { + return selectOne(IotOtaTaskDO::getFirmwareId, firmwareId, + IotOtaTaskDO::getName, name); } default PageResult selectUpgradeTaskPage(IotOtaTaskPageReqVO pageReqVO) { diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaTaskRecordMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaTaskRecordMapper.java new file mode 100644 index 0000000000..d6d147107f --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaTaskRecordMapper.java @@ -0,0 +1,41 @@ +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 { + + default List selectListByFirmwareIdAndTaskId(Long firmwareId, Long taskId) { + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(IotOtaTaskRecordDO::getFirmwareId, firmwareId) + .eqIfPresent(IotOtaTaskRecordDO::getTaskId, taskId) + .select(IotOtaTaskRecordDO::getDeviceId, IotOtaTaskRecordDO::getStatus)); + } + + default PageResult selectPage(IotOtaTaskRecordPageReqVO pageReqVO) { + return selectPage(pageReqVO, new LambdaQueryWrapperX() + .eqIfPresent(IotOtaTaskRecordDO::getTaskId, pageReqVO.getTaskId())); + } + + default void updateByTaskIdAndStatus(Long taskId, Integer fromStatus, IotOtaTaskRecordDO updateRecord) { + update(updateRecord, new LambdaUpdateWrapper() + .eq(IotOtaTaskRecordDO::getTaskId, taskId) + .eq(IotOtaTaskRecordDO::getStatus, fromStatus)); + } + + default List selectListByDeviceIdAndStatus(Set deviceIds, Set statuses) { + return selectList(new LambdaQueryWrapperX() + .inIfPresent(IotOtaTaskRecordDO::getDeviceId, deviceIds) + .inIfPresent(IotOtaTaskRecordDO::getStatus, statuses)); + } + +} diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaUpgradeRecordMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaUpgradeRecordMapper.java deleted file mode 100644 index 53620780bf..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/ota/IotOtaUpgradeRecordMapper.java +++ /dev/null @@ -1,111 +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.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 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 { - - // TODO @li:selectByFirmwareIdAndTaskIdAndDeviceId;让方法自解释 - /** - * 根据条件查询单个OTA升级记录 - * - * @param firmwareId 固件ID,可选参数,用于筛选固件ID匹配的记录 - * @param taskId 任务ID,可选参数,用于筛选任务ID匹配的记录 - * @param deviceId 设备ID,可选参数,用于筛选设备ID匹配的记录 - * @return 返回符合条件的单个OTA升级记录,如果不存在则返回null - */ - default IotOtaTaskRecordDO selectByConditions(Long firmwareId, Long taskId, String deviceId) { - // 使用LambdaQueryWrapperX构建查询条件,根据传入的参数动态添加查询条件 - return selectOne(new LambdaQueryWrapperX() - .eqIfPresent(IotOtaTaskRecordDO::getFirmwareId, firmwareId) - .eqIfPresent(IotOtaTaskRecordDO::getTaskId, taskId) - .eqIfPresent(IotOtaTaskRecordDO::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> 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> selectOtaUpgradeRecordStatistics(Long firmwareId); - - // TODO @li:这里的注释,可以去掉哈 - /** - * 根据分页查询条件获取 OTA升级记录的分页结果 - * - * @param pageReqVO 分页查询请求参数,包含设备名称、任务ID等查询条件 - * @return 返回分页查询结果,包含符合条件的 OTA升级记录列表 - */ - // TODO @li:selectPage 就 ok 拉。 - default PageResult selectUpgradeRecordPage(IotOtaTaskRecordPageReqVO pageReqVO) { - // TODO @li:这里的注释,可以去掉哈;然后下面的“如果”。。。也没必要注释 - // 使用LambdaQueryWrapperX构建查询条件,并根据请求参数动态添加查询条件 - return selectPage(pageReqVO, new LambdaQueryWrapperX() -// .likeIfPresent(IotOtaTaskRecordDO::getDeviceName, pageReqVO.getDeviceName()) // 如果设备名称存在,则添加模糊查询条件 - .eqIfPresent(IotOtaTaskRecordDO::getTaskId, pageReqVO.getTaskId())); // 如果任务ID存在,则添加等值查询条件 - } - - // TODO @li:这里的注释,可以去掉哈 - /** - * 根据任务ID和状态更新升级记录的状态 - *

- * 该函数用于将符合指定任务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() - .set(IotOtaTaskRecordDO::getStatus, setStatus) - .eq(IotOtaTaskRecordDO::getTaskId, taskId) - .eq(IotOtaTaskRecordDO::getStatus, whereStatus) - ); - } - -} diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/DictTypeConstants.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/DictTypeConstants.java index b7750bd0b0..384bf734e6 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/DictTypeConstants.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/DictTypeConstants.java @@ -16,4 +16,7 @@ public class DictTypeConstants { public static final String ALERT_LEVEL = "iot_alert_level"; + public static final String OTA_TASK_DEVICE_SCOPE = "iot_ota_task_device_scope"; + public static final String OTA_TASK_STATUS = "iot_ota_task_status"; + } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java index 8e445bf540..63d4a253e4 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java @@ -41,20 +41,25 @@ public interface ErrorCodeConstants { ErrorCode DEVICE_GROUP_NOT_EXISTS = new ErrorCode(1_050_005_000, "设备分组不存在"); ErrorCode DEVICE_GROUP_DELETE_FAIL_DEVICE_EXISTS = new ErrorCode(1_050_005_001, "设备分组下存在设备,不允许删除"); - // ========== 固件相关 1-050-008-000 ========== + // ========== OTA 固件相关 1-050-008-000 ========== ErrorCode OTA_FIRMWARE_NOT_EXISTS = new ErrorCode(1_050_008_000, "固件信息不存在"); ErrorCode OTA_FIRMWARE_PRODUCT_VERSION_DUPLICATE = new ErrorCode(1_050_008_001, "产品版本号重复"); - ErrorCode OTA_UPGRADE_TASK_NOT_EXISTS = new ErrorCode(1_050_008_100, "升级任务不存在"); - ErrorCode OTA_UPGRADE_TASK_NAME_DUPLICATE = new ErrorCode(1_050_008_101, "升级任务名称重复"); - ErrorCode OTA_UPGRADE_TASK_DEVICE_IDS_EMPTY = new ErrorCode(1_050_008_102, "设备编号列表不能为空"); - ErrorCode OTA_UPGRADE_TASK_DEVICE_LIST_EMPTY = new ErrorCode(1_050_008_103, "设备列表不能为空"); - ErrorCode OTA_UPGRADE_TASK_CANNOT_CANCEL = new ErrorCode(1_050_008_104, "升级任务不能取消"); + // ========== OTA 升级任务相关 1-050-008-100 ========== - ErrorCode OTA_UPGRADE_RECORD_NOT_EXISTS = new ErrorCode(1_050_008_200, "升级记录不存在"); - ErrorCode OTA_UPGRADE_RECORD_DUPLICATE = new ErrorCode(1_050_008_201, "升级记录重复"); - ErrorCode OTA_UPGRADE_RECORD_CANNOT_RETRY = new ErrorCode(1_050_008_202, "升级记录不能重试"); + ErrorCode OTA_TASK_NOT_EXISTS = new ErrorCode(1_050_008_100, "升级任务不存在"); + ErrorCode OTA_TASK_CREATE_FAIL_NAME_DUPLICATE = new ErrorCode(1_050_008_101, "创建 OTA 任务失败,原因:任务名称重复"); + ErrorCode OTA_TASK_CREATE_FAIL_DEVICE_FIRMWARE_EXISTS = new ErrorCode(1_050_008_102, + "创建 OTA 任务失败,原因:设备({})已经是该固件版本"); + ErrorCode OTA_TASK_CREATE_FAIL_DEVICE_OTA_IN_PROCESS = new ErrorCode(1_050_008_102, + "创建 OTA 任务失败,原因:设备({})已经在升级中..."); + ErrorCode OTA_TASK_CREATE_FAIL_DEVICE_EMPTY = new ErrorCode(1_050_008_103, "创建 OTA 任务失败,原因:没有可升级的设备"); + ErrorCode OTA_TASK_CANCEL_FAIL_STATUS_END = new ErrorCode(1_050_008_104, "取消 OTA 任务失败,原因:任务状态不是进行中"); + + // ========== OTA 升级任务相关 1-050-008-100 ========== + + ErrorCode OTA_TASK_RECORD_NOT_EXISTS = new ErrorCode(1_050_008_200, "升级记录不存在"); // ========== IoT 数据流转规则 1-050-010-000 ========== ErrorCode DATA_RULE_NOT_EXISTS = new ErrorCode(1_050_010_000, "数据流转规则不存在"); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaTaskRecordStatusEnum.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaTaskRecordStatusEnum.java index c95b033d70..8c423949b7 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaTaskRecordStatusEnum.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaTaskRecordStatusEnum.java @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.iot.enums.ota; import cn.iocoder.yudao.framework.common.core.ArrayValuable; +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; import lombok.Getter; import lombok.RequiredArgsConstructor; import java.util.Arrays; +import java.util.List; +import java.util.Set; /** * IoT OTA 升级任务记录的状态枚举 @@ -26,6 +29,17 @@ public enum IotOtaTaskRecordStatusEnum implements ArrayValuable { public static final Integer[] ARRAYS = Arrays.stream(values()) .map(IotOtaTaskRecordStatusEnum::getStatus).toArray(Integer[]::new); + public static final Set IN_PROCESS_STATUSES = SetUtils.asSet( + PENDING.getStatus(), + PUSHED.getStatus(), + UPGRADING.getStatus(), + SUCCESS.getStatus()); + + public static final List PRIORITY_STATUSES = Arrays.asList( + SUCCESS.getStatus(), + PENDING.getStatus(), PUSHED.getStatus(), UPGRADING.getStatus(), + FAILURE.getStatus(), CANCELED.getStatus()); + /** * 状态 */ diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java index 7bfb9800d0..328d7bd5d6 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java @@ -12,7 +12,6 @@ import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Set; /** * IoT 设备 Service 接口 @@ -155,21 +154,13 @@ public interface IotDeviceService { List getDeviceListByState(Integer state); /** - * 根据产品ID获取设备列表 + * 根据产品编号,获取设备列表 * - * @param productId 产品ID,用于查询特定产品的设备列表 - * @return 返回与指定产品ID关联的设备列表,列表中的每个元素为IotDeviceDO对象 + * @param productId 产品编号 + * @return 设备列表 */ List getDeviceListByProductId(Long productId); - /** - * 根据设备ID列表获取设备信息列表 - * - * @param deviceIdList 设备ID列表,包含需要查询的设备ID - * @return 返回与设备ID列表对应的设备信息列表,列表中的每个元素为IotDeviceDO对象 - */ - List getDeviceListByIdList(List deviceIdList); - /** * 基于产品编号,获得设备数量 * @@ -248,6 +239,6 @@ public interface IotDeviceService { * * @param ids 设备编号数组 */ - void validateDevicesExist(Set ids); + List validateDeviceListExists(Collection ids); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java index 30f7b26878..4cdf859d06 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java @@ -278,11 +278,6 @@ public class IotDeviceServiceImpl implements IotDeviceService { return deviceMapper.selectListByProductId(productId); } - @Override - public List getDeviceListByIdList(List deviceIdList) { - return deviceMapper.selectByIds(deviceIdList); - } - @Override public void updateDeviceState(IotDeviceDO device, Integer state) { // 1. 更新状态和时间 @@ -474,14 +469,15 @@ public class IotDeviceServiceImpl implements IotDeviceService { } @Override - public void validateDevicesExist(Set ids) { + public List validateDeviceListExists(Collection ids) { if (CollUtil.isEmpty(ids)) { - return; + return Collections.emptyList(); } - List deviceIds = deviceMapper.selectByIds(ids); - if (deviceIds.size() != ids.size()) { + List devices = deviceMapper.selectByIds(ids); + if (devices.size() != ids.size()) { throw exception(DEVICE_NOT_EXISTS); } + return devices; } private IotDeviceServiceImpl getSelf() { diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaFirmwareService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaFirmwareService.java index 9b9ffaf796..14fc38cde7 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaFirmwareService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaFirmwareService.java @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO; import jakarta.validation.Valid; /** - * OTA 固件管理 Service + * OTA 固件管理 Service 接口 * * @author Shelly Chan */ diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaFirmwareServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaFirmwareServiceImpl.java index f0d22ea22f..a5da1dba3f 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaFirmwareServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaFirmwareServiceImpl.java @@ -23,9 +23,14 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.OTA_FIRMWARE_NOT_EXISTS; import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.OTA_FIRMWARE_PRODUCT_VERSION_DUPLICATE; -@Slf4j +/** + * OTA 固件管理 Service 实现类 + * + * @author Shelly Chan + */ @Service @Validated +@Slf4j public class IotOtaFirmwareServiceImpl implements IotOtaFirmwareService { @Resource @@ -37,7 +42,9 @@ public class IotOtaFirmwareServiceImpl implements IotOtaFirmwareService { @Override public Long createOtaFirmware(IotOtaFirmwareCreateReqVO saveReqVO) { // 1.1 校验固件产品 + 版本号不能重复 - validateProductAndVersionDuplicate(saveReqVO.getProductId(), saveReqVO.getVersion()); + if (otaFirmwareMapper.selectByProductIdAndVersion(saveReqVO.getProductId(), saveReqVO.getVersion()) != null) { + throw exception(OTA_FIRMWARE_PRODUCT_VERSION_DUPLICATE); + } // 1.2 校验产品存在 productService.validateProductExists(saveReqVO.getProductId()); @@ -83,25 +90,12 @@ public class IotOtaFirmwareServiceImpl implements IotOtaFirmwareService { return firmware; } - /** - * 验证产品和版本号是否重复 - */ - private void validateProductAndVersionDuplicate(Long productId, String version) { - // 只查询1条记录检查是否存在 - IotOtaFirmwareDO firmware = otaFirmwareMapper.selectOne(IotOtaFirmwareDO::getProductId, productId, - IotOtaFirmwareDO::getVersion, version); - if (firmware != null) { - throw exception(OTA_FIRMWARE_PRODUCT_VERSION_DUPLICATE); - } - } - /** * 计算文件签名 - * + * * @param firmware 固件对象 - * @throws Exception 下载或计算签名失败时抛出异常 */ - private void calculateFileDigest(IotOtaFirmwareDO firmware) throws Exception { + private void calculateFileDigest(IotOtaFirmwareDO firmware) { String fileUrl = firmware.getFileUrl(); // 下载文件并计算签名 byte[] fileBytes = HttpUtil.downloadBytes(fileUrl); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskRecordService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskRecordService.java index 4a8367017a..eb5a04ac2a 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskRecordService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskRecordService.java @@ -2,67 +2,67 @@ package cn.iocoder.yudao.module.iot.service.ota; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordPageReqVO; +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskRecordDO; import jakarta.validation.Valid; import java.util.List; import java.util.Map; +import java.util.Set; -// TODO @li:注释写的有点冗余,可以看看别的模块哈。= = AI 生成的注释,有的时候太啰嗦了,需要处理下的哈 /** - * IotOtaUpgradeRecordService 接口定义了与物联网设备OTA升级记录相关的操作。 - * 该接口提供了创建、更新、查询、统计和重试升级记录的功能。 + * IoT OTA 升级记录 Service 接口 */ public interface IotOtaTaskRecordService { /** * 批量创建 OTA 升级记录 - * 该函数用于为指定的设备列表、固件ID和升级任务ID创建OTA升级记录。 * - * @param deviceIds 设备ID列表,表示需要升级的设备集合。 - * @param firmwareId 固件ID,表示要升级到的固件版本。 - * @param upgradeTaskId 升级任务ID,表示此次升级任务的唯一标识。 + * @param devices 设备列表 + * @param firmwareId 固件编号 + * @param taskId 任务编号 */ - void createOtaTaskRecordBatch(List deviceIds, Long firmwareId, Long upgradeTaskId); + void createOtaTaskRecordList(List devices, Long firmwareId, Long taskId); /** - * 获取 OTA 升级记录的数量统计 + * 获取 OTA 升级记录的状态统计 * - * @return 返回一个 Map,其中键为状态码,值为对应状态的升级记录数量 + * @param firmwareId 固件编号 + * @param taskId 任务编号 + * @return 状态统计 Map,key 为状态码,value 为对应状态的升级记录数量 */ - Map getOtaTaskRecordCount(@Valid IotOtaTaskRecordPageReqVO pageReqVO); + Map getOtaTaskRecordStatusCountMap(Long firmwareId, Long taskId); /** - * 获取 OTA 升级记录的统计信息 + * 获取 OTA 升级记录 * - * @return 返回一个 Map,其中键为状态码,值为对应状态的升级记录统计信息 - */ - Map getOtaTaskRecordStatistics(Long firmwareId); - - /** - * 获取指定 ID 的 OTA 升级记录的详细信息 - * - * @param id 需要查询的升级记录的 ID - * @return 返回包含升级记录详细信息的响应对象 + * @param id 编号 + * @return OTA 升级记录 */ IotOtaTaskRecordDO getOtaTaskRecord(Long id); /** - * 分页查询 OTA 升级记录 + * 获取 OTA 升级记录分页 * - * @param pageReqVO 包含分页查询条件的请求对象,必须经过验证。 - * @return 返回包含分页查询结果的响应对象。 + * @param pageReqVO 分页查询 + * @return OTA 升级记录分页 */ PageResult getOtaTaskRecordPage(@Valid IotOtaTaskRecordPageReqVO pageReqVO); /** - * 根据任务 ID 取消升级记录 - *

- * 该函数用于根据给定的任务ID,取消与该任务相关的升级记录。通常用于在任务执行失败或用户手动取消时, - * 清理或标记相关的升级记录为取消状态。 + * 根据 OTA 任务编号,取消未结束的升级记录 * - * @param taskId 要取消升级记录的任务ID。该ID唯一标识一个任务,通常由任务管理系统生成。 + * @param taskId 升级任务编号 */ - void cancelUpgradeRecordByTaskId(Long taskId); + void cancelTaskRecordListByTaskId(Long taskId); + + /** + * 根据设备编号和记录状态,获取 OTA 升级记录列表 + * + * @param deviceIds 设备编号集合 + * @param statuses 记录状态集合 + * @return OTA 升级记录列表 + */ + List getOtaTaskRecordListByDeviceIdAndStatus(Set deviceIds, Set statuses); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskRecordServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskRecordServiceImpl.java index 4f9cb7e1d8..ab156a8787 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskRecordServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskRecordServiceImpl.java @@ -2,177 +2,100 @@ package cn.iocoder.yudao.module.iot.service.ota; import cn.hutool.core.convert.Convert; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.record.IotOtaTaskRecordPageReqVO; 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.dal.dataobject.ota.IotOtaTaskDO; -import cn.iocoder.yudao.module.iot.dal.mysql.ota.IotOtaUpgradeRecordMapper; +import cn.iocoder.yudao.module.iot.dal.mysql.ota.IotOtaTaskRecordMapper; import cn.iocoder.yudao.module.iot.enums.ota.IotOtaTaskRecordStatusEnum; -import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; +import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.OTA_TASK_RECORD_NOT_EXISTS; -// TODO @li:@Service、@Validated、@Slf4j,先用关键注解;2)类注释,简单写 -@Slf4j +/** + * OTA 升级任务记录 Service 实现类 + */ @Service @Validated +@Slf4j public class IotOtaTaskRecordServiceImpl implements IotOtaTaskRecordService { @Resource - private IotOtaUpgradeRecordMapper iotOtaUpgradeRecordMapper; - - @Resource - private IotDeviceService deviceService; - @Resource - private IotOtaFirmwareService firmwareService; - @Resource - private IotOtaTaskService upgradeTaskService; + private IotOtaTaskRecordMapper otaTaskRecordMapper; @Override - public void createOtaTaskRecordBatch(List deviceIds, Long firmwareId, Long upgradeTaskId) { - // 1. 校验升级记录信息是否存在,并且已经取消的任务可以重新开始 - deviceIds.forEach(deviceId -> validateUpgradeRecordDuplicate(firmwareId, upgradeTaskId, String.valueOf(deviceId))); - - // 2. 初始化OTA升级记录列表信息 - IotOtaTaskDO upgradeTask = upgradeTaskService.getOtaTask(upgradeTaskId); - IotOtaFirmwareDO firmware = firmwareService.getOtaFirmware(firmwareId); - List deviceList = deviceService.getDeviceListByIdList(deviceIds); - List upgradeRecordList = deviceList.stream().map(device -> { - IotOtaTaskRecordDO upgradeRecord = new IotOtaTaskRecordDO(); - upgradeRecord.setFirmwareId(firmware.getId()); - upgradeRecord.setTaskId(upgradeTask.getId()); - upgradeRecord.setDeviceId(device.getId()); - upgradeRecord.setFromFirmwareId(Convert.toLong(device.getFirmwareId())); - upgradeRecord.setStatus(IotOtaTaskRecordStatusEnum.PENDING.getStatus()); - upgradeRecord.setProgress(0); - return upgradeRecord; - }).toList(); - // 3. 保存数据 - iotOtaUpgradeRecordMapper.insertBatch(upgradeRecordList); - // TODO @芋艿:在这里需要处理推送升级任务的逻辑 - } - - // TODO @li:1)方法注释,简单写;2)父类写了注释,子类就不用写了。。。 - /** - * 获取OTA升级记录的数量统计。 - * 该方法根据传入的查询条件,统计不同状态的OTA升级记录数量,并返回一个包含各状态数量的映射。 - * - * @param pageReqVO 包含查询条件的请求对象,主要包括任务ID和设备名称等信息。 - * @return 返回一个Map,其中键为状态常量,值为对应状态的记录数量。 - */ - @Override - @Transactional - public Map getOtaTaskRecordCount(IotOtaTaskRecordPageReqVO pageReqVO) { - // 分别查询不同状态的OTA升级记录数量 - List> upgradeRecordCountList = iotOtaUpgradeRecordMapper.selectOtaUpgradeRecordCount( - pageReqVO.getTaskId(), pageReqVO.getDeviceName()); - Map upgradeRecordCountMap = ObjectUtils.defaultIfNull(upgradeRecordCountList.get(0)); - Objects.requireNonNull(upgradeRecordCountMap); - return upgradeRecordCountMap.entrySet().stream().collect(Collectors.toMap( - entry -> Convert.toInt(entry.getKey()), - entry -> Convert.toLong(entry.getValue()))); + public void createOtaTaskRecordList(List devices, Long firmwareId, Long taskId) { + List records = convertList(devices, device -> + IotOtaTaskRecordDO.builder().firmwareId(firmwareId).taskId(taskId) + .deviceId(device.getId()).fromFirmwareId(Convert.toLong(device.getFirmwareId())) + .status(IotOtaTaskRecordStatusEnum.PENDING.getStatus()).progress(0).build()); + otaTaskRecordMapper.insertBatch(records); } @Override - @Transactional - public Map getOtaTaskRecordStatistics(Long firmwareId) { - // 查询并统计不同状态的OTA升级记录数量 - List> upgradeRecordStatisticsList = iotOtaUpgradeRecordMapper.selectOtaUpgradeRecordStatistics(firmwareId); - Map upgradeRecordStatisticsMap = ObjectUtils.defaultIfNull(upgradeRecordStatisticsList.get(0)); - Objects.requireNonNull(upgradeRecordStatisticsMap); - return upgradeRecordStatisticsMap.entrySet().stream().collect(Collectors.toMap( - entry -> Convert.toInt(entry.getKey()), - entry -> Convert.toLong(entry.getValue()))); + public Map getOtaTaskRecordStatusCountMap(Long firmwareId, Long taskId) { + // 按照 status 枚举,初始化 countMap 为 0 + Map countMap = convertMap(Arrays.asList(IotOtaTaskRecordStatusEnum.values()), + IotOtaTaskRecordStatusEnum::getStatus, iotOtaTaskRecordStatusEnum -> 0L); + + // 查询记录,只返回 id、status 字段 + List records = otaTaskRecordMapper.selectListByFirmwareIdAndTaskId(firmwareId, taskId); + Map> deviceStatusesMap = convertMultiMap(records, + IotOtaTaskRecordDO::getDeviceId, IotOtaTaskRecordDO::getStatus); + // 找到第一个匹配的优先级状态,避免重复计算 + deviceStatusesMap.forEach((deviceId, statuses) -> { + for (Integer priorityStatus : IotOtaTaskRecordStatusEnum.PRIORITY_STATUSES) { + if (statuses.contains(priorityStatus)) { + countMap.put(priorityStatus, countMap.get(priorityStatus) + 1); + return; + } + } + }); + return countMap; } @Override public IotOtaTaskRecordDO getOtaTaskRecord(Long id) { - return iotOtaUpgradeRecordMapper.selectById(id); + return otaTaskRecordMapper.selectById(id); } @Override public PageResult getOtaTaskRecordPage(IotOtaTaskRecordPageReqVO pageReqVO) { - return iotOtaUpgradeRecordMapper.selectUpgradeRecordPage(pageReqVO); + return otaTaskRecordMapper.selectPage(pageReqVO); } @Override - public void cancelUpgradeRecordByTaskId(Long taskId) { - // 暂定只有待推送的升级记录可以取消 TODO @芋艿:可以看看阿里云,哪些可以取消 - iotOtaUpgradeRecordMapper.updateUpgradeRecordStatusByTaskIdAndStatus( - IotOtaTaskRecordStatusEnum.CANCELED.getStatus(), taskId, - IotOtaTaskRecordStatusEnum.PENDING.getStatus()); + public void cancelTaskRecordListByTaskId(Long taskId) { + // 设置取消记录的描述 + IotOtaTaskRecordDO updateRecord = IotOtaTaskRecordDO.builder() + .status(IotOtaTaskRecordStatusEnum.CANCELED.getStatus()) + .description("管理员取消升级任务") + .build(); + + otaTaskRecordMapper.updateByTaskIdAndStatus( + taskId, IotOtaTaskRecordStatusEnum.PENDING.getStatus(), updateRecord); + } + + @Override + public List getOtaTaskRecordListByDeviceIdAndStatus(Set deviceIds, Set statuses) { + return otaTaskRecordMapper.selectListByDeviceIdAndStatus(deviceIds, statuses); } - /** - * 验证指定的升级记录是否存在。 - *

- * 该函数通过给定的ID查询升级记录,如果查询结果为空,则抛出异常,表示升级记录不存在。 - * - * @param id 升级记录的唯一标识符,类型为Long。 - * @throws cn.iocoder.yudao.framework.common.exception.ServiceException,则抛出异常,异常类型为OTA_UPGRADE_RECORD_NOT_EXISTS。 - */ private IotOtaTaskRecordDO validateUpgradeRecordExists(Long id) { - // 根据ID查询升级记录 - IotOtaTaskRecordDO upgradeRecord = iotOtaUpgradeRecordMapper.selectById(id); - // 如果查询结果为空,抛出异常 + IotOtaTaskRecordDO upgradeRecord = otaTaskRecordMapper.selectById(id); if (upgradeRecord == null) { - throw exception(OTA_UPGRADE_RECORD_NOT_EXISTS); + throw exception(OTA_TASK_RECORD_NOT_EXISTS); } return upgradeRecord; } - // TODO @li:注释有点冗余 - /** - * 校验固件升级记录是否重复。 - *

- * 该函数用于检查给定的固件ID、任务ID和设备ID是否已经存在未取消的升级记录。 - * 如果存在未取消的记录,则抛出异常,提示升级记录重复。 - * - * @param firmwareId 固件ID,用于标识特定的固件版本 - * @param taskId 任务ID,用于标识特定的升级任务 - * @param deviceId 设备ID,用于标识特定的设备 - */ - private void validateUpgradeRecordDuplicate(Long firmwareId, Long taskId, String deviceId) { - IotOtaTaskRecordDO upgradeRecord = iotOtaUpgradeRecordMapper.selectByConditions(firmwareId, taskId, deviceId); - if (upgradeRecord == null) { - return; - } - if (!Objects.equals(upgradeRecord.getStatus(), IotOtaTaskRecordStatusEnum.CANCELED.getStatus())) { - throw exception(OTA_UPGRADE_RECORD_DUPLICATE); - } - } - - // TODO @li:注释有点冗余 - /** - * 验证升级记录是否可以重试。 - *

- * 该方法用于检查给定的升级记录是否处于允许重试的状态。如果升级记录的状态为 - * PENDING、PUSHED 或 UPGRADING,则抛出异常,表示不允许重试。 - * - * @param upgradeRecord 需要验证的升级记录对象,类型为 IotOtaUpgradeRecordDO - * @throws cn.iocoder.yudao.framework.common.exception.ServiceException,则抛出 OTA_UPGRADE_RECORD_CANNOT_RETRY 异常 - */ - // TODO @li:这种一次性的方法(不复用的),其实一步一定要抽成小方法; - private void validateUpgradeRecordCanRetry(IotOtaTaskRecordDO upgradeRecord) { - if (ObjectUtils.equalsAny(upgradeRecord.getStatus(), - IotOtaTaskRecordStatusEnum.PENDING.getStatus(), - IotOtaTaskRecordStatusEnum.PUSHED.getStatus(), - IotOtaTaskRecordStatusEnum.UPGRADING.getStatus())) { - throw exception(OTA_UPGRADE_RECORD_CANNOT_RETRY); - } - } - } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskService.java index f3b5374697..2e9153b7f8 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskService.java @@ -14,7 +14,7 @@ import jakarta.validation.Valid; public interface IotOtaTaskService { /** - * 创建 OTA升 级任务 + * 创建 OTA 升级任务 * * @param createReqVO 创建请求对象 * @return 升级任务编号 diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskServiceImpl.java index 13773a090b..309cefa942 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/ota/IotOtaTaskServiceImpl.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.iot.service.ota; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjUtil; 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.IotOtaTaskCreateReqVO; @@ -9,8 +9,10 @@ import cn.iocoder.yudao.module.iot.controller.admin.ota.vo.task.IotOtaTaskPageRe 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.IotOtaTaskDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaTaskRecordDO; import cn.iocoder.yudao.module.iot.dal.mysql.ota.IotOtaTaskMapper; import cn.iocoder.yudao.module.iot.enums.ota.IotOtaTaskDeviceScopeEnum; +import cn.iocoder.yudao.module.iot.enums.ota.IotOtaTaskRecordStatusEnum; import cn.iocoder.yudao.module.iot.enums.ota.IotOtaTaskStatusEnum; import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; import jakarta.annotation.Resource; @@ -24,6 +26,7 @@ import java.util.List; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; /** @@ -45,26 +48,29 @@ public class IotOtaTaskServiceImpl implements IotOtaTaskService { private IotOtaFirmwareService otaFirmwareService; @Resource @Lazy // 延迟,避免循环依赖报错 - private IotOtaTaskRecordService otaUpgradeRecordService; + private IotOtaTaskRecordService otaTaskRecordService; @Override @Transactional(rollbackFor = Exception.class) public Long createOtaTask(IotOtaTaskCreateReqVO createReqVO) { - // 1.1 校验同一固件的升级任务名称不重复 - validateFirmwareTaskDuplicate(createReqVO.getFirmwareId(), createReqVO.getName()); - // 1.2 校验固件信息是否存在 + // 1.1 校验固件信息是否存在 IotOtaFirmwareDO firmware = otaFirmwareService.validateFirmwareExists(createReqVO.getFirmwareId()); - // 1.3 补全设备范围信息,并且校验是否又设备可以升级,如果没有设备可以升级,则报错 - validateScopeAndDevice(createReqVO.getDeviceScope(), createReqVO.getDeviceIds(), firmware.getProductId()); + // 1.2 校验同一固件的升级任务名称不重复 + if (otaTaskMapper.selectByFirmwareIdAndName(firmware.getId(), createReqVO.getName()) != null) { + throw exception(OTA_TASK_CREATE_FAIL_NAME_DUPLICATE); + } + // 1.3 校验设备范围信息 + List devices = validateOtaTaskDeviceScope(createReqVO, firmware.getProductId()); - // 2. 保存 OTA 升级任务信息到数据库 - IotOtaTaskDO upgradeTask = initOtaUpgradeTask(createReqVO, firmware.getProductId()); - otaTaskMapper.insert(upgradeTask); + // 2. 保存升级任务,直接转换 + IotOtaTaskDO task = BeanUtils.toBean(createReqVO, IotOtaTaskDO.class) + .setStatus(IotOtaTaskStatusEnum.IN_PROGRESS.getStatus()) + .setDeviceTotalCount(devices.size()).setDeviceSuccessCount(0); + otaTaskMapper.insert(task); - // 3. 生成设备升级记录信息并存储,等待定时任务轮询 - // TODO @芋艿:在处理; -// otaUpgradeRecordService.createOtaUpgradeRecordBatch(upgradeTask.getDeviceIds(), firmware.getId(), upgradeTask.getId()); - return upgradeTask.getId(); + // 3. 生成设备升级记录 + otaTaskRecordService.createOtaTaskRecordList(devices, firmware.getId(), task.getId()); + return task.getId(); } @Override @@ -73,18 +79,17 @@ public class IotOtaTaskServiceImpl implements IotOtaTaskService { // 1.1 校验升级任务是否存在 IotOtaTaskDO upgradeTask = validateUpgradeTaskExists(id); // 1.2 校验升级任务是否可以取消 - // TODO @li:ObjUtil notequals - if (!Objects.equals(upgradeTask.getStatus(), IotOtaTaskStatusEnum.IN_PROGRESS.getStatus())) { - throw exception(OTA_UPGRADE_TASK_CANNOT_CANCEL); + if (ObjUtil.notEqual(upgradeTask.getStatus(), IotOtaTaskStatusEnum.IN_PROGRESS.getStatus())) { + throw exception(OTA_TASK_CANCEL_FAIL_STATUS_END); } - // 2. 更新 OTA 升级任务状态为已取消 + // 2. 更新升级任务状态为已取消 otaTaskMapper.updateById(IotOtaTaskDO.builder() .id(id).status(IotOtaTaskStatusEnum.CANCELED.getStatus()) .build()); - // 3. 更新 OTA 升级记录状态为已取消 - otaUpgradeRecordService.cancelUpgradeRecordByTaskId(id); + // 3. 更新升级记录状态为已取消 + otaTaskRecordService.cancelTaskRecordListByTaskId(id); } @Override @@ -97,50 +102,55 @@ public class IotOtaTaskServiceImpl implements IotOtaTaskService { return otaTaskMapper.selectUpgradeTaskPage(pageReqVO); } - /** - * 校验固件升级任务是否重复 - */ - private void validateFirmwareTaskDuplicate(Long firmwareId, String taskName) { - List upgradeTaskList = otaTaskMapper.selectByFirmwareIdAndName(firmwareId, taskName); - if (CollUtil.isNotEmpty(upgradeTaskList)) { - throw exception(OTA_UPGRADE_TASK_NAME_DUPLICATE); - } - } - - private void validateScopeAndDevice(Integer scope, List deviceIds, Long productId) { - if (Objects.equals(scope, IotOtaTaskDeviceScopeEnum.SELECT.getScope())) { - if (CollUtil.isEmpty(deviceIds)) { - throw exception(OTA_UPGRADE_TASK_DEVICE_IDS_EMPTY); + private List validateOtaTaskDeviceScope(IotOtaTaskCreateReqVO createReqVO, Long productId) { + // 情况一:选择设备 + if (Objects.equals(createReqVO.getDeviceScope(), IotOtaTaskDeviceScopeEnum.SELECT.getScope())) { + // 1.1 校验设备存在 + List devices = deviceService.validateDeviceListExists(createReqVO.getDeviceIds()); + for (IotDeviceDO device : devices) { + if (ObjUtil.notEqual(device.getProductId(), productId)) { + throw exception(DEVICE_NOT_EXISTS); + } } - return; + // 1.2 校验设备是否已经是该固件版本 + devices.forEach(device -> { + if (Objects.equals(device.getFirmwareId(), createReqVO.getFirmwareId())) { + throw exception(OTA_TASK_CREATE_FAIL_DEVICE_FIRMWARE_EXISTS, device.getDeviceName()); + } + }); + // 1.3 校验设备是否已经在升级中 + List records = otaTaskRecordService.getOtaTaskRecordListByDeviceIdAndStatus( + convertSet(devices, IotDeviceDO::getId), IotOtaTaskRecordStatusEnum.IN_PROCESS_STATUSES); + devices.forEach(device -> { + if (CollUtil.contains(records, item -> item.getDeviceId().equals(device.getId()))) { + throw exception(OTA_TASK_CREATE_FAIL_DEVICE_OTA_IN_PROCESS, device.getDeviceName()); + } + }); + return devices; } - - if (Objects.equals(scope, IotOtaTaskDeviceScopeEnum.ALL.getScope())) { - List deviceList = deviceService.getDeviceListByProductId(productId); - if (CollUtil.isEmpty(deviceList)) { - throw exception(OTA_UPGRADE_TASK_DEVICE_LIST_EMPTY); + // 情况二:全部设备 + if (Objects.equals(createReqVO.getDeviceScope(), IotOtaTaskDeviceScopeEnum.ALL.getScope())) { + List devices = deviceService.getDeviceListByProductId(productId); + // 2.1.1 移除已经是该固件版本的设备 + devices.removeIf(device -> Objects.equals(device.getFirmwareId(), createReqVO.getFirmwareId())); + // 2.1.2 移除已经在升级中的设备 + List records = otaTaskRecordService.getOtaTaskRecordListByDeviceIdAndStatus( + convertSet(devices, IotDeviceDO::getId), IotOtaTaskRecordStatusEnum.IN_PROCESS_STATUSES); + devices.removeIf(device -> CollUtil.contains(records, + item -> item.getDeviceId().equals(device.getId()))); + // 2.2 校验是否有可升级的设备 + if (CollUtil.isEmpty(devices)) { + throw exception(OTA_TASK_CREATE_FAIL_DEVICE_EMPTY); } + return devices; } + throw new IllegalArgumentException("不支持的设备范围:" + createReqVO.getDeviceScope()); } private IotOtaTaskDO validateUpgradeTaskExists(Long id) { IotOtaTaskDO upgradeTask = otaTaskMapper.selectById(id); if (Objects.isNull(upgradeTask)) { - throw exception(OTA_UPGRADE_TASK_NOT_EXISTS); - } - return upgradeTask; - } - - private IotOtaTaskDO initOtaUpgradeTask(IotOtaTaskCreateReqVO createReqVO, Long productId) { - IotOtaTaskDO upgradeTask = BeanUtils.toBean(createReqVO, IotOtaTaskDO.class); - upgradeTask.setDeviceTotalCount(Convert.toLong(CollUtil.size(createReqVO.getDeviceIds()))) - .setStatus(IotOtaTaskStatusEnum.IN_PROGRESS.getStatus()); - - if (Objects.equals(createReqVO.getDeviceScope(), IotOtaTaskDeviceScopeEnum.ALL.getScope())) { - List deviceList = deviceService.getDeviceListByProductId(productId); - upgradeTask.setDeviceTotalCount((long) deviceList.size()); -// upgradeTask.setDeviceIds( -// deviceList.stream().map(IotDeviceDO::getId).collect(Collectors.toList())); + throw exception(OTA_TASK_NOT_EXISTS); } return upgradeTask; } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataRuleServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataRuleServiceImpl.java index 3144a1362a..8eafcb681a 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataRuleServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataRuleServiceImpl.java @@ -121,7 +121,7 @@ public class IotDataRuleServiceImpl implements IotDataRuleService { convertSet(sourceConfigs, IotDataRuleDO.SourceConfig::getProductId)); // 2. 校验设备 - deviceService.validateDevicesExist(convertSet(sourceConfigs, IotDataRuleDO.SourceConfig::getDeviceId, + deviceService.validateDeviceListExists(convertSet(sourceConfigs, IotDataRuleDO.SourceConfig::getDeviceId, config -> ObjUtil.notEqual(config.getDeviceId(), IotDeviceDO.DEVICE_ID_ALL))); // 3. 校验物模型存在