Commit 76ab64a255c311a354060eb2580f57a37aa29b7f

Authored by YunaiV
1 parent 0b16f167

【代码评审】IoT:物模型的管理

Showing 11 changed files with 42 additions and 83 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelEvent.java
@@ -5,6 +5,7 @@ import lombok.Data; @@ -5,6 +5,7 @@ import lombok.Data;
5 5
6 import java.util.List; 6 import java.util.List;
7 7
  8 +// TODO @puhui999:必要的参数校验
8 /** 9 /**
9 * 物模型中的事件 10 * 物模型中的事件
10 * 11 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelParam.java
@@ -6,6 +6,7 @@ import lombok.Data; @@ -6,6 +6,7 @@ import lombok.Data;
6 6
7 import java.util.List; 7 import java.util.List;
8 8
  9 +// TODO @puhui999:必要的参数校验
9 /** 10 /**
10 * IOT 产品物模型中的参数 11 * IOT 产品物模型中的参数
11 * 12 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelProperty.java
@@ -6,6 +6,7 @@ import lombok.Data; @@ -6,6 +6,7 @@ import lombok.Data;
6 6
7 import java.util.List; 7 import java.util.List;
8 8
  9 +// TODO @puhui999:必要的参数校验
9 /** 10 /**
10 * 物模型中的属性 11 * 物模型中的属性
11 * 12 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelRespVO.java deleted
1 -package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model;  
2 -  
3 -import lombok.*;  
4 -  
5 -import java.util.List;  
6 -  
7 -@Data  
8 -@Builder  
9 -@NoArgsConstructor  
10 -@AllArgsConstructor  
11 -@ToString  
12 -public class ThingModelRespVO {  
13 -  
14 - /**  
15 - * 产品编号  
16 - */  
17 - private Long id;  
18 -  
19 - /**  
20 - * 产品标识  
21 - */  
22 - private String productKey;  
23 -  
24 - /**  
25 - * 物模型  
26 - */  
27 - private Model model;  
28 -  
29 - /**  
30 - * 物模型  
31 - */  
32 - @Data  
33 - public static class Model {  
34 -  
35 - /**  
36 - * 属性列表  
37 - */  
38 - private List<ThingModelProperty> properties;  
39 -  
40 - /**  
41 - * 服务列表  
42 - */  
43 - private List<ThingModelService> services;  
44 -  
45 - /**  
46 - * 事件列表  
47 - */  
48 - private List<ThingModelEvent> events;  
49 - }  
50 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelService.java
@@ -5,6 +5,7 @@ import lombok.Data; @@ -5,6 +5,7 @@ import lombok.Data;
5 5
6 import java.util.List; 6 import java.util.List;
7 7
  8 +// TODO @puhui999:必要的参数校验
