Commit 643e28938458a740b5975f99992533c0c10d70e0

Authored by 安浩浩
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,6 +9,7 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
9 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO; 9 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO;
10 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceRespVO; 10 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceRespVO;
11 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO; 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 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; 13 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
13 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; 14 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
14 import io.swagger.v3.oas.annotations.Operation; 15 import io.swagger.v3.oas.annotations.Operation;
@@ -45,12 +46,9 @@ public class IotDeviceController { @@ -45,12 +46,9 @@ public class IotDeviceController {
45 46
46 @PutMapping("/update-status") 47 @PutMapping("/update-status")
47 @Operation(summary = "更新设备状态") 48 @Operation(summary = "更新设备状态")
48 - @Parameter(name = "id", description = "编号", required = true)  
49 - @Parameter(name = "status", description = "状态", required = true, example = "1")  
50 @PreAuthorize("@ss.hasPermission('iot:device:update')") 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 return success(true); 52 return success(true);
55 } 53 }
56 54
@@ -88,17 +86,4 @@ public class IotDeviceController { @@ -88,17 +86,4 @@ public class IotDeviceController {
88 return success(BeanUtils.toBean(pageResult, IotDeviceRespVO.class)); 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 \ No newline at end of file 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,6 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import cn.iocoder.yudao.framework.common.validation.InEnum; 4 import cn.iocoder.yudao.framework.common.validation.InEnum;
5 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; 5 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
  6 +import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum;
6 import io.swagger.v3.oas.annotations.media.Schema; 7 import io.swagger.v3.oas.annotations.media.Schema;
7 import lombok.Data; 8 import lombok.Data;
8 import lombok.EqualsAndHashCode; 9 import lombok.EqualsAndHashCode;
@@ -28,6 +29,9 @@ public class IotDevicePageReqVO extends PageParam { @@ -28,6 +29,9 @@ public class IotDevicePageReqVO extends PageParam {
28 @Schema(description = "设备名称", example = "王五") 29 @Schema(description = "设备名称", example = "王五")
29 private String deviceName; 30 private String deviceName;
30 31
  32 + @Schema(description = "备注名称", example = "张三")
  33 + private String nickname;
  34 +
31 @Schema(description = "产品编号", example = "26202") 35 @Schema(description = "产品编号", example = "26202")
32 private Long productId; 36 private Long productId;
33 37
@@ -35,12 +39,9 @@ public class IotDevicePageReqVO extends PageParam { @@ -35,12 +39,9 @@ public class IotDevicePageReqVO extends PageParam {
35 private String productKey; 39 private String productKey;
36 40
37 @Schema(description = "设备类型", example = "1") 41 @Schema(description = "设备类型", example = "1")
38 - // TODO @haohao:需要有个设备类型的枚举 42 + @InEnum(IotProductDeviceTypeEnum.class)
39 private Integer deviceType; 43 private Integer deviceType;
40 44
41 - @Schema(description = "备注名称", example = "张三")  
42 - private String nickname;  
43 -  
44 @Schema(description = "网关设备 ID", example = "16380") 45 @Schema(description = "网关设备 ID", example = "16380")
45 private Long gatewayId; 46 private Long gatewayId;
46 47
@@ -64,12 +65,6 @@ public class IotDevicePageReqVO extends PageParam { @@ -64,12 +65,6 @@ public class IotDevicePageReqVO extends PageParam {
64 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 65 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
65 private LocalDateTime[] activeTime; 66 private LocalDateTime[] activeTime;
66 67
67 - @Schema(description = "设备的 IP 地址")  
68 - private String ip;  
69 -  
70 - @Schema(description = "设备的固件版本")  
71 - private String firmwareVersion;  
72 -  
73 @Schema(description = "设备密钥,用于设备认证,需安全存储") 68 @Schema(description = "设备密钥,用于设备认证,需安全存储")
74 private String deviceSecret; 69 private String deviceSecret;
75 70
@@ -85,21 +80,6 @@ public class IotDevicePageReqVO extends PageParam { @@ -85,21 +80,6 @@ public class IotDevicePageReqVO extends PageParam {
85 @Schema(description = "认证类型(如一机一密、动态注册)", example = "2") 80 @Schema(description = "认证类型(如一机一密、动态注册)", example = "2")
86 private String authType; 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 @Schema(description = "创建时间") 83 @Schema(description = "创建时间")
104 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 84 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
105 private LocalDateTime[] createTime; 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,7 +25,7 @@ public class IotDeviceRespVO {
25 private String deviceName; 25 private String deviceName;
26 26
27 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202") 27 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26202")
28 - @ExcelProperty("产品 ID") 28 + @ExcelProperty("产品编号")
29 private Long productId; 29 private Long productId;
30 30
31 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) 31 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED)
@@ -41,7 +41,6 @@ public class IotDeviceRespVO { @@ -41,7 +41,6 @@ public class IotDeviceRespVO {
41 private String nickname; 41 private String nickname;
42 42
43 @Schema(description = "网关设备 ID", example = "16380") 43 @Schema(description = "网关设备 ID", example = "16380")
44 - @ExcelProperty("网关设备 ID")  
45 private Long gatewayId; 44 private Long gatewayId;
46 45
47 @Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 46 @Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@@ -64,14 +63,6 @@ public class IotDeviceRespVO { @@ -64,14 +63,6 @@ public class IotDeviceRespVO {
64 @ExcelProperty("设备激活时间") 63 @ExcelProperty("设备激活时间")
65 private LocalDateTime activeTime; 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 @Schema(description = "设备密钥,用于设备认证") 66 @Schema(description = "设备密钥,用于设备认证")
76 @ExcelProperty("设备密钥") 67 @ExcelProperty("设备密钥")
77 private String deviceSecret; 68 private String deviceSecret;
@@ -92,27 +83,6 @@ public class IotDeviceRespVO { @@ -92,27 +83,6 @@ public class IotDeviceRespVO {
92 @ExcelProperty("认证类型(如一机一密、动态注册)") 83 @ExcelProperty("认证类型(如一机一密、动态注册)")
93 private String authType; 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 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 86 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
117 @ExcelProperty("创建时间") 87 @ExcelProperty("创建时间")
118 private LocalDateTime createTime; 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 +6,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductPageReqVO; 6 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductPageReqVO;
7 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductRespVO; 7 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductRespVO;
8 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductSaveReqVO; 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 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; 10 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
10 import cn.iocoder.yudao.module.iot.service.product.IotProductService; 11 import cn.iocoder.yudao.module.iot.service.product.IotProductService;
11 import io.swagger.v3.oas.annotations.Operation; 12 import io.swagger.v3.oas.annotations.Operation;
@@ -17,6 +18,8 @@ import org.springframework.security.access.prepost.PreAuthorize; @@ -17,6 +18,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
17 import org.springframework.validation.annotation.Validated; 18 import org.springframework.validation.annotation.Validated;
18 import org.springframework.web.bind.annotation.*; 19 import org.springframework.web.bind.annotation.*;
19 20
  21 +import java.util.List;
  22 +
20 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 23 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
21 24
22 @Tag(name = "管理后台 - IoT 产品") 25 @Tag(name = "管理后台 - IoT 产品")
@@ -80,4 +83,12 @@ public class IotProductController { @@ -80,4 +83,12 @@ public class IotProductController {
80 return success(BeanUtils.toBean(pageResult, IotProductRespVO.class)); 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 \ No newline at end of file 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 \ No newline at end of file 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,34 +50,34 @@ public class IotDeviceDO extends BaseDO {
50 50
51 /** 51 /**
52 * 产品编号 52 * 产品编号
53 - * 53 + * <p>
54 * 关联 {@link IotProductDO#getId()} 54 * 关联 {@link IotProductDO#getId()}
55 */ 55 */
56 private Long productId; 56 private Long productId;
57 /** 57 /**
58 * 产品标识 58 * 产品标识
59 - * 59 + * <p>
60 * 冗余 {@link IotProductDO#getProductKey()} 60 * 冗余 {@link IotProductDO#getProductKey()}
61 */ 61 */
62 private String productKey; 62 private String productKey;
63 /** 63 /**
64 * 设备类型 64 * 设备类型
65 - * 65 + * <p>
66 * 冗余 {@link IotProductDO#getDeviceType()} 66 * 冗余 {@link IotProductDO#getDeviceType()}
67 */ 67 */
68 private Integer deviceType; 68 private Integer deviceType;
69 69
70 /** 70 /**
71 * 设备状态 71 * 设备状态
72 - * 72 + * <p>
73 * 枚举 {@link IotDeviceStatusEnum} 73 * 枚举 {@link IotDeviceStatusEnum}
74 */ 74 */
75 private Integer status; 75 private Integer status;
76 /** 76 /**
77 * 网关设备编号 77 * 网关设备编号
78 - * 78 + * <p>
79 * 子设备需要关联的网关设备 ID 79 * 子设备需要关联的网关设备 ID
80 - * 80 + * <p>
81 * 关联 {@link IotDeviceDO#getId()} 81 * 关联 {@link IotDeviceDO#getId()}
82 */ 82 */
83 private Long gatewayId; 83 private Long gatewayId;
@@ -140,7 +140,7 @@ public class IotDeviceDO extends BaseDO { @@ -140,7 +140,7 @@ public class IotDeviceDO extends BaseDO {
140 private BigDecimal longitude; 140 private BigDecimal longitude;
141 /** 141 /**
142 * 地区编码 142 * 地区编码
143 - * 143 + * <p>
144 * 关联 Area 的 id 144 * 关联 Area 的 id
145 */ 145 */
146 private Integer areaId; 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&lt;IotDeviceDO&gt; { @@ -29,18 +29,11 @@ public interface IotDeviceMapper extends BaseMapperX&lt;IotDeviceDO&gt; {
29 .betweenIfPresent(IotDeviceDO::getLastOnlineTime, reqVO.getLastOnlineTime()) 29 .betweenIfPresent(IotDeviceDO::getLastOnlineTime, reqVO.getLastOnlineTime())
30 .betweenIfPresent(IotDeviceDO::getLastOfflineTime, reqVO.getLastOfflineTime()) 30 .betweenIfPresent(IotDeviceDO::getLastOfflineTime, reqVO.getLastOfflineTime())
31 .betweenIfPresent(IotDeviceDO::getActiveTime, reqVO.getActiveTime()) 31 .betweenIfPresent(IotDeviceDO::getActiveTime, reqVO.getActiveTime())
32 - .eqIfPresent(IotDeviceDO::getIp, reqVO.getIp())  
33 - .eqIfPresent(IotDeviceDO::getFirmwareVersion, reqVO.getFirmwareVersion())  
34 .eqIfPresent(IotDeviceDO::getDeviceSecret, reqVO.getDeviceSecret()) 32 .eqIfPresent(IotDeviceDO::getDeviceSecret, reqVO.getDeviceSecret())
35 .eqIfPresent(IotDeviceDO::getMqttClientId, reqVO.getMqttClientId()) 33 .eqIfPresent(IotDeviceDO::getMqttClientId, reqVO.getMqttClientId())
36 .likeIfPresent(IotDeviceDO::getMqttUsername, reqVO.getMqttUsername()) 34 .likeIfPresent(IotDeviceDO::getMqttUsername, reqVO.getMqttUsername())
37 .eqIfPresent(IotDeviceDO::getMqttPassword, reqVO.getMqttPassword()) 35 .eqIfPresent(IotDeviceDO::getMqttPassword, reqVO.getMqttPassword())
38 .eqIfPresent(IotDeviceDO::getAuthType, reqVO.getAuthType()) 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 .betweenIfPresent(IotDeviceDO::getCreateTime, reqVO.getCreateTime()) 37 .betweenIfPresent(IotDeviceDO::getCreateTime, reqVO.getCreateTime())
45 .orderByDesc(IotDeviceDO::getId)); 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&lt;IotProductDO&gt; { @@ -25,4 +25,5 @@ public interface IotProductMapper extends BaseMapperX&lt;IotProductDO&gt; {
25 default IotProductDO selectByProductKey(String productKey) { 25 default IotProductDO selectByProductKey(String productKey) {
26 return selectOne(new LambdaQueryWrapperX<IotProductDO>().eq(IotProductDO::getProductKey, productKey)); 26 return selectOne(new LambdaQueryWrapperX<IotProductDO>().eq(IotProductDO::getProductKey, productKey));
27 } 27 }
  28 +
28 } 29 }
29 \ No newline at end of file 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,11 +6,12 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO; 7 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO;
8 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO; 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 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; 10 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
10 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; 11 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
11 import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper; 12 import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper;
12 -import cn.iocoder.yudao.module.iot.dal.mysql.product.IotProductMapper;  
13 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; 13 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum;
  14 +import cn.iocoder.yudao.module.iot.service.product.IotProductService;
14 import jakarta.annotation.Resource; 15 import jakarta.annotation.Resource;
15 import lombok.extern.slf4j.Slf4j; 16 import lombok.extern.slf4j.Slf4j;
16 import org.springframework.stereotype.Service; 17 import org.springframework.stereotype.Service;
@@ -35,9 +36,8 @@ public class DeviceServiceImpl implements IotDeviceService { @@ -35,9 +36,8 @@ public class DeviceServiceImpl implements IotDeviceService {
35 36
36 @Resource 37 @Resource
37 private IotDeviceMapper deviceMapper; 38 private IotDeviceMapper deviceMapper;
38 - // TODO @haohao:不直接调用 productmapper,通过 productservice;每一个模型,不直接使用对方的  
39 @Resource 39 @Resource
40 - private IotProductMapper productMapper; 40 + private IotProductService productService;
41 41
42 /** 42 /**
43 * 创建 IoT 设备 43 * 创建 IoT 设备
@@ -49,7 +49,7 @@ public class DeviceServiceImpl implements IotDeviceService { @@ -49,7 +49,7 @@ public class DeviceServiceImpl implements IotDeviceService {
49 @Transactional(rollbackFor = Exception.class) 49 @Transactional(rollbackFor = Exception.class)
50 public Long createDevice(IotDeviceSaveReqVO createReqVO) { 50 public Long createDevice(IotDeviceSaveReqVO createReqVO) {
51 // 1.1 校验产品是否存在 51 // 1.1 校验产品是否存在
52 - IotProductDO product = productMapper.selectById(createReqVO.getProductId()); 52 + IotProductDO product = productService.getProduct(createReqVO.getProductId());
53 if (product == null) { 53 if (product == null) {
54 throw exception(PRODUCT_NOT_EXISTS); 54 throw exception(PRODUCT_NOT_EXISTS);
55 } 55 }
@@ -106,8 +106,7 @@ public class DeviceServiceImpl implements IotDeviceService { @@ -106,8 +106,7 @@ public class DeviceServiceImpl implements IotDeviceService {
106 * @return 生成的 deviceSecret 106 * @return 生成的 deviceSecret
107 */ 107 */
108 private String generateDeviceSecret() { 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,7 +146,6 @@ public class DeviceServiceImpl implements IotDeviceService {
147 * @return 生成的唯一 DeviceName 146 * @return 生成的唯一 DeviceName
148 */ 147 */
149 private String generateUniqueDeviceName(String productKey) { 148 private String generateUniqueDeviceName(String productKey) {
150 - // TODO @haohao:业务逻辑里,尽量避免 while true。万一 bug = =;虽然这个不会哈。我先改了下  
151 for (int i = 0; i < Short.MAX_VALUE; i++) { 149 for (int i = 0; i < Short.MAX_VALUE; i++) {
152 String deviceName = IdUtil.fastSimpleUUID().substring(0, 20); 150 String deviceName = IdUtil.fastSimpleUUID().substring(0, 20);
153 if (deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName) != null) { 151 if (deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName) != null) {
@@ -161,16 +159,11 @@ public class DeviceServiceImpl implements IotDeviceService { @@ -161,16 +159,11 @@ public class DeviceServiceImpl implements IotDeviceService {
161 @Transactional(rollbackFor = Exception.class) 159 @Transactional(rollbackFor = Exception.class)
162 public void updateDevice(IotDeviceSaveReqVO updateReqVO) { 160 public void updateDevice(IotDeviceSaveReqVO updateReqVO) {
163 // 校验存在 161 // 校验存在
164 - IotDeviceDO existingDevice = validateDeviceExists(updateReqVO.getId()); 162 + validateDeviceExists(updateReqVO.getId());
165 163
166 // 设备名称 和 产品 ID 不能修改 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 // 更新 DO 对象 168 // 更新 DO 对象
176 IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class); 169 IotDeviceDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceDO.class);
@@ -222,19 +215,12 @@ public class DeviceServiceImpl implements IotDeviceService { @@ -222,19 +215,12 @@ public class DeviceServiceImpl implements IotDeviceService {
222 } 215 }
223 216
224 @Override 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 deviceMapper.updateById(updateObj); 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,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 \ No newline at end of file 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 +6,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.product.vo.IotProductSaveReq
6 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; 6 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
7 import jakarta.validation.Valid; 7 import jakarta.validation.Valid;
8 8
  9 +import java.util.List;
  10 +
9 /** 11 /**
10 * IoT 产品 Service 接口 12 * IoT 产品 Service 接口
11 * 13 *
@@ -58,4 +60,12 @@ public interface IotProductService { @@ -58,4 +60,12 @@ public interface IotProductService {
58 * @param status 状态 60 * @param status 状态
59 */ 61 */
60 void updateProductStatus(Long id, Integer status); 62 void updateProductStatus(Long id, Integer status);
  63 +
  64 + /**
  65 + * 获得所有产品
  66 + *
  67 + * @return 产品列表
  68 + */
  69 + List<IotProductDO> listAllProducts();
  70 +
61 } 71 }
62 \ No newline at end of file 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,6 +12,7 @@ import jakarta.annotation.Resource;
12 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
13 import org.springframework.validation.annotation.Validated; 13 import org.springframework.validation.annotation.Validated;
14 14
  15 +import java.util.List;
15 import java.util.Objects; 16 import java.util.Objects;
16 import java.util.UUID; 17 import java.util.UUID;
17 18
@@ -113,4 +114,9 @@ public class IotProductServiceImpl implements IotProductService { @@ -113,4 +114,9 @@ public class IotProductServiceImpl implements IotProductService {
113 productMapper.updateById(updateObj); 114 productMapper.updateById(updateObj);
114 } 115 }
115 116
  117 + @Override
  118 + public List<IotProductDO> listAllProducts() {
  119 + return productMapper.selectList();
  120 + }
  121 +
116 } 122 }
117 \ No newline at end of file 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,6 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
24 import org.springframework.validation.annotation.Validated; 24 import org.springframework.validation.annotation.Validated;
25 25
26 import java.util.*; 26 import java.util.*;
  27 +import java.util.stream.Collectors;
27 28
28 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
29 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList; 30 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
@@ -176,22 +177,33 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -176,22 +177,33 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
176 List<IotThinkModelFunctionDO> createList = diffResult.get(0); // 需要新增的 177 List<IotThinkModelFunctionDO> createList = diffResult.get(0); // 需要新增的
177 List<IotThinkModelFunctionDO> updateList = diffResult.get(1); // 需要更新的 178 List<IotThinkModelFunctionDO> updateList = diffResult.get(1); // 需要更新的
178 List<IotThinkModelFunctionDO> deleteList = diffResult.get(2); // 需要删除的 179 List<IotThinkModelFunctionDO> deleteList = diffResult.get(2); // 需要删除的
  180 +
179 // 3.2 批量执行数据库操作 181 // 3.2 批量执行数据库操作
  182 + // 新增数据库中的新事件和服务列表
180 if (CollUtil.isNotEmpty(createList)) { 183 if (CollUtil.isNotEmpty(createList)) {
181 thinkModelFunctionMapper.insertBatch(createList); 184 thinkModelFunctionMapper.insertBatch(createList);
182 } 185 }
  186 + // 更新数据库中的事件和服务列表
183 if (CollUtil.isNotEmpty(updateList)) { 187 if (CollUtil.isNotEmpty(updateList)) {
184 - for (IotThinkModelFunctionDO updateFunc : updateList) {  
185 - // 设置 ID,以便更新 188 + // 首先,为每个需要更新的对象设置其对应的 ID
  189 + updateList.forEach(updateFunc -> {
186 IotThinkModelFunctionDO oldFunc = findFunctionByIdentifierAndType( 190 IotThinkModelFunctionDO oldFunc = findFunctionByIdentifierAndType(
187 oldFunctionList, updateFunc.getIdentifier(), updateFunc.getType()); 191 oldFunctionList, updateFunc.getIdentifier(), updateFunc.getType());
188 if (oldFunc != null) { 192 if (oldFunc != null) {
189 updateFunc.setId(oldFunc.getId()); 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 if (CollUtil.isNotEmpty(deleteList)) { 207 if (CollUtil.isNotEmpty(deleteList)) {
196 Set<Long> idsToDelete = CollectionUtils.convertSet(deleteList, IotThinkModelFunctionDO::getId); 208 Set<Long> idsToDelete = CollectionUtils.convertSet(deleteList, IotThinkModelFunctionDO::getId);
197 thinkModelFunctionMapper.deleteByIds(idsToDelete); 209 thinkModelFunctionMapper.deleteByIds(idsToDelete);