Commit 643e28938458a740b5975f99992533c0c10d70e0
1 parent
6b9cca0b
【优化】IOT 设备管理
Showing
14 changed files
with
110 additions
and
120 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.java
| ... | ... | @@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| 9 | 9 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO; |
| 10 | 10 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceRespVO; |
| 11 | 11 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO; |
| 12 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO; | |
| 12 | 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 13 | 14 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 14 | 15 | import io.swagger.v3.oas.annotations.Operation; |
| ... | ... | @@ -45,12 +46,9 @@ public class IotDeviceController { |
| 45 | 46 | |
| 46 | 47 | @PutMapping("/update-status") |
| 47 | 48 | @Operation(summary = "更新设备状态") |
| 48 | - @Parameter(name = "id", description = "编号", required = true) | |
| 49 | - @Parameter(name = "status", description = "状态", required = true, example = "1") | |
| 50 | 49 | @PreAuthorize("@ss.hasPermission('iot:device:update')") |
| 51 | - public CommonResult<Boolean> updateDeviceStatus(@RequestParam("id") Long id, | |
| 52 | - @RequestParam("status") Integer status) { | |
| 53 | - deviceService.updateDeviceStatus(id, status); | |
| 50 | + public CommonResult<Boolean> updateDeviceStatus(@Valid @RequestBody IotDeviceStatusUpdateReqVO updateReqVO) { | |
| 51 | + deviceService.updateDeviceStatus(updateReqVO); | |
| 54 | 52 | return success(true); |
| 55 | 53 | } |
| 56 | 54 | |
| ... | ... | @@ -88,17 +86,4 @@ public class IotDeviceController { |
| 88 | 86 | return success(BeanUtils.toBean(pageResult, IotDeviceRespVO.class)); |
| 89 | 87 | } |
| 90 | 88 | |
| 91 | - @GetMapping("/export-excel") | |
| 92 | - @Operation(summary = "导出设备 Excel") | |
| 93 | - @PreAuthorize("@ss.hasPermission('iot:device:export')") | |
| 94 | - @ApiAccessLog(operateType = EXPORT) | |
| 95 | - public void exportDeviceExcel(@Valid IotDevicePageReqVO pageReqVO, | |
| 96 | - HttpServletResponse response) throws IOException { | |
| 97 | - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); | |
| 98 | - List<IotDeviceDO> list = deviceService.getDevicePage(pageReqVO).getList(); | |
| 99 | - // 导出 Excel | |
| 100 | - ExcelUtils.write(response, "IoT 设备.xls", "数据", IotDeviceRespVO.class, | |
| 101 | - BeanUtils.toBean(list, IotDeviceRespVO.class)); | |
| 102 | - } | |
| 103 | - | |
| 104 | 89 | } |
| 105 | 90 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDevicePageReqVO.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 5 | 5 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; |
| 6 | +import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; | |
| 6 | 7 | import io.swagger.v3.oas.annotations.media.Schema; |
| 7 | 8 | import lombok.Data; |
| 8 | 9 | import lombok.EqualsAndHashCode; |
| ... | ... | @@ -28,6 +29,9 @@ public class IotDevicePageReqVO extends PageParam { |
| 28 | 29 | @Schema(description = "设备名称", example = "王五") |
| 29 | 30 | private String deviceName; |
| 30 | 31 | |
| 32 | + @Schema(description = "备注名称", example = "张三") | |
| 33 | + private String nickname; | |
| 34 | + | |
| 31 | 35 | @Schema(description = "产品编号", example = "26202") |
| 32 | 36 | private Long productId; |
| 33 | 37 | |
| ... | ... | @@ -35,12 +39,9 @@ public class IotDevicePageReqVO extends PageParam { |
| 35 | 39 | private String productKey; |
| 36 | 40 | |
| 37 | 41 | @Schema(description = "设备类型", example = "1") |
| 38 | - // TODO @haohao:需要有个设备类型的枚举 | |
| 42 | + @InEnum(IotProductDeviceTypeEnum.class) | |
| 39 | 43 | private Integer deviceType; |
| 40 | 44 | |
| 41 | - @Schema(description = "备注名称", example = "张三") | |
| 42 | - private String nickname; | |
| 43 | - | |
| 44 | 45 | @Schema(description = "网关设备 ID", example = "16380") |
| 45 | 46 | private Long gatewayId; |
| 46 | 47 | |
| ... | ... | @@ -64,12 +65,6 @@ public class IotDevicePageReqVO extends PageParam { |
| 64 | 65 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 65 | 66 | private LocalDateTime[] activeTime; |
| 66 | 67 | |
| 67 | - @Schema(description = "设备的 IP 地址") | |
| 68 | - private String ip; | |
| 69 | - | |
| 70 | - @Schema(description = "设备的固件版本") | |
| 71 | - private String firmwareVersion; | |
| 72 | - | |
| 73 | 68 | @Schema(description = "设备密钥,用于设备认证,需安全存储") |
| 74 | 69 | private String deviceSecret; |
| 75 | 70 | |
| ... | ... | @@ -85,21 +80,6 @@ public class IotDevicePageReqVO extends PageParam { |
| 85 | 80 | @Schema(description = "认证类型(如一机一密、动态注册)", example = "2") |
| 86 | 81 | private String authType; |
| 87 | 82 | |
| 88 | - @Schema(description = "设备位置的纬度,范围 -90.000000 ~ 90.000000") | |
| 89 | - private BigDecimal latitude; | |
| 90 | - | |
| 91 | - @Schema(description = "设备位置的经度,范围 -180.000000 ~ 180.000000") | |
| 92 | - private BigDecimal longitude; | |
| 93 | - | |
| 94 | - @Schema(description = "地区编码,符合国家地区编码标准,关联地区表", example = "16995") | |
| 95 | - private Integer areaId; | |
| 96 | - | |
| 97 | - @Schema(description = "设备详细地址") | |
| 98 | - private String address; | |
| 99 | - | |
| 100 | - @Schema(description = "设备序列号") | |
| 101 | - private String serialNumber; | |
| 102 | - | |
| 103 | 83 | @Schema(description = "创建时间") |
| 104 | 84 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 105 | 85 | private LocalDateTime[] createTime; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDeviceRespVO.java
| ... | ... | @@ -25,7 +25,7 @@ public class IotDeviceRespVO { |
| 25 | 25 | private String deviceName; |
| 26 | 26 | |
| 27 | 27 | @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202") |
| 28 | - @ExcelProperty("产品 ID") | |
| 28 | + @ExcelProperty("产品编号") | |
| 29 | 29 | private Long productId; |
| 30 | 30 | |
| 31 | 31 | @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) |
| ... | ... | @@ -41,7 +41,6 @@ public class IotDeviceRespVO { |
| 41 | 41 | private String nickname; |
| 42 | 42 | |
| 43 | 43 | @Schema(description = "网关设备 ID", example = "16380") |
| 44 | - @ExcelProperty("网关设备 ID") | |
| 45 | 44 | private Long gatewayId; |
| 46 | 45 | |
| 47 | 46 | @Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| ... | ... | @@ -64,14 +63,6 @@ public class IotDeviceRespVO { |
| 64 | 63 | @ExcelProperty("设备激活时间") |
| 65 | 64 | private LocalDateTime activeTime; |
| 66 | 65 | |
| 67 | - @Schema(description = "设备的 IP 地址") | |
| 68 | - @ExcelProperty("设备的 IP 地址") | |
| 69 | - private String ip; | |
| 70 | - | |
| 71 | - @Schema(description = "设备的固件版本") | |
| 72 | - @ExcelProperty("设备的固件版本") | |
| 73 | - private String firmwareVersion; | |
| 74 | - | |
| 75 | 66 | @Schema(description = "设备密钥,用于设备认证") |
| 76 | 67 | @ExcelProperty("设备密钥") |
| 77 | 68 | private String deviceSecret; |
| ... | ... | @@ -92,27 +83,6 @@ public class IotDeviceRespVO { |
| 92 | 83 | @ExcelProperty("认证类型(如一机一密、动态注册)") |
| 93 | 84 | private String authType; |
| 94 | 85 | |
| 95 | - // TODO @haohao:经纬度:可能 double 就够啦 | |
| 96 | - @Schema(description = "设备位置的纬度,范围") | |
| 97 | - @ExcelProperty("设备位置的纬度") | |
| 98 | - private BigDecimal latitude; | |
| 99 | - | |
| 100 | - @Schema(description = "设备位置的经度") | |
| 101 | - @ExcelProperty("设备位置的经度") | |
| 102 | - private BigDecimal longitude; | |
| 103 | - | |
| 104 | - @Schema(description = "地区编码", example = "16995") | |
| 105 | - @ExcelProperty("地区编码") | |
| 106 | - private Integer areaId; | |
| 107 | - | |
| 108 | - @Schema(description = "设备详细地址") | |
| 109 | - @ExcelProperty("设备详细地址") | |
| 110 | - private String address; | |
| 111 | - | |
| 112 | - @Schema(description = "设备序列号") | |
| 113 | - @ExcelProperty("设备序列号") | |
| 114 | - private String serialNumber; | |
| 115 | - | |
| 116 | 86 | @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 117 | 87 | @ExcelProperty("创建时间") |
| 118 | 88 | private LocalDateTime createTime; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDeviceStatusUpdateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.device.vo; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 4 | +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; | |
| 5 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 6 | +import jakarta.validation.constraints.NotNull; | |
| 7 | +import lombok.Data; | |
| 8 | + | |
| 9 | +@Schema(description = "管理后台 - IoT 设备状态更新 Request VO") | |
| 10 | +@Data | |
| 11 | +public class IotDeviceStatusUpdateReqVO { | |
| 12 | + | |
| 13 | + @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 14 | + @NotNull(message = "设备编号不能为空") | |
| 15 | + private Long id; | |
| 16 | + | |
| 17 | + @Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 18 | + @NotNull(message = "设备状态不能为空") | |
| 19 | + @InEnum(IotDeviceStatusEnum.class) | |
| 20 | + private Integer status; | |
| 21 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/product/IotProductController.java
| ... | ... | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | 6 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductPageReqVO; |
| 7 | 7 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductRespVO; |
| 8 | 8 | import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductSaveReqVO; |
| 9 | +import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductSimpleRespVO; | |
| 9 | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 10 | 11 | import cn.iocoder.yudao.module.iot.service.product.IotProductService; |
| 11 | 12 | import io.swagger.v3.oas.annotations.Operation; |
| ... | ... | @@ -17,6 +18,8 @@ import org.springframework.security.access.prepost.PreAuthorize; |
| 17 | 18 | import org.springframework.validation.annotation.Validated; |
| 18 | 19 | import org.springframework.web.bind.annotation.*; |
| 19 | 20 | |
| 21 | +import java.util.List; | |
| 22 | + | |
| 20 | 23 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 21 | 24 | |
| 22 | 25 | @Tag(name = "管理后台 - IoT 产品") |
| ... | ... | @@ -80,4 +83,12 @@ public class IotProductController { |
| 80 | 83 | return success(BeanUtils.toBean(pageResult, IotProductRespVO.class)); |
| 81 | 84 | } |
| 82 | 85 | |
| 86 | + @GetMapping("/list-all-simple") | |
| 87 | + @Operation(summary = "获得所有产品列表") | |
| 88 | + @PreAuthorize("@ss.hasPermission('iot:product:query')") | |
| 89 | + public CommonResult<List<IotProductSimpleRespVO>> listAllSimpleProducts() { | |
| 90 | + List<IotProductDO> list = productService.listAllProducts(); | |
| 91 | + return success(BeanUtils.toBean(list, IotProductSimpleRespVO.class)); | |
| 92 | + } | |
| 93 | + | |
| 83 | 94 | } |
| 84 | 95 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/product/vo/IotProductSimpleRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.product.vo; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +@Schema(description = "管理后台 - IoT 产品 Response VO") | |
| 7 | +@Data | |
| 8 | +public class IotProductSimpleRespVO { | |
| 9 | + | |
| 10 | + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26087") | |
| 11 | + private Long id; | |
| 12 | + | |
| 13 | + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") | |
| 14 | + private String name; | |
| 15 | + | |
| 16 | +} | |
| 0 | 17 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDO.java
| ... | ... | @@ -50,34 +50,34 @@ public class IotDeviceDO extends BaseDO { |
| 50 | 50 | |
| 51 | 51 | /** |
| 52 | 52 | * 产品编号 |
| 53 | - * | |
| 53 | + * <p> | |
| 54 | 54 | * 关联 {@link IotProductDO#getId()} |
| 55 | 55 | */ |
| 56 | 56 | private Long productId; |
| 57 | 57 | /** |
| 58 | 58 | * 产品标识 |
| 59 | - * | |
| 59 | + * <p> | |
| 60 | 60 | * 冗余 {@link IotProductDO#getProductKey()} |
| 61 | 61 | */ |
| 62 | 62 | private String productKey; |
| 63 | 63 | /** |
| 64 | 64 | * 设备类型 |
| 65 | - * | |
| 65 | + * <p> | |
| 66 | 66 | * 冗余 {@link IotProductDO#getDeviceType()} |
| 67 | 67 | */ |
| 68 | 68 | private Integer deviceType; |
| 69 | 69 | |
| 70 | 70 | /** |
| 71 | 71 | * 设备状态 |
| 72 | - * | |
| 72 | + * <p> | |
| 73 | 73 | * 枚举 {@link IotDeviceStatusEnum} |
| 74 | 74 | */ |
| 75 | 75 | private Integer status; |
| 76 | 76 | /** |
| 77 | 77 | * 网关设备编号 |
| 78 | - * | |
| 78 | + * <p> | |
| 79 | 79 | * 子设备需要关联的网关设备 ID |
| 80 | - * | |
| 80 | + * <p> | |
| 81 | 81 | * 关联 {@link IotDeviceDO#getId()} |
| 82 | 82 | */ |
| 83 | 83 | private Long gatewayId; |
| ... | ... | @@ -140,7 +140,7 @@ public class IotDeviceDO extends BaseDO { |
| 140 | 140 | private BigDecimal longitude; |
| 141 | 141 | /** |
| 142 | 142 | * 地区编码 |
| 143 | - * | |
| 143 | + * <p> | |
| 144 | 144 | * 关联 Area 的 id |
| 145 | 145 | */ |
| 146 | 146 | private Integer areaId; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java
| ... | ... | @@ -29,18 +29,11 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> { |
| 29 | 29 | .betweenIfPresent(IotDeviceDO::getLastOnlineTime, reqVO.getLastOnlineTime()) |
| 30 | 30 | .betweenIfPresent(IotDeviceDO::getLastOfflineTime, reqVO.getLastOfflineTime()) |
| 31 | 31 | .betweenIfPresent(IotDeviceDO::getActiveTime, reqVO.getActiveTime()) |
| 32 | - .eqIfPresent(IotDeviceDO::getIp, reqVO.getIp()) | |
| 33 | - .eqIfPresent(IotDeviceDO::getFirmwareVersion, reqVO.getFirmwareVersion()) | |
| 34 | 32 | .eqIfPresent(IotDeviceDO::getDeviceSecret, reqVO.getDeviceSecret()) |
| 35 | 33 | .eqIfPresent(IotDeviceDO::getMqttClientId, reqVO.getMqttClientId()) |
| 36 | 34 | .likeIfPresent(IotDeviceDO::getMqttUsername, reqVO.getMqttUsername()) |
| 37 | 35 | .eqIfPresent(IotDeviceDO::getMqttPassword, reqVO.getMqttPassword()) |
| 38 | 36 | .eqIfPresent(IotDeviceDO::getAuthType, reqVO.getAuthType()) |
| 39 | - .eqIfPresent(IotDeviceDO::getLatitude, reqVO.getLatitude()) | |
| 40 | - .eqIfPresent(IotDeviceDO::getLongitude, reqVO.getLongitude()) | |
| 41 | - .eqIfPresent(IotDeviceDO::getAreaId, reqVO.getAreaId()) | |
| 42 | - .eqIfPresent(IotDeviceDO::getAddress, reqVO.getAddress()) | |
| 43 | - .eqIfPresent(IotDeviceDO::getSerialNumber, reqVO.getSerialNumber()) | |
| 44 | 37 | .betweenIfPresent(IotDeviceDO::getCreateTime, reqVO.getCreateTime()) |
| 45 | 38 | .orderByDesc(IotDeviceDO::getId)); |
| 46 | 39 | } | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/product/IotProductMapper.java
| ... | ... | @@ -25,4 +25,5 @@ public interface IotProductMapper extends BaseMapperX<IotProductDO> { |
| 25 | 25 | default IotProductDO selectByProductKey(String productKey) { |
| 26 | 26 | return selectOne(new LambdaQueryWrapperX<IotProductDO>().eq(IotProductDO::getProductKey, productKey)); |
| 27 | 27 | } |
| 28 | + | |
| 28 | 29 | } |
| 29 | 30 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
| ... | ... | @@ -6,11 +6,12 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 7 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO; |
| 8 | 8 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO; |
| 9 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO; | |
| 9 | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 10 | 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 11 | 12 | import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper; |
| 12 | -import cn.iocoder.yudao.module.iot.dal.mysql.product.IotProductMapper; | |
| 13 | 13 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; |
| 14 | +import cn.iocoder.yudao.module.iot.service.product.IotProductService; | |
| 14 | 15 | import jakarta.annotation.Resource; |
| 15 | 16 | import lombok.extern.slf4j.Slf4j; |
| 16 | 17 | import org.springframework.stereotype.Service; |
| ... | ... | @@ -35,9 +36,8 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 35 | 36 | |
| 36 | 37 | @Resource |
| 37 | 38 | private IotDeviceMapper deviceMapper; |
| 38 | - // TODO @haohao:不直接调用 productmapper,通过 productservice;每一个模型,不直接使用对方的 | |
| 39 | 39 | @Resource |
| 40 | - private IotProductMapper productMapper; | |
| 40 | + private IotProductService productService; | |
| 41 | 41 | |
| 42 | 42 | /** |
| 43 | 43 | * 创建 IoT 设备 |
| ... | ... | @@ -49,7 +49,7 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 49 | 49 | @Transactional(rollbackFor = Exception.class) |
| 50 | 50 | public Long createDevice(IotDeviceSaveReqVO createReqVO) { |
| 51 | 51 | // 1.1 校验产品是否存在 |
| 52 | - IotProductDO product = productMapper.selectById(createReqVO.getProductId()); | |
| 52 | + IotProductDO product = productService.getProduct(createReqVO.getProductId()); | |
| 53 | 53 | if (product == null) { |
| 54 | 54 | throw exception(PRODUCT_NOT_EXISTS); |
| 55 | 55 | } |
| ... | ... | @@ -106,8 +106,7 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 106 | 106 | * @return 生成的 deviceSecret |
| 107 | 107 | */ |
| 108 | 108 | private String generateDeviceSecret() { |
| 109 | - // TODO @haohao:return IdUtil.fastSimpleUUID() | |
| 110 | - return UUID.randomUUID().toString().replace("-", ""); | |
| 109 | + return IdUtil.fastSimpleUUID(); | |
| 111 | 110 | } |
| 112 | 111 | |
| 113 | 112 | /** |
| ... | ... | @@ -147,7 +146,6 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 147 | 146 | * @return 生成的唯一 DeviceName |
| 148 | 147 | */ |
| 149 | 148 | private String generateUniqueDeviceName(String productKey) { |
| 150 | - // TODO @haohao:业务逻辑里,尽量避免 while true。万一 bug = =;虽然这个不会哈。我先改了下 | |
| 151 | 149 | for (int i = 0; i < Short.MAX_VALUE; i++) { |
| 152 | 150 | String deviceName = IdUtil.fastSimpleUUID().substring(0, 20); |
| 153 | 151 | if (deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName) != null) { |
| ... | ... | @@ -161,16 +159,11 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 161 | 159 | @Transactional(rollbackFor = Exception.class) |
| 162 | 160 | public void updateDevice(IotDeviceSaveReqVO updateReqVO) { |
| 163 | 161 | // 校验存在 |
| 164 | - IotDeviceDO existingDevice = validateDeviceExists(updateReqVO.getId()); | |
| 162 | + validateDeviceExists(updateReqVO.getId()); | |
| 165 | 163 | |
| 166 | 164 | // 设备名称 和 产品 ID 不能修改 |
| 167 | - // TODO @haohao:这种,直接设置为 null 就不会更新了。忽略前端的传参 | |
| 168 | - if (updateReqVO.getDeviceName() != null && !updateReqVO.getDeviceName().equals(existingDevice.getDeviceName())) { | |
| 169 | - throw exception(DEVICE_NAME_CANNOT_BE_MODIFIED); | |
| 170 | - } | |
| 171 | - if (updateReqVO.getProductId() != null && !updateReqVO.getProductId().equals(existingDevice.getProductId())) { | |
| 172 | - throw exception(DEVICE_PRODUCT_CANNOT_BE_MODIFIED); | |
| 173 | - } | |
| 165 | + updateReqVO.setDeviceName(null); | |
| 166 | + updateReqVO.setProductId(null); | |
| 174 | 167 | |
| 175 | 168 | // 更新 DO 对象 |
| 176 | 169 | IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class); |
| ... | ... | @@ -222,19 +215,12 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 222 | 215 | } |
| 223 | 216 | |
| 224 | 217 | @Override |
| 225 | - public void updateDeviceStatus(Long id, Integer status) { | |
| 218 | + public void updateDeviceStatus(IotDeviceStatusUpdateReqVO updateReqVO) { | |
| 226 | 219 | // 校验存在 |
| 227 | - validateDeviceExists(id); | |
| 228 | - | |
| 229 | - // TODO @haohao:这个可以直接用 swagger 注解哈 | |
| 230 | - // 校验状态是否合法 | |
| 231 | - if (!IotDeviceStatusEnum.isValidStatus(status)) { | |
| 232 | - throw exception(DEVICE_INVALID_DEVICE_STATUS); | |
| 233 | - } | |
| 220 | + validateDeviceExists(updateReqVO.getId()); | |
| 234 | 221 | |
| 235 | 222 | // 更新状态和更新时间 |
| 236 | - IotDeviceDO updateObj = new IotDeviceDO().setId(id).setStatus(status) | |
| 237 | - .setStatusLastUpdateTime(LocalDateTime.now()); | |
| 223 | + IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class); | |
| 238 | 224 | deviceMapper.updateById(updateObj); |
| 239 | 225 | } |
| 240 | 226 | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
| ... | ... | @@ -53,9 +53,8 @@ public interface IotDeviceService { |
| 53 | 53 | /** |
| 54 | 54 | * 更新设备状态 |
| 55 | 55 | * |
| 56 | - * @param id 编号 | |
| 57 | - * @param status 状态 | |
| 56 | + * @param updateReqVO 更新信息 | |
| 58 | 57 | */ |
| 59 | - void updateDeviceStatus(Long id, Integer status); | |
| 58 | + void updateDeviceStatus(IotDeviceStatusUpdateReqVO updateReqVO); | |
| 60 | 59 | |
| 61 | 60 | } |
| 62 | 61 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductService.java
| ... | ... | @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductSaveReq |
| 6 | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 7 | 7 | import jakarta.validation.Valid; |
| 8 | 8 | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 9 | 11 | /** |
| 10 | 12 | * IoT 产品 Service 接口 |
| 11 | 13 | * |
| ... | ... | @@ -58,4 +60,12 @@ public interface IotProductService { |
| 58 | 60 | * @param status 状态 |
| 59 | 61 | */ |
| 60 | 62 | void updateProductStatus(Long id, Integer status); |
| 63 | + | |
| 64 | + /** | |
| 65 | + * 获得所有产品 | |
| 66 | + * | |
| 67 | + * @return 产品列表 | |
| 68 | + */ | |
| 69 | + List<IotProductDO> listAllProducts(); | |
| 70 | + | |
| 61 | 71 | } |
| 62 | 72 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductServiceImpl.java
| ... | ... | @@ -12,6 +12,7 @@ import jakarta.annotation.Resource; |
| 12 | 12 | import org.springframework.stereotype.Service; |
| 13 | 13 | import org.springframework.validation.annotation.Validated; |
| 14 | 14 | |
| 15 | +import java.util.List; | |
| 15 | 16 | import java.util.Objects; |
| 16 | 17 | import java.util.UUID; |
| 17 | 18 | |
| ... | ... | @@ -113,4 +114,9 @@ public class IotProductServiceImpl implements IotProductService { |
| 113 | 114 | productMapper.updateById(updateObj); |
| 114 | 115 | } |
| 115 | 116 | |
| 117 | + @Override | |
| 118 | + public List<IotProductDO> listAllProducts() { | |
| 119 | + return productMapper.selectList(); | |
| 120 | + } | |
| 121 | + | |
| 116 | 122 | } |
| 117 | 123 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thinkmodelfunction/IotThinkModelFunctionServiceImpl.java
| ... | ... | @@ -24,6 +24,7 @@ import org.springframework.transaction.annotation.Transactional; |
| 24 | 24 | import org.springframework.validation.annotation.Validated; |
| 25 | 25 | |
| 26 | 26 | import java.util.*; |
| 27 | +import java.util.stream.Collectors; | |
| 27 | 28 | |
| 28 | 29 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 29 | 30 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList; |
| ... | ... | @@ -176,22 +177,33 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe |
| 176 | 177 | List<IotThinkModelFunctionDO> createList = diffResult.get(0); // 需要新增的 |
| 177 | 178 | List<IotThinkModelFunctionDO> updateList = diffResult.get(1); // 需要更新的 |
| 178 | 179 | List<IotThinkModelFunctionDO> deleteList = diffResult.get(2); // 需要删除的 |
| 180 | + | |
| 179 | 181 | // 3.2 批量执行数据库操作 |
| 182 | + // 新增数据库中的新事件和服务列表 | |
| 180 | 183 | if (CollUtil.isNotEmpty(createList)) { |
| 181 | 184 | thinkModelFunctionMapper.insertBatch(createList); |
| 182 | 185 | } |
| 186 | + // 更新数据库中的事件和服务列表 | |
| 183 | 187 | if (CollUtil.isNotEmpty(updateList)) { |
| 184 | - for (IotThinkModelFunctionDO updateFunc : updateList) { | |
| 185 | - // 设置 ID,以便更新 | |
| 188 | + // 首先,为每个需要更新的对象设置其对应的 ID | |
| 189 | + updateList.forEach(updateFunc -> { | |
| 186 | 190 | IotThinkModelFunctionDO oldFunc = findFunctionByIdentifierAndType( |
| 187 | 191 | oldFunctionList, updateFunc.getIdentifier(), updateFunc.getType()); |
| 188 | 192 | if (oldFunc != null) { |
| 189 | 193 | updateFunc.setId(oldFunc.getId()); |
| 190 | - thinkModelFunctionMapper.updateById(updateFunc); | |
| 191 | 194 | } |
| 195 | + }); | |
| 196 | + // 过滤掉没有设置 ID 的对象 | |
| 197 | + List<IotThinkModelFunctionDO> validUpdateList = updateList.stream() | |
| 198 | + .filter(func -> func.getId() != null) | |
| 199 | + .collect(Collectors.toList()); | |
| 200 | + // 执行批量更新 | |
| 201 | + if (CollUtil.isNotEmpty(validUpdateList)) { | |
| 202 | + thinkModelFunctionMapper.updateBatch(validUpdateList); | |
| 192 | 203 | } |
| 193 | - // TODO @haohao:seckillProductMapper.updateBatch(diffList.get(1)); 可以直接类似这么操作哇? | |
| 194 | 204 | } |
| 205 | + | |
| 206 | + // 删除数据库中的旧事件和服务列表 | |
| 195 | 207 | if (CollUtil.isNotEmpty(deleteList)) { |
| 196 | 208 | Set<Long> idsToDelete = CollectionUtils.convertSet(deleteList, IotThinkModelFunctionDO::getId); |
| 197 | 209 | thinkModelFunctionMapper.deleteByIds(idsToDelete); | ... | ... |