8 /** 9 /**
9 * 物模型中的服务 10 * 物模型中的服务
10 * 11 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelListReqVO.java
@@ -6,10 +6,15 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -6,10 +6,15 @@ import io.swagger.v3.oas.annotations.media.Schema;
6 import jakarta.validation.constraints.NotNull; 6 import jakarta.validation.constraints.NotNull;
7 import lombok.Data; 7 import lombok.Data;
8 8
9 -@Schema(description = "管理后台 - IoT 产品物模型List Request VO") 9 +// TODO @puhui999:部分字段,可以用 cursor 加上 example
  10 +@Schema(description = "管理后台 - IoT 产品物模型 List Request VO")
10 @Data 11 @Data
11 public class IotThingModelListReqVO { 12 public class IotThingModelListReqVO {
12 13
  14 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED)
  15 + @NotNull(message = "产品编号不能为空")
  16 + private Long productId;
  17 +
13 @Schema(description = "功能标识") 18 @Schema(description = "功能标识")
14 private String identifier; 19 private String identifier;
15 20
@@ -20,8 +25,4 @@ public class IotThingModelListReqVO { @@ -20,8 +25,4 @@ public class IotThingModelListReqVO {
20 @InEnum(IotThingModelTypeEnum.class) 25 @InEnum(IotThingModelTypeEnum.class)
21 private Integer type; 26 private Integer type;
22 27
23 - @Schema(description = "产品 ID", requiredMode = Schema.RequiredMode.REQUIRED)  
24 - @NotNull(message = "产品 ID 不能为空")  
25 - private Long productId;  
26 -  
27 } 28 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelPageReqVO.java
@@ -9,12 +9,17 @@ import lombok.Data; @@ -9,12 +9,17 @@ import lombok.Data;
9 import lombok.EqualsAndHashCode; 9 import lombok.EqualsAndHashCode;
10 import lombok.ToString; 10 import lombok.ToString;
11 11
  12 +// TODO @puhui999:部分字段,可以用 cursor 加上 example
12 @Schema(description = "管理后台 - IoT 产品物模型分页 Request VO") 13 @Schema(description = "管理后台 - IoT 产品物模型分页 Request VO")
13 @Data 14 @Data
14 @EqualsAndHashCode(callSuper = true) 15 @EqualsAndHashCode(callSuper = true)
15 @ToString(callSuper = true) 16 @ToString(callSuper = true)
16 public class IotThingModelPageReqVO extends PageParam { 17 public class IotThingModelPageReqVO extends PageParam {
17 18
  19 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + @NotNull(message = "产品编号不能为空")
  21 + private Long productId;
  22 +
18 @Schema(description = "功能标识") 23 @Schema(description = "功能标识")
19 private String identifier; 24 private String identifier;
20 25
@@ -25,8 +30,4 @@ public class IotThingModelPageReqVO extends PageParam { @@ -25,8 +30,4 @@ public class IotThingModelPageReqVO extends PageParam {
25 @InEnum(IotThingModelTypeEnum.class) 30 @InEnum(IotThingModelTypeEnum.class)
26 private Integer type; 31 private Integer type;
27 32
28 - @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED)  
29 - @NotNull(message = "产品ID不能为空")  
30 - private Long productId;  
31 -  
32 } 33 }
33 \ No newline at end of file 34 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelRespVO.java
@@ -10,6 +10,7 @@ import lombok.Data; @@ -10,6 +10,7 @@ import lombok.Data;
10 10
11 import java.time.LocalDateTime; 11 import java.time.LocalDateTime;
12 12
  13 +// TODO @puhui999:部分字段,可以用 cursor 加上 example
13 @Schema(description = "管理后台 - IoT 产品物模型 Response VO") 14 @Schema(description = "管理后台 - IoT 产品物模型 Response VO")
14 @Data 15 @Data
15 @ExcelIgnoreUnannotated 16 @ExcelIgnoreUnannotated
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelSaveReqVO.java
@@ -10,6 +10,7 @@ import jakarta.validation.constraints.NotEmpty; @@ -10,6 +10,7 @@ import jakarta.validation.constraints.NotEmpty;
10 import jakarta.validation.constraints.NotNull; 10 import jakarta.validation.constraints.NotNull;
11 import lombok.Data; 11 import lombok.Data;
12 12
  13 +// TODO @puhui999:部分字段,可以用 cursor 加上 example
13 @Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO") 14 @Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO")
14 @Data 15 @Data
15 public class IotThingModelSaveReqVO { 16 public class IotThingModelSaveReqVO {
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java
@@ -79,4 +79,5 @@ public interface IotThingModelService { @@ -79,4 +79,5 @@ public interface IotThingModelService {
79 * @return 产品物模型列表 79 * @return 产品物模型列表
80 */ 80 */
81 List<IotThingModelDO> getThingModelList(IotThingModelListReqVO reqVO); 81 List<IotThingModelDO> getThingModelList(IotThingModelListReqVO reqVO);
  82 +
82 } 83 }
83 \ No newline at end of file 84 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.service.thingmodel; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.service.thingmodel;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
  5 +import cn.hutool.core.util.StrUtil;
5 import cn.hutool.extra.spring.SpringUtil; 6 import cn.hutool.extra.spring.SpringUtil;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -54,29 +55,26 @@ public class IotThingModelServiceImpl implements IotThingModelService { @@ -54,29 +55,26 @@ public class IotThingModelServiceImpl implements IotThingModelService {
54 @Override 55 @Override
55 @Transactional(rollbackFor = Exception.class) 56 @Transactional(rollbackFor = Exception.class)
56 public Long createThingModel(IotThingModelSaveReqVO createReqVO) { 57 public Long createThingModel(IotThingModelSaveReqVO createReqVO) {
57 - // 1. 校验功能标识符在同一产品下是否唯一 58 + // 1.1 校验功能标识符在同一产品下是否唯一
58 validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier()); 59 validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier());
59 -  
60 - // 2. 功能名称在同一产品下是否唯一 60 + // 1.2 功能名称在同一产品下是否唯一
61 validateNameUnique(createReqVO.getProductId(), createReqVO.getName()); 61 validateNameUnique(createReqVO.getProductId(), createReqVO.getName());
62 -  
63 - // 3. 系统保留字段,不能用于标识符定义 62 + // 1.3 系统保留字段,不能用于标识符定义
64 validateNotDefaultEventAndService(createReqVO.getIdentifier()); 63 validateNotDefaultEventAndService(createReqVO.getIdentifier());
65 -  
66 - // 4. 校验产品状态,发布状态下,不允许新增功能 64 + // 1.4 校验产品状态,发布状态下,不允许新增功能
67 validateProductStatus(createReqVO.getProductId()); 65 validateProductStatus(createReqVO.getProductId());
68 66
69 - // 5. 插入数据库 67 + // 2. 插入数据库
70 IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(createReqVO); 68 IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(createReqVO);
71 thingModelMapper.insert(thingModel); 69 thingModelMapper.insert(thingModel);
72 70
73 - // 6. 如果创建的是属性,需要更新默认的事件和服务 71 + // 3. 如果创建的是属性,需要更新默认的事件和服务
74 if (Objects.equals(createReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { 72 if (Objects.equals(createReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
75 createDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey()); 73 createDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey());
76 } 74 }
77 // TODO @puhui999: 服务和事件的情况 method 怎么设置?在前端设置还是后端设置? 75 // TODO @puhui999: 服务和事件的情况 method 怎么设置?在前端设置还是后端设置?
78 76
79 - // 7. 删除缓存 77 + // 4. 删除缓存
80 deleteThingModelListCache(createReqVO.getProductKey()); 78 deleteThingModelListCache(createReqVO.getProductKey());
81 return thingModel.getId(); 79 return thingModel.getId();
82 } 80 }
@@ -84,38 +82,35 @@ public class IotThingModelServiceImpl implements IotThingModelService { @@ -84,38 +82,35 @@ public class IotThingModelServiceImpl implements IotThingModelService {
84 @Override 82 @Override
85 @Transactional(rollbackFor = Exception.class) 83 @Transactional(rollbackFor = Exception.class)
86 public void updateThingModel(IotThingModelSaveReqVO updateReqVO) { 84 public void updateThingModel(IotThingModelSaveReqVO updateReqVO) {
87 - // 1. 校验功能是否存在 85 + // 1.1 校验功能是否存在
88 validateProductThingModelMapperExists(updateReqVO.getId()); 86 validateProductThingModelMapperExists(updateReqVO.getId());
89 -  
90 - // 2. 校验功能标识符是否唯一 87 + // 1.2 校验功能标识符是否唯一
91 validateIdentifierUniqueForUpdate(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier()); 88 validateIdentifierUniqueForUpdate(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier());
92 -  
93 - // 3. 校验产品状态,发布状态下,不允许操作功能 89 + // 1.3 校验产品状态,发布状态下,不允许操作功能
94 validateProductStatus(updateReqVO.getProductId()); 90 validateProductStatus(updateReqVO.getProductId());
95 91
96 - // 4. 更新数据库 92 + // 2. 更新数据库
97 IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(updateReqVO); 93 IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(updateReqVO);
98 thingModelMapper.updateById(thingModel); 94 thingModelMapper.updateById(thingModel);
99 95
100 - // 5. 如果更新的是属性,需要更新默认的事件和服务 96 + // 3. 如果更新的是属性,需要更新默认的事件和服务
101 if (Objects.equals(updateReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { 97 if (Objects.equals(updateReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
102 createDefaultEventsAndServices(updateReqVO.getProductId(), updateReqVO.getProductKey()); 98 createDefaultEventsAndServices(updateReqVO.getProductId(), updateReqVO.getProductKey());
103 } 99 }
104 100
105 - // 6. 删除缓存 101 + // 4. 删除缓存
106 deleteThingModelListCache(updateReqVO.getProductKey()); 102 deleteThingModelListCache(updateReqVO.getProductKey());
107 } 103 }
108 104
109 @Override 105 @Override
110 @Transactional(rollbackFor = Exception.class) 106 @Transactional(rollbackFor = Exception.class)
111 public void deleteThingModel(Long id) { 107 public void deleteThingModel(Long id) {
112 - // 1. 校验功能是否存在 108 + // 1.1 校验功能是否存在
113 IotThingModelDO thingModel = thingModelMapper.selectById(id); 109 IotThingModelDO thingModel = thingModelMapper.selectById(id);
114 if (thingModel == null) { 110 if (thingModel == null) {
115 throw exception(THING_MODEL_NOT_EXISTS); 111 throw exception(THING_MODEL_NOT_EXISTS);
116 } 112 }
117 -  
118 - // 3. 校验产品状态,发布状态下,不允许操作功能 113 + // 1.2 校验产品状态,发布状态下,不允许操作功能
119 validateProductStatus(thingModel.getProductId()); 114 validateProductStatus(thingModel.getProductId());
120 115
121 // 2. 删除功能 116 // 2. 删除功能
@@ -168,6 +163,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { @@ -168,6 +163,7 @@ public class IotThingModelServiceImpl implements IotThingModelService {
168 } 163 }
169 } 164 }
170 165
  166 + // TODO @puhui999:这个方法,和 validateIdentifierUnique 可以融合下
171 private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) { 167 private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) {
172 IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); 168 IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier);
173 if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) { 169 if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) {
@@ -176,15 +172,16 @@ public class IotThingModelServiceImpl implements IotThingModelService { @@ -176,15 +172,16 @@ public class IotThingModelServiceImpl implements IotThingModelService {
176 } 172 }
177 173
178 private void validateProductStatus(Long createReqVO) { 174 private void validateProductStatus(Long createReqVO) {
179 - IotProductDO product = productService.getProduct(createReqVO); 175 + IotProductDO product = productService.validateProductExists(createReqVO);
180 if (Objects.equals(product.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) { 176 if (Objects.equals(product.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) {
181 throw exception(PRODUCT_STATUS_NOT_ALLOW_THING_MODEL); 177 throw exception(PRODUCT_STATUS_NOT_ALLOW_THING_MODEL);
182 } 178 }
183 } 179 }
184 180
  181 + // TODO @芋艿:在 review 下
185 private void validateNotDefaultEventAndService(String identifier) { 182 private void validateNotDefaultEventAndService(String identifier) {
186 - // set, get, post, property, event, time, value 是系统保留字段,不能用于标识符定义  
187 - if (CollUtil.containsAny(Arrays.asList("set", "get", "post", "property", "event", "time", "value"), Collections.singletonList(identifier))) { 183 + // 系统保留字段,不能用于标识符定义
  184 + if (StrUtil.equalsAny(identifier, "set", "get", "post", "property", "event", "time", "value")) {
188 throw exception(THING_MODEL_IDENTIFIER_INVALID); 185 throw exception(THING_MODEL_IDENTIFIER_INVALID);
189 } 186 }
190 } 187 }
@@ -205,6 +202,9 @@ public class IotThingModelServiceImpl implements IotThingModelService { @@ -205,6 +202,9 @@ public class IotThingModelServiceImpl implements IotThingModelService {
205 202
206 /** 203 /**
207 * 创建默认的事件和服务 204 * 创建默认的事件和服务
  205 + *
  206 + * @param productId 产品编号
  207 + * @param productKey 产品标识
208 */ 208 */
209 public void createDefaultEventsAndServices(Long productId, String productKey) { 209 public void createDefaultEventsAndServices(Long productId, String productKey) {
210 // 1. 获取当前属性列表 210 // 1. 获取当前属性列表