Commit 6b9cca0b79612fc3ca26f04b73b23d9f973dd873
1 parent
bd18e730
【代码评审】IOT:设备的 review
Showing
14 changed files
with
143 additions
and
438 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/device/IotDeviceStatusEnum.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.enums.device; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | |
| 3 | 4 | import lombok.Getter; |
| 4 | 5 | |
| 6 | +import java.util.Arrays; | |
| 7 | + | |
| 5 | 8 | /** |
| 6 | 9 | * IoT 设备状态枚举 |
| 7 | - * 设备状态:0 - 未激活,1 - 在线,2 - 离线,3 - 已禁用 | |
| 10 | + * | |
| 11 | + * @author haohao | |
| 8 | 12 | */ |
| 9 | 13 | @Getter |
| 10 | -public enum IotDeviceStatusEnum { | |
| 14 | +public enum IotDeviceStatusEnum implements IntArrayValuable { | |
| 11 | 15 | |
| 12 | 16 | INACTIVE(0, "未激活"), |
| 13 | 17 | ONLINE(1, "在线"), |
| 14 | 18 | OFFLINE(2, "离线"), |
| 15 | 19 | DISABLED(3, "已禁用"); |
| 16 | 20 | |
| 21 | + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(IotDeviceStatusEnum::getStatus).toArray(); | |
| 22 | + | |
| 17 | 23 | /** |
| 18 | 24 | * 状态 |
| 19 | 25 | */ |
| ... | ... | @@ -40,4 +46,10 @@ public enum IotDeviceStatusEnum { |
| 40 | 46 | public static boolean isValidStatus(Integer status) { |
| 41 | 47 | return fromStatus(status) != null; |
| 42 | 48 | } |
| 49 | + | |
| 50 | + @Override | |
| 51 | + public int[] array() { | |
| 52 | + return ARRAYS; | |
| 53 | + } | |
| 54 | + | |
| 43 | 55 | } | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.java
| ... | ... | @@ -37,14 +37,14 @@ public class IotDeviceController { |
| 37 | 37 | private IotDeviceService deviceService; |
| 38 | 38 | |
| 39 | 39 | @PostMapping("/create") |
| 40 | - @Operation(summary = "创建IoT 设备") | |
| 40 | + @Operation(summary = "创建设备") | |
| 41 | 41 | @PreAuthorize("@ss.hasPermission('iot:device:create')") |
| 42 | 42 | public CommonResult<Long> createDevice(@Valid @RequestBody IotDeviceSaveReqVO createReqVO) { |
| 43 | 43 | return success(deviceService.createDevice(createReqVO)); |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | @PutMapping("/update-status") |
| 47 | - @Operation(summary = "更新IoT 设备状态") | |
| 47 | + @Operation(summary = "更新设备状态") | |
| 48 | 48 | @Parameter(name = "id", description = "编号", required = true) |
| 49 | 49 | @Parameter(name = "status", description = "状态", required = true, example = "1") |
| 50 | 50 | @PreAuthorize("@ss.hasPermission('iot:device:update')") |
| ... | ... | @@ -55,7 +55,7 @@ public class IotDeviceController { |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | 57 | @PutMapping("/update") |
| 58 | - @Operation(summary = "更新IoT 设备") | |
| 58 | + @Operation(summary = "更新设备") | |
| 59 | 59 | @PreAuthorize("@ss.hasPermission('iot:device:update')") |
| 60 | 60 | public CommonResult<Boolean> updateDevice(@Valid @RequestBody IotDeviceSaveReqVO updateReqVO) { |
| 61 | 61 | deviceService.updateDevice(updateReqVO); |
| ... | ... | @@ -63,7 +63,7 @@ public class IotDeviceController { |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | 65 | @DeleteMapping("/delete") |
| 66 | - @Operation(summary = "删除IoT 设备") | |
| 66 | + @Operation(summary = "删除设备") | |
| 67 | 67 | @Parameter(name = "id", description = "编号", required = true) |
| 68 | 68 | @PreAuthorize("@ss.hasPermission('iot:device:delete')") |
| 69 | 69 | public CommonResult<Boolean> deleteDevice(@RequestParam("id") Long id) { |
| ... | ... | @@ -72,7 +72,7 @@ public class IotDeviceController { |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | @GetMapping("/get") |
| 75 | - @Operation(summary = "获得IoT 设备") | |
| 75 | + @Operation(summary = "获得设备") | |
| 76 | 76 | @Parameter(name = "id", description = "编号", required = true, example = "1024") |
| 77 | 77 | @PreAuthorize("@ss.hasPermission('iot:device:query')") |
| 78 | 78 | public CommonResult<IotDeviceRespVO> getDevice(@RequestParam("id") Long id) { |
| ... | ... | @@ -81,7 +81,7 @@ public class IotDeviceController { |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | 83 | @GetMapping("/page") |
| 84 | - @Operation(summary = "获得IoT 设备分页") | |
| 84 | + @Operation(summary = "获得设备分页") | |
| 85 | 85 | @PreAuthorize("@ss.hasPermission('iot:device:query')") |
| 86 | 86 | public CommonResult<PageResult<IotDeviceRespVO>> getDevicePage(@Valid IotDevicePageReqVO pageReqVO) { |
| 87 | 87 | PageResult<IotDeviceDO> pageResult = deviceService.getDevicePage(pageReqVO); |
| ... | ... | @@ -89,7 +89,7 @@ public class IotDeviceController { |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | @GetMapping("/export-excel") |
| 92 | - @Operation(summary = "导出IoT 设备 Excel") | |
| 92 | + @Operation(summary = "导出设备 Excel") | |
| 93 | 93 | @PreAuthorize("@ss.hasPermission('iot:device:export')") |
| 94 | 94 | @ApiAccessLog(operateType = EXPORT) |
| 95 | 95 | public void exportDeviceExcel(@Valid IotDevicePageReqVO pageReqVO, | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDevicePageReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.controller.admin.device.vo; |
| 2 | 2 | |
| 3 | -import lombok.*; | |
| 4 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 5 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 6 | -import java.math.BigDecimal; | |
| 4 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 5 | +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; | |
| 6 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 7 | +import lombok.Data; | |
| 8 | +import lombok.EqualsAndHashCode; | |
| 9 | +import lombok.ToString; | |
| 7 | 10 | import org.springframework.format.annotation.DateTimeFormat; |
| 11 | + | |
| 12 | +import java.math.BigDecimal; | |
| 8 | 13 | import java.time.LocalDateTime; |
| 9 | 14 | |
| 10 | 15 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| ... | ... | @@ -15,28 +20,32 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ |
| 15 | 20 | @ToString(callSuper = true) |
| 16 | 21 | public class IotDevicePageReqVO extends PageParam { |
| 17 | 22 | |
| 18 | - @Schema(description = "设备唯一标识符,全局唯一,用于识别设备") | |
| 23 | + // TODO @芋艿:需要去掉一些多余的字段; | |
| 24 | + | |
| 25 | + @Schema(description = "设备唯一标识符", example = "24602") | |
| 19 | 26 | private String deviceKey; |
| 20 | 27 | |
| 21 | - @Schema(description = "设备名称,在产品内唯一,用于标识设备", example = "王五") | |
| 28 | + @Schema(description = "设备名称", example = "王五") | |
| 22 | 29 | private String deviceName; |
| 23 | 30 | |
| 24 | - @Schema(description = "产品 ID,关联 iot_product 表的 id", example = "26202") | |
| 31 | + @Schema(description = "产品编号", example = "26202") | |
| 25 | 32 | private Long productId; |
| 26 | 33 | |
| 27 | - @Schema(description = "产品 Key,关联 iot_product 表的 product_key") | |
| 34 | + @Schema(description = "产品标识") | |
| 28 | 35 | private String productKey; |
| 29 | 36 | |
| 30 | - @Schema(description = "设备类型:0 - 直连设备,1 - 网关子设备,2 - 网关设备", example = "1") | |
| 37 | + @Schema(description = "设备类型", example = "1") | |
| 38 | + // TODO @haohao:需要有个设备类型的枚举 | |
| 31 | 39 | private Integer deviceType; |
| 32 | 40 | |
| 33 | - @Schema(description = "设备备注名称,供用户自定义备注", example = "张三") | |
| 41 | + @Schema(description = "备注名称", example = "张三") | |
| 34 | 42 | private String nickname; |
| 35 | 43 | |
| 36 | - @Schema(description = "网关设备 ID,子设备需要关联的网关设备 ID", example = "16380") | |
| 44 | + @Schema(description = "网关设备 ID", example = "16380") | |
| 37 | 45 | private Long gatewayId; |
| 38 | 46 | |
| 39 | - @Schema(description = "设备状态:0 - 未激活,1 - 在线,2 - 离线,3 - 已禁用", example = "1") | |
| 47 | + @Schema(description = "设备状态", example = "1") | |
| 48 | + @InEnum(IotDeviceStatusEnum.class) | |
| 40 | 49 | private Integer status; |
| 41 | 50 | |
| 42 | 51 | @Schema(description = "设备状态最后更新时间") | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDeviceRespVO.java
| ... | ... | @@ -13,7 +13,7 @@ import java.time.LocalDateTime; |
| 13 | 13 | @ExcelIgnoreUnannotated |
| 14 | 14 | public class IotDeviceRespVO { |
| 15 | 15 | |
| 16 | - @Schema(description = "设备 ID,主键,自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "177") | |
| 16 | + @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177") | |
| 17 | 17 | private Long id; |
| 18 | 18 | |
| 19 | 19 | @Schema(description = "设备唯一标识符", requiredMode = Schema.RequiredMode.REQUIRED) |
| ... | ... | @@ -24,11 +24,11 @@ public class IotDeviceRespVO { |
| 24 | 24 | @ExcelProperty("设备名称备") |
| 25 | 25 | private String deviceName; |
| 26 | 26 | |
| 27 | - @Schema(description = "产品 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202") | |
| 27 | + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202") | |
| 28 | 28 | @ExcelProperty("产品 ID") |
| 29 | 29 | private Long productId; |
| 30 | 30 | |
| 31 | - @Schema(description = "产品 Key", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 31 | + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 32 | 32 | @ExcelProperty("产品 Key") |
| 33 | 33 | private String productKey; |
| 34 | 34 | |
| ... | ... | @@ -72,7 +72,7 @@ public class IotDeviceRespVO { |
| 72 | 72 | @ExcelProperty("设备的固件版本") |
| 73 | 73 | private String firmwareVersion; |
| 74 | 74 | |
| 75 | - @Schema(description = "设备密钥,用于设备认证,需安全存储") | |
| 75 | + @Schema(description = "设备密钥,用于设备认证") | |
| 76 | 76 | @ExcelProperty("设备密钥") |
| 77 | 77 | private String deviceSecret; |
| 78 | 78 | |
| ... | ... | @@ -92,16 +92,17 @@ public class IotDeviceRespVO { |
| 92 | 92 | @ExcelProperty("认证类型(如一机一密、动态注册)") |
| 93 | 93 | private String authType; |
| 94 | 94 | |
| 95 | - @Schema(description = "设备位置的纬度,范围 -90.000000 ~ 90.000000") | |
| 96 | - @ExcelProperty("设备位置的纬度,范围 -90.000000 ~ 90.000000") | |
| 95 | + // TODO @haohao:经纬度:可能 double 就够啦 | |
| 96 | + @Schema(description = "设备位置的纬度,范围") | |
| 97 | + @ExcelProperty("设备位置的纬度") | |
| 97 | 98 | private BigDecimal latitude; |
| 98 | 99 | |
| 99 | - @Schema(description = "设备位置的经度,范围 -180.000000 ~ 180.000000") | |
| 100 | - @ExcelProperty("设备位置的经度,范围 -180.000000 ~ 180.000000") | |
| 100 | + @Schema(description = "设备位置的经度") | |
| 101 | + @ExcelProperty("设备位置的经度") | |
| 101 | 102 | private BigDecimal longitude; |
| 102 | 103 | |
| 103 | - @Schema(description = "地区编码,符合国家地区编码标准,关联地区表", example = "16995") | |
| 104 | - @ExcelProperty("地区编码,符合国家地区编码标准,关联地区表") | |
| 104 | + @Schema(description = "地区编码", example = "16995") | |
| 105 | + @ExcelProperty("地区编码") | |
| 105 | 106 | private Integer areaId; |
| 106 | 107 | |
| 107 | 108 | @Schema(description = "设备详细地址") | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/IotDeviceSaveReqVO.java
| ... | ... | @@ -7,16 +7,16 @@ import lombok.Data; |
| 7 | 7 | @Data |
| 8 | 8 | public class IotDeviceSaveReqVO { |
| 9 | 9 | |
| 10 | - @Schema(description = "设备 ID,主键,自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "177") | |
| 10 | + @Schema(description = "设备编号", example = "177") | |
| 11 | 11 | private Long id; |
| 12 | 12 | |
| 13 | - @Schema(description = "设备名称,在产品内唯一,用于标识设备", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") | |
| 13 | + @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") | |
| 14 | 14 | private String deviceName; |
| 15 | 15 | |
| 16 | - @Schema(description = "设备备注名称,供用户自定义备注", example = "张三") | |
| 16 | + @Schema(description = "备注名称", example = "张三") | |
| 17 | 17 | private String nickname; |
| 18 | 18 | |
| 19 | - @Schema(description = "产品 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202") | |
| 19 | + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202") | |
| 20 | 20 | private Long productId; |
| 21 | 21 | |
| 22 | 22 | } |
| 23 | 23 | \ 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
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.dal.dataobject.device; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 5 | +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; | |
| 5 | 6 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 6 | 7 | import com.baomidou.mybatisplus.annotation.TableId; |
| 7 | 8 | import com.baomidou.mybatisplus.annotation.TableName; |
| ... | ... | @@ -13,7 +14,7 @@ import java.time.LocalDateTime; |
| 13 | 14 | /** |
| 14 | 15 | * IoT 设备 DO |
| 15 | 16 | * |
| 16 | - * @author 芋道源码 | |
| 17 | + * @author haohao | |
| 17 | 18 | */ |
| 18 | 19 | @TableName("iot_device") |
| 19 | 20 | @KeySequence("iot_device_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 |
| ... | ... | @@ -39,33 +40,48 @@ public class IotDeviceDO extends BaseDO { |
| 39 | 40 | */ |
| 40 | 41 | private String deviceName; |
| 41 | 42 | /** |
| 42 | - * 产品 ID,关联 iot_product 表的 id | |
| 43 | + * 设备备注名称 | |
| 44 | + */ | |
| 45 | + private String nickname; | |
| 46 | + /** | |
| 47 | + * 设备序列号 | |
| 48 | + */ | |
| 49 | + private String serialNumber; | |
| 50 | + | |
| 51 | + /** | |
| 52 | + * 产品编号 | |
| 53 | + * | |
| 43 | 54 | * 关联 {@link IotProductDO#getId()} |
| 44 | 55 | */ |
| 45 | 56 | private Long productId; |
| 46 | 57 | /** |
| 47 | - * 产品 Key,关联 iot_product 表的 product_key | |
| 48 | - * 关联 {@link IotProductDO#getProductKey()} | |
| 58 | + * 产品标识 | |
| 59 | + * | |
| 60 | + * 冗余 {@link IotProductDO#getProductKey()} | |
| 49 | 61 | */ |
| 50 | 62 | private String productKey; |
| 51 | 63 | /** |
| 52 | - * 设备类型:0 - 直连设备,1 - 网关子设备,2 - 网关设备 | |
| 53 | - * 关联 {@link IotProductDO#getDeviceType()} | |
| 64 | + * 设备类型 | |
| 65 | + * | |
| 66 | + * 冗余 {@link IotProductDO#getDeviceType()} | |
| 54 | 67 | */ |
| 55 | 68 | private Integer deviceType; |
| 69 | + | |
| 56 | 70 | /** |
| 57 | - * 设备备注名称,供用户自定义备注 | |
| 71 | + * 设备状态 | |
| 72 | + * | |
| 73 | + * 枚举 {@link IotDeviceStatusEnum} | |
| 58 | 74 | */ |
| 59 | - private String nickname; | |
| 75 | + private Integer status; | |
| 60 | 76 | /** |
| 61 | - * 网关设备 ID,子设备需要关联的网关设备 ID | |
| 77 | + * 网关设备编号 | |
| 78 | + * | |
| 79 | + * 子设备需要关联的网关设备 ID | |
| 80 | + * | |
| 81 | + * 关联 {@link IotDeviceDO#getId()} | |
| 62 | 82 | */ |
| 63 | 83 | private Long gatewayId; |
| 64 | - /** | |
| 65 | - * 设备状态:0 - 未激活,1 - 在线,2 - 离线,3 - 已禁用 | |
| 66 | - * 关联 {@link cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum} | |
| 67 | - */ | |
| 68 | - private Integer status; | |
| 84 | + | |
| 69 | 85 | /** |
| 70 | 86 | * 设备状态最后更新时间 |
| 71 | 87 | */ |
| ... | ... | @@ -82,6 +98,7 @@ public class IotDeviceDO extends BaseDO { |
| 82 | 98 | * 设备激活时间 |
| 83 | 99 | */ |
| 84 | 100 | private LocalDateTime activeTime; |
| 101 | + | |
| 85 | 102 | /** |
| 86 | 103 | * 设备的 IP 地址 |
| 87 | 104 | */ |
| ... | ... | @@ -90,6 +107,7 @@ public class IotDeviceDO extends BaseDO { |
| 90 | 107 | * 设备的固件版本 |
| 91 | 108 | */ |
| 92 | 109 | private String firmwareVersion; |
| 110 | + | |
| 93 | 111 | /** |
| 94 | 112 | * 设备密钥,用于设备认证,需安全存储 |
| 95 | 113 | */ |
| ... | ... | @@ -109,26 +127,26 @@ public class IotDeviceDO extends BaseDO { |
| 109 | 127 | /** |
| 110 | 128 | * 认证类型(如一机一密、动态注册) |
| 111 | 129 | */ |
| 130 | + // TODO @haohao:是不是要枚举哈 | |
| 112 | 131 | private String authType; |
| 132 | + | |
| 113 | 133 | /** |
| 114 | - * 设备位置的纬度,范围 -90.000000 ~ 90.000000 | |
| 134 | + * 设备位置的纬度 | |
| 115 | 135 | */ |
| 116 | 136 | private BigDecimal latitude; |
| 117 | 137 | /** |
| 118 | - * 设备位置的经度,范围 -180.000000 ~ 180.000000 | |
| 138 | + * 设备位置的经度 | |
| 119 | 139 | */ |
| 120 | 140 | private BigDecimal longitude; |
| 121 | 141 | /** |
| 122 | - * 地区编码,符合国家地区编码标准,关联地区表 | |
| 142 | + * 地区编码 | |
| 143 | + * | |
| 144 | + * 关联 Area 的 id | |
| 123 | 145 | */ |
| 124 | 146 | private Integer areaId; |
| 125 | 147 | /** |
| 126 | 148 | * 设备详细地址 |
| 127 | 149 | */ |
| 128 | 150 | private String address; |
| 129 | - /** | |
| 130 | - * 设备序列号 | |
| 131 | - */ | |
| 132 | - private String serialNumber; | |
| 133 | 151 | |
| 134 | 152 | } |
| 135 | 153 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.device; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.IdUtil; | |
| 3 | 4 | import cn.hutool.core.util.StrUtil; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| ... | ... | @@ -34,6 +35,7 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 34 | 35 | |
| 35 | 36 | @Resource |
| 36 | 37 | private IotDeviceMapper deviceMapper; |
| 38 | + // TODO @haohao:不直接调用 productmapper,通过 productservice;每一个模型,不直接使用对方的 | |
| 37 | 39 | @Resource |
| 38 | 40 | private IotProductMapper productMapper; |
| 39 | 41 | |
| ... | ... | @@ -46,40 +48,33 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 46 | 48 | @Override |
| 47 | 49 | @Transactional(rollbackFor = Exception.class) |
| 48 | 50 | public Long createDevice(IotDeviceSaveReqVO createReqVO) { |
| 49 | - // 1. 转换 VO 为 DO | |
| 50 | - IotDeviceDO device = BeanUtils.toBean(createReqVO, IotDeviceDO.class); | |
| 51 | - | |
| 52 | - // 2. 根据产品 ID 查询产品信息 | |
| 51 | + // 1.1 校验产品是否存在 | |
| 53 | 52 | IotProductDO product = productMapper.selectById(createReqVO.getProductId()); |
| 54 | 53 | if (product == null) { |
| 55 | 54 | throw exception(PRODUCT_NOT_EXISTS); |
| 56 | 55 | } |
| 57 | - device.setProductKey(product.getProductKey()); | |
| 58 | - device.setDeviceType(product.getDeviceType()); | |
| 59 | - | |
| 60 | - // 3. DeviceName 可以为空,当为空时,自动生成产品下的唯一标识符作为 DeviceName | |
| 61 | - if (StrUtil.isBlank(device.getDeviceName())) { | |
| 62 | - device.setDeviceName(generateUniqueDeviceName(createReqVO.getProductId())); | |
| 56 | + // 1.2 校验设备名称在同一产品下是否唯一 | |
| 57 | + if (StrUtil.isBlank(createReqVO.getDeviceName())) { | |
| 58 | + createReqVO.setDeviceName(generateUniqueDeviceName(product.getProductKey())); | |
| 59 | + } else { | |
| 60 | + validateDeviceNameUnique(product.getProductKey(), createReqVO.getDeviceName()); | |
| 63 | 61 | } |
| 64 | 62 | |
| 65 | - // 4. 校验设备名称在同一产品下是否唯一 | |
| 66 | - validateDeviceNameUnique(device.getProductKey(), device.getDeviceName()); | |
| 67 | - | |
| 68 | - // 5. 生成并设置必要的字段 | |
| 63 | + // 2.1 转换 VO 为 DO | |
| 64 | + IotDeviceDO device = BeanUtils.toBean(createReqVO, IotDeviceDO.class) | |
| 65 | + .setProductKey(product.getProductKey()) | |
| 66 | + .setDeviceType(product.getDeviceType()); | |
| 67 | + // 2.2 生成并设置必要的字段 | |
| 69 | 68 | device.setDeviceKey(generateUniqueDeviceKey()); |
| 70 | 69 | device.setDeviceSecret(generateDeviceSecret()); |
| 71 | 70 | device.setMqttClientId(generateMqttClientId()); |
| 72 | 71 | device.setMqttUsername(generateMqttUsername(device.getDeviceName(), device.getProductKey())); |
| 73 | 72 | device.setMqttPassword(generateMqttPassword()); |
| 74 | - | |
| 75 | - // 6. 设置设备状态为未激活 | |
| 73 | + // 2.3 设置设备状态为未激活 | |
| 76 | 74 | device.setStatus(IotDeviceStatusEnum.INACTIVE.getStatus()); |
| 77 | 75 | device.setStatusLastUpdateTime(LocalDateTime.now()); |
| 78 | - | |
| 79 | - // 7. 插入到数据库 | |
| 76 | + // 2.4 插入到数据库 | |
| 80 | 77 | deviceMapper.insert(device); |
| 81 | - | |
| 82 | - // 8. 返回生成的设备 ID | |
| 83 | 78 | return device.getId(); |
| 84 | 79 | } |
| 85 | 80 | |
| ... | ... | @@ -111,7 +106,7 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 111 | 106 | * @return 生成的 deviceSecret |
| 112 | 107 | */ |
| 113 | 108 | private String generateDeviceSecret() { |
| 114 | - // 32 位随机字符串 | |
| 109 | + // TODO @haohao:return IdUtil.fastSimpleUUID() | |
| 115 | 110 | return UUID.randomUUID().toString().replace("-", ""); |
| 116 | 111 | } |
| 117 | 112 | |
| ... | ... | @@ -141,39 +136,25 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 141 | 136 | * @return 生成的 MQTT Password |
| 142 | 137 | */ |
| 143 | 138 | private String generateMqttPassword() { |
| 144 | - // 在实际应用中,建议使用更安全的方法生成 MQTT Password,如加密或哈希 | |
| 139 | + // TODO @haohao:【后续优化】在实际应用中,建议使用更安全的方法生成 MQTT Password,如加密或哈希 | |
| 145 | 140 | return UUID.randomUUID().toString(); |
| 146 | 141 | } |
| 147 | 142 | |
| 148 | 143 | /** |
| 149 | 144 | * 生成唯一的 DeviceName |
| 150 | 145 | * |
| 151 | - * @param productId 产品 ID | |
| 146 | + * @param productKey 产品标识 | |
| 152 | 147 | * @return 生成的唯一 DeviceName |
| 153 | 148 | */ |
| 154 | - private String generateUniqueDeviceName(Long productId) { | |
| 155 | - // 实现逻辑以在产品下生成唯一的设备名称 | |
| 156 | - String deviceName; | |
| 157 | - String productKey = getProductKey(productId); | |
| 158 | - do { | |
| 159 | - // 20 位随机字符串 | |
| 160 | - deviceName = UUID.randomUUID().toString().replace("-", "").substring(0, 20); | |
| 161 | - } while (deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName) != null); | |
| 162 | - return deviceName; | |
| 163 | - } | |
| 164 | - | |
| 165 | - /** | |
| 166 | - * 获取产品 Key | |
| 167 | - * | |
| 168 | - * @param productId 产品 ID | |
| 169 | - * @return 产品 Key | |
| 170 | - */ | |
| 171 | - private String getProductKey(Long productId) { | |
| 172 | - IotProductDO product = productMapper.selectById(productId); | |
| 173 | - if (product == null) { | |
| 174 | - throw exception(PRODUCT_NOT_EXISTS); | |
| 149 | + private String generateUniqueDeviceName(String productKey) { | |
| 150 | + // TODO @haohao:业务逻辑里,尽量避免 while true。万一 bug = =;虽然这个不会哈。我先改了下 | |
| 151 | + for (int i = 0; i < Short.MAX_VALUE; i++) { | |
| 152 | + String deviceName = IdUtil.fastSimpleUUID().substring(0, 20); | |
| 153 | + if (deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName) != null) { | |
| 154 | + return deviceName; | |
| 155 | + } | |
| 175 | 156 | } |
| 176 | - return product.getProductKey(); | |
| 157 | + throw new IllegalArgumentException("生成 DeviceName 失败"); | |
| 177 | 158 | } |
| 178 | 159 | |
| 179 | 160 | @Override |
| ... | ... | @@ -183,6 +164,7 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 183 | 164 | IotDeviceDO existingDevice = validateDeviceExists(updateReqVO.getId()); |
| 184 | 165 | |
| 185 | 166 | // 设备名称 和 产品 ID 不能修改 |
| 167 | + // TODO @haohao:这种,直接设置为 null 就不会更新了。忽略前端的传参 | |
| 186 | 168 | if (updateReqVO.getDeviceName() != null && !updateReqVO.getDeviceName().equals(existingDevice.getDeviceName())) { |
| 187 | 169 | throw exception(DEVICE_NAME_CANNOT_BE_MODIFIED); |
| 188 | 170 | } |
| ... | ... | @@ -200,18 +182,14 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 200 | 182 | @Override |
| 201 | 183 | @Transactional(rollbackFor = Exception.class) |
| 202 | 184 | public void deleteDevice(Long id) { |
| 203 | - // 校验存在 | |
| 204 | - IotDeviceDO iotDeviceDO = validateDeviceExists(id); | |
| 205 | - | |
| 206 | - // 如果是网关设备,检查是否有子设备 | |
| 207 | - if (iotDeviceDO.getGatewayId() != null) { | |
| 208 | - long childCount = deviceMapper.selectCountByGatewayId(id); | |
| 209 | - if (childCount > 0) { | |
| 210 | - throw exception(DEVICE_HAS_CHILDREN); | |
| 211 | - } | |
| 185 | + // 1.1 校验存在 | |
| 186 | + IotDeviceDO device = validateDeviceExists(id); | |
| 187 | + // 1.2 如果是网关设备,检查是否有子设备 | |
| 188 | + if (device.getGatewayId() != null && deviceMapper.selectCountByGatewayId(id) > 0) { | |
| 189 | + throw exception(DEVICE_HAS_CHILDREN); | |
| 212 | 190 | } |
| 213 | 191 | |
| 214 | - // 删除设备 | |
| 192 | + // 2. 删除设备 | |
| 215 | 193 | deviceMapper.deleteById(id); |
| 216 | 194 | } |
| 217 | 195 | |
| ... | ... | @@ -222,11 +200,11 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 222 | 200 | * @return 设备对象 |
| 223 | 201 | */ |
| 224 | 202 | private IotDeviceDO validateDeviceExists(Long id) { |
| 225 | - IotDeviceDO iotDeviceDO = deviceMapper.selectById(id); | |
| 226 | - if (iotDeviceDO == null) { | |
| 203 | + IotDeviceDO device = deviceMapper.selectById(id); | |
| 204 | + if (device == null) { | |
| 227 | 205 | throw exception(DEVICE_NOT_EXISTS); |
| 228 | 206 | } |
| 229 | - return iotDeviceDO; | |
| 207 | + return device; | |
| 230 | 208 | } |
| 231 | 209 | |
| 232 | 210 | @Override |
| ... | ... | @@ -244,21 +222,20 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 244 | 222 | } |
| 245 | 223 | |
| 246 | 224 | @Override |
| 247 | - @Transactional(rollbackFor = Exception.class) | |
| 248 | 225 | public void updateDeviceStatus(Long id, Integer status) { |
| 249 | 226 | // 校验存在 |
| 250 | 227 | validateDeviceExists(id); |
| 251 | 228 | |
| 229 | + // TODO @haohao:这个可以直接用 swagger 注解哈 | |
| 252 | 230 | // 校验状态是否合法 |
| 253 | 231 | if (!IotDeviceStatusEnum.isValidStatus(status)) { |
| 254 | 232 | throw exception(DEVICE_INVALID_DEVICE_STATUS); |
| 255 | 233 | } |
| 256 | 234 | |
| 257 | 235 | // 更新状态和更新时间 |
| 258 | - IotDeviceDO updateObj = new IotDeviceDO() | |
| 259 | - .setId(id) | |
| 260 | - .setStatus(status) | |
| 236 | + IotDeviceDO updateObj = new IotDeviceDO().setId(id).setStatus(status) | |
| 261 | 237 | .setStatusLastUpdateTime(LocalDateTime.now()); |
| 262 | 238 | deviceMapper.updateById(updateObj); |
| 263 | 239 | } |
| 240 | + | |
| 264 | 241 | } |
| 265 | 242 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
| ... | ... | @@ -13,7 +13,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 13 | 13 | public interface IotDeviceService { |
| 14 | 14 | |
| 15 | 15 | /** |
| 16 | - * 创建IoT 设备 | |
| 16 | + * 创建设备 | |
| 17 | 17 | * |
| 18 | 18 | * @param createReqVO 创建信息 |
| 19 | 19 | * @return 编号 |
| ... | ... | @@ -21,21 +21,21 @@ public interface IotDeviceService { |
| 21 | 21 | Long createDevice(@Valid IotDeviceSaveReqVO createReqVO); |
| 22 | 22 | |
| 23 | 23 | /** |
| 24 | - * 更新IoT 设备 | |
| 24 | + * 更新设备 | |
| 25 | 25 | * |
| 26 | 26 | * @param updateReqVO 更新信息 |
| 27 | 27 | */ |
| 28 | 28 | void updateDevice(@Valid IotDeviceSaveReqVO updateReqVO); |
| 29 | 29 | |
| 30 | 30 | /** |
| 31 | - * 删除IoT 设备 | |
| 31 | + * 删除设备 | |
| 32 | 32 | * |
| 33 | 33 | * @param id 编号 |
| 34 | 34 | */ |
| 35 | 35 | void deleteDevice(Long id); |
| 36 | 36 | |
| 37 | 37 | /** |
| 38 | - * 获得IoT 设备 | |
| 38 | + * 获得设备 | |
| 39 | 39 | * |
| 40 | 40 | * @param id 编号 |
| 41 | 41 | * @return IoT 设备 |
| ... | ... | @@ -43,7 +43,7 @@ public interface IotDeviceService { |
| 43 | 43 | IotDeviceDO getDevice(Long id); |
| 44 | 44 | |
| 45 | 45 | /** |
| 46 | - * 获得IoT 设备分页 | |
| 46 | + * 获得设备分页 | |
| 47 | 47 | * |
| 48 | 48 | * @param pageReqVO 分页查询 |
| 49 | 49 | * @return IoT 设备分页 |
| ... | ... | @@ -51,10 +51,11 @@ public interface IotDeviceService { |
| 51 | 51 | PageResult<IotDeviceDO> getDevicePage(IotDevicePageReqVO pageReqVO); |
| 52 | 52 | |
| 53 | 53 | /** |
| 54 | - * 更新IoT 设备状态 | |
| 54 | + * 更新设备状态 | |
| 55 | 55 | * |
| 56 | 56 | * @param id 编号 |
| 57 | 57 | * @param status 状态 |
| 58 | 58 | */ |
| 59 | 59 | void updateDeviceStatus(Long id, Integer status); |
| 60 | + | |
| 60 | 61 | } |
| 61 | 62 | \ 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
| ... | ... | @@ -170,7 +170,6 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe |
| 170 | 170 | |
| 171 | 171 | // 3.1 使用 diffList 方法比较新旧列表 |
| 172 | 172 | List<List<IotThinkModelFunctionDO>> diffResult = diffList(oldFunctionList, newFunctionList, |
| 173 | - // TODO @haohao:是不是用 id 比较相同就 ok 哈。如果可以的化,下面的 update 可以更简单 | |
| 174 | 173 | // 继续使用 identifier 和 type 进行比较:这样可以准确地匹配对应的功能对象。 |
| 175 | 174 | (oldFunc, newFunc) -> Objects.equals(oldFunc.getIdentifier(), newFunc.getIdentifier()) |
| 176 | 175 | && Objects.equals(oldFunc.getType(), newFunc.getType())); |
| ... | ... | @@ -191,6 +190,7 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe |
| 191 | 190 | thinkModelFunctionMapper.updateById(updateFunc); |
| 192 | 191 | } |
| 193 | 192 | } |
| 193 | + // TODO @haohao:seckillProductMapper.updateBatch(diffList.get(1)); 可以直接类似这么操作哇? | |
| 194 | 194 | } |
| 195 | 195 | if (CollUtil.isNotEmpty(deleteList)) { |
| 196 | 196 | Set<Long> idsToDelete = CollectionUtils.convertSet(deleteList, IotThinkModelFunctionDO::getId); | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDeviceMapper.xml deleted
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
| 3 | -<mapper namespace="cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper"> | |
| 4 | - | |
| 5 | - <!-- | |
| 6 | - 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。 | |
| 7 | - 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。 | |
| 8 | - 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。 | |
| 9 | - 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ | |
| 10 | - --> | |
| 11 | - | |
| 12 | -</mapper> | |
| 13 | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/thinkmodelfunction/IotThinkModelFunctionMapper.xml deleted
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
| 3 | -<mapper namespace="cn.iocoder.yudao.module.iot.dal.mysql.thinkmodelfunction.IotThinkModelFunctionMapper"> | |
| 4 | - | |
| 5 | - <!-- | |
| 6 | - 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。 | |
| 7 | - 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。 | |
| 8 | - 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。 | |
| 9 | - 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ | |
| 10 | - --> | |
| 11 | - | |
| 12 | -</mapper> | |
| 13 | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImplTest.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.service.device; | |
| 2 | - | |
| 3 | -import org.junit.jupiter.api.Disabled; | |
| 4 | -import org.junit.jupiter.api.Test; | |
| 5 | - | |
| 6 | -import jakarta.annotation.Resource; | |
| 7 | - | |
| 8 | -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 9 | - | |
| 10 | -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.*; | |
| 11 | -import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | |
| 12 | -import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper; | |
| 13 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 14 | - | |
| 15 | -import org.springframework.context.annotation.Import; | |
| 16 | - | |
| 17 | -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; | |
| 18 | -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; | |
| 19 | -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | |
| 20 | -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; | |
| 21 | -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; | |
| 22 | -import static org.junit.jupiter.api.Assertions.*; | |
| 23 | - | |
| 24 | -/** | |
| 25 | - * {@link DeviceServiceImpl} 的单元测试类 | |
| 26 | - * | |
| 27 | - * @author 芋道源码 | |
| 28 | - */ | |
| 29 | -@Import(DeviceServiceImpl.class) | |
| 30 | -public class DeviceServiceImplTest extends BaseDbUnitTest { | |
| 31 | - | |
| 32 | - @Resource | |
| 33 | - private DeviceServiceImpl deviceService; | |
| 34 | - | |
| 35 | - @Resource | |
| 36 | - private IotDeviceMapper deviceMapper; | |
| 37 | - | |
| 38 | - @Test | |
| 39 | - public void testCreateDevice_success() { | |
| 40 | - // 准备参数 | |
| 41 | - IotDeviceSaveReqVO createReqVO = randomPojo(IotDeviceSaveReqVO.class).setId(null); | |
| 42 | - | |
| 43 | - // 调用 | |
| 44 | - Long deviceId = deviceService.createDevice(createReqVO); | |
| 45 | - // 断言 | |
| 46 | - assertNotNull(deviceId); | |
| 47 | - // 校验记录的属性是否正确 | |
| 48 | - IotDeviceDO device = deviceMapper.selectById(deviceId); | |
| 49 | - assertPojoEquals(createReqVO, device, "id"); | |
| 50 | - } | |
| 51 | - | |
| 52 | - @Test | |
| 53 | - public void testUpdateDevice_success() { | |
| 54 | - // mock 数据 | |
| 55 | - IotDeviceDO dbDevice = randomPojo(IotDeviceDO.class); | |
| 56 | - deviceMapper.insert(dbDevice);// @Sql: 先插入出一条存在的数据 | |
| 57 | - // 准备参数 | |
| 58 | - IotDeviceSaveReqVO updateReqVO = randomPojo(IotDeviceSaveReqVO.class, o -> { | |
| 59 | - o.setId(dbDevice.getId()); // 设置更新的 ID | |
| 60 | - }); | |
| 61 | - | |
| 62 | - // 调用 | |
| 63 | - deviceService.updateDevice(updateReqVO); | |
| 64 | - // 校验是否更新正确 | |
| 65 | - IotDeviceDO device = deviceMapper.selectById(updateReqVO.getId()); // 获取最新的 | |
| 66 | - assertPojoEquals(updateReqVO, device); | |
| 67 | - } | |
| 68 | - | |
| 69 | - @Test | |
| 70 | - public void testUpdateDevice_notExists() { | |
| 71 | - // 准备参数 | |
| 72 | - IotDeviceSaveReqVO updateReqVO = randomPojo(IotDeviceSaveReqVO.class); | |
| 73 | - | |
| 74 | - // 调用, 并断言异常 | |
| 75 | - assertServiceException(() -> deviceService.updateDevice(updateReqVO), DEVICE_NOT_EXISTS); | |
| 76 | - } | |
| 77 | - | |
| 78 | - @Test | |
| 79 | - public void testDeleteDevice_success() { | |
| 80 | - // mock 数据 | |
| 81 | - IotDeviceDO dbDevice = randomPojo(IotDeviceDO.class); | |
| 82 | - deviceMapper.insert(dbDevice);// @Sql: 先插入出一条存在的数据 | |
| 83 | - // 准备参数 | |
| 84 | - Long id = dbDevice.getId(); | |
| 85 | - | |
| 86 | - // 调用 | |
| 87 | - deviceService.deleteDevice(id); | |
| 88 | - // 校验数据不存在了 | |
| 89 | - assertNull(deviceMapper.selectById(id)); | |
| 90 | - } | |
| 91 | - | |
| 92 | - @Test | |
| 93 | - public void testDeleteDevice_notExists() { | |
| 94 | - // 准备参数 | |
| 95 | - Long id = randomLongId(); | |
| 96 | - | |
| 97 | - // 调用, 并断言异常 | |
| 98 | - assertServiceException(() -> deviceService.deleteDevice(id), DEVICE_NOT_EXISTS); | |
| 99 | - } | |
| 100 | - | |
| 101 | - @Test | |
| 102 | - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 | |
| 103 | - public void testGetDevicePage() { | |
| 104 | - // mock 数据 | |
| 105 | - IotDeviceDO dbDevice = randomPojo(IotDeviceDO.class, o -> { // 等会查询到 | |
| 106 | - o.setDeviceKey(null); | |
| 107 | - o.setDeviceName(null); | |
| 108 | - o.setProductId(null); | |
| 109 | - o.setProductKey(null); | |
| 110 | - o.setDeviceType(null); | |
| 111 | - o.setNickname(null); | |
| 112 | - o.setGatewayId(null); | |
| 113 | - o.setStatus(null); | |
| 114 | - o.setStatusLastUpdateTime(null); | |
| 115 | - o.setLastOnlineTime(null); | |
| 116 | - o.setLastOfflineTime(null); | |
| 117 | - o.setActiveTime(null); | |
| 118 | - o.setIp(null); | |
| 119 | - o.setFirmwareVersion(null); | |
| 120 | - o.setDeviceSecret(null); | |
| 121 | - o.setMqttClientId(null); | |
| 122 | - o.setMqttUsername(null); | |
| 123 | - o.setMqttPassword(null); | |
| 124 | - o.setAuthType(null); | |
| 125 | - o.setLatitude(null); | |
| 126 | - o.setLongitude(null); | |
| 127 | - o.setAreaId(null); | |
| 128 | - o.setAddress(null); | |
| 129 | - o.setSerialNumber(null); | |
| 130 | - o.setCreateTime(null); | |
| 131 | - }); | |
| 132 | - deviceMapper.insert(dbDevice); | |
| 133 | - // 测试 deviceKey 不匹配 | |
| 134 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setDeviceKey(null))); | |
| 135 | - // 测试 deviceName 不匹配 | |
| 136 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setDeviceName(null))); | |
| 137 | - // 测试 productId 不匹配 | |
| 138 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setProductId(null))); | |
| 139 | - // 测试 productKey 不匹配 | |
| 140 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setProductKey(null))); | |
| 141 | - // 测试 deviceType 不匹配 | |
| 142 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setDeviceType(null))); | |
| 143 | - // 测试 nickname 不匹配 | |
| 144 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setNickname(null))); | |
| 145 | - // 测试 gatewayId 不匹配 | |
| 146 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setGatewayId(null))); | |
| 147 | - // 测试 status 不匹配 | |
| 148 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setStatus(null))); | |
| 149 | - // 测试 statusLastUpdateTime 不匹配 | |
| 150 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setStatusLastUpdateTime(null))); | |
| 151 | - // 测试 lastOnlineTime 不匹配 | |
| 152 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setLastOnlineTime(null))); | |
| 153 | - // 测试 lastOfflineTime 不匹配 | |
| 154 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setLastOfflineTime(null))); | |
| 155 | - // 测试 activeTime 不匹配 | |
| 156 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setActiveTime(null))); | |
| 157 | - // 测试 ip 不匹配 | |
| 158 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setIp(null))); | |
| 159 | - // 测试 firmwareVersion 不匹配 | |
| 160 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setFirmwareVersion(null))); | |
| 161 | - // 测试 deviceSecret 不匹配 | |
| 162 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setDeviceSecret(null))); | |
| 163 | - // 测试 mqttClientId 不匹配 | |
| 164 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setMqttClientId(null))); | |
| 165 | - // 测试 mqttUsername 不匹配 | |
| 166 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setMqttUsername(null))); | |
| 167 | - // 测试 mqttPassword 不匹配 | |
| 168 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setMqttPassword(null))); | |
| 169 | - // 测试 authType 不匹配 | |
| 170 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setAuthType(null))); | |
| 171 | - // 测试 latitude 不匹配 | |
| 172 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setLatitude(null))); | |
| 173 | - // 测试 longitude 不匹配 | |
| 174 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setLongitude(null))); | |
| 175 | - // 测试 areaId 不匹配 | |
| 176 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setAreaId(null))); | |
| 177 | - // 测试 address 不匹配 | |
| 178 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setAddress(null))); | |
| 179 | - // 测试 serialNumber 不匹配 | |
| 180 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setSerialNumber(null))); | |
| 181 | - // 测试 createTime 不匹配 | |
| 182 | - deviceMapper.insert(cloneIgnoreId(dbDevice, o -> o.setCreateTime(null))); | |
| 183 | - // 准备参数 | |
| 184 | - IotDevicePageReqVO reqVO = new IotDevicePageReqVO(); | |
| 185 | - reqVO.setDeviceKey(null); | |
| 186 | - reqVO.setDeviceName(null); | |
| 187 | - reqVO.setProductId(null); | |
| 188 | - reqVO.setProductKey(null); | |
| 189 | - reqVO.setDeviceType(null); | |
| 190 | - reqVO.setNickname(null); | |
| 191 | - reqVO.setGatewayId(null); | |
| 192 | - reqVO.setStatus(null); | |
| 193 | - reqVO.setStatusLastUpdateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); | |
| 194 | - reqVO.setLastOnlineTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); | |
| 195 | - reqVO.setLastOfflineTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); | |
| 196 | - reqVO.setActiveTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); | |
| 197 | - reqVO.setIp(null); | |
| 198 | - reqVO.setFirmwareVersion(null); | |
| 199 | - reqVO.setDeviceSecret(null); | |
| 200 | - reqVO.setMqttClientId(null); | |
| 201 | - reqVO.setMqttUsername(null); | |
| 202 | - reqVO.setMqttPassword(null); | |
| 203 | - reqVO.setAuthType(null); | |
| 204 | - reqVO.setLatitude(null); | |
| 205 | - reqVO.setLongitude(null); | |
| 206 | - reqVO.setAreaId(null); | |
| 207 | - reqVO.setAddress(null); | |
| 208 | - reqVO.setSerialNumber(null); | |
| 209 | - reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); | |
| 210 | - | |
| 211 | - // 调用 | |
| 212 | - PageResult<IotDeviceDO> pageResult = deviceService.getDevicePage(reqVO); | |
| 213 | - // 断言 | |
| 214 | - assertEquals(1, pageResult.getTotal()); | |
| 215 | - assertEquals(1, pageResult.getList().size()); | |
| 216 | - assertPojoEquals(dbDevice, pageResult.getList().get(0)); | |
| 217 | - } | |
| 218 | - | |
| 219 | -} | |
| 220 | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/thinkmodelfunction/IotThinkModelFunctionServiceImplTest.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.service.thinkmodelfunction; | |
| 2 | - | |
| 3 | -import org.junit.jupiter.api.Test; | |
| 4 | - | |
| 5 | -import jakarta.annotation.Resource; | |
| 6 | - | |
| 7 | -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 8 | - | |
| 9 | -import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.*; | |
| 10 | -import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; | |
| 11 | -import cn.iocoder.yudao.module.iot.dal.mysql.thinkmodelfunction.IotThinkModelFunctionMapper; | |
| 12 | - | |
| 13 | -import org.springframework.context.annotation.Import; | |
| 14 | - | |
| 15 | -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; | |
| 16 | -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; | |
| 17 | -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | |
| 18 | -import static org.junit.jupiter.api.Assertions.*; | |
| 19 | - | |
| 20 | -/** | |
| 21 | - * {@link IotThinkModelFunctionServiceImpl} 的单元测试类 | |
| 22 | - * | |
| 23 | - * @author 芋道源码 | |
| 24 | - */ | |
| 25 | -@Import(IotThinkModelFunctionServiceImpl.class) | |
| 26 | -public class IotThinkModelFunctionServiceImplTest extends BaseDbUnitTest { | |
| 27 | - | |
| 28 | - @Resource | |
| 29 | - private IotThinkModelFunctionServiceImpl thinkModelFunctionService; | |
| 30 | - | |
| 31 | - @Resource | |
| 32 | - private IotThinkModelFunctionMapper thinkModelFunctionMapper; | |
| 33 | - | |
| 34 | - @Test | |
| 35 | - public void testCreateThinkModelFunction_success() { | |
| 36 | - // 准备参数 | |
| 37 | - IotThinkModelFunctionSaveReqVO createReqVO = randomPojo(IotThinkModelFunctionSaveReqVO.class); | |
| 38 | - | |
| 39 | - // 调用 | |
| 40 | - Long thinkModelFunctionId = thinkModelFunctionService.createThinkModelFunction(createReqVO); | |
| 41 | - // 断言 | |
| 42 | - assertNotNull(thinkModelFunctionId); | |
| 43 | - // 校验记录的属性是否正确 | |
| 44 | - IotThinkModelFunctionDO thinkModelFunction = thinkModelFunctionMapper.selectById(thinkModelFunctionId); | |
| 45 | - assertPojoEquals(createReqVO, thinkModelFunction, "id"); | |
| 46 | - } | |
| 47 | - | |
| 48 | - @Test | |
| 49 | - public void testDeleteThinkModelFunction_success() { | |
| 50 | - // mock 数据 | |
| 51 | - IotThinkModelFunctionDO dbThinkModelFunction = randomPojo(IotThinkModelFunctionDO.class); | |
| 52 | - thinkModelFunctionMapper.insert(dbThinkModelFunction);// @Sql: 先插入出一条存在的数据 | |
| 53 | - // 准备参数 | |
| 54 | - Long id = dbThinkModelFunction.getId(); | |
| 55 | - | |
| 56 | - // 调用 | |
| 57 | - thinkModelFunctionService.deleteThinkModelFunction(id); | |
| 58 | - // 校验数据不存在了 | |
| 59 | - assertNull(thinkModelFunctionMapper.selectById(id)); | |
| 60 | - } | |
| 61 | - | |
| 62 | - @Test | |
| 63 | - public void testDeleteThinkModelFunction_notExists() { | |
| 64 | - // 准备参数 | |
| 65 | - Long id = randomLongId(); | |
| 66 | - | |
| 67 | - // 调用, 并断言异常 | |
| 68 | - assertServiceException(() -> thinkModelFunctionService.deleteThinkModelFunction(id), THINK_MODEL_FUNCTION_NOT_EXISTS); | |
| 69 | - } | |
| 70 | - | |
| 71 | -} | |
| 72 | 0 | \ No newline at end of file |