mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	【代码评审】IoT:物模型的管理
This commit is contained in:
		| @ -5,6 +5,7 @@ import lombok.Data; | |||||||
|  |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
|  | // TODO @puhui999:必要的参数校验 | ||||||
| /** | /** | ||||||
|  * 物模型中的事件 |  * 物模型中的事件 | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ import lombok.Data; | |||||||
|  |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
|  | // TODO @puhui999:必要的参数校验 | ||||||
| /** | /** | ||||||
|  * IOT 产品物模型中的参数 |  * IOT 产品物模型中的参数 | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ import lombok.Data; | |||||||
|  |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
|  | // TODO @puhui999:必要的参数校验 | ||||||
| /** | /** | ||||||
|  * 物模型中的属性 |  * 物模型中的属性 | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -1,50 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; |  | ||||||
|  |  | ||||||
| import lombok.*; |  | ||||||
|  |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| @Data |  | ||||||
| @Builder |  | ||||||
| @NoArgsConstructor |  | ||||||
| @AllArgsConstructor |  | ||||||
| @ToString |  | ||||||
| public class ThingModelRespVO { |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 产品编号 |  | ||||||
|      */ |  | ||||||
|     private Long id; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 产品标识 |  | ||||||
|      */ |  | ||||||
|     private String productKey; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 物模型 |  | ||||||
|      */ |  | ||||||
|     private Model model; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 物模型 |  | ||||||
|      */ |  | ||||||
|     @Data |  | ||||||
|     public static class Model { |  | ||||||
|  |  | ||||||
|         /** |  | ||||||
|          * 属性列表 |  | ||||||
|          */ |  | ||||||
|         private List<ThingModelProperty> properties; |  | ||||||
|  |  | ||||||
|         /** |  | ||||||
|          * 服务列表 |  | ||||||
|          */ |  | ||||||
|         private List<ThingModelService> services; |  | ||||||
|  |  | ||||||
|         /** |  | ||||||
|          * 事件列表 |  | ||||||
|          */ |  | ||||||
|         private List<ThingModelEvent> events; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -5,6 +5,7 @@ import lombok.Data; | |||||||
|  |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
|  | // TODO @puhui999:必要的参数校验 | ||||||
| /** | /** | ||||||
|  * 物模型中的服务 |  * 物模型中的服务 | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -6,10 +6,15 @@ import io.swagger.v3.oas.annotations.media.Schema; | |||||||
| import jakarta.validation.constraints.NotNull; | import jakarta.validation.constraints.NotNull; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
|  | // TODO @puhui999:部分字段,可以用 cursor 加上 example | ||||||
| @Schema(description = "管理后台 - IoT 产品物模型 List Request VO") | @Schema(description = "管理后台 - IoT 产品物模型 List Request VO") | ||||||
| @Data | @Data | ||||||
| public class IotThingModelListReqVO { | public class IotThingModelListReqVO { | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|  |     @NotNull(message = "产品编号不能为空") | ||||||
|  |     private Long productId; | ||||||
|  |  | ||||||
|     @Schema(description = "功能标识") |     @Schema(description = "功能标识") | ||||||
|     private String identifier; |     private String identifier; | ||||||
|  |  | ||||||
| @ -20,8 +25,4 @@ public class IotThingModelListReqVO { | |||||||
|     @InEnum(IotThingModelTypeEnum.class) |     @InEnum(IotThingModelTypeEnum.class) | ||||||
|     private Integer type; |     private Integer type; | ||||||
|  |  | ||||||
|     @Schema(description = "产品 ID", requiredMode = Schema.RequiredMode.REQUIRED) |  | ||||||
|     @NotNull(message = "产品 ID 不能为空") |  | ||||||
|     private Long productId; |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,12 +9,17 @@ import lombok.Data; | |||||||
| import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||||
| import lombok.ToString; | import lombok.ToString; | ||||||
|  |  | ||||||
|  | // TODO @puhui999:部分字段,可以用 cursor 加上 example | ||||||
| @Schema(description = "管理后台 - IoT 产品物模型分页 Request VO") | @Schema(description = "管理后台 - IoT 产品物模型分页 Request VO") | ||||||
| @Data | @Data | ||||||
| @EqualsAndHashCode(callSuper = true) | @EqualsAndHashCode(callSuper = true) | ||||||
| @ToString(callSuper = true) | @ToString(callSuper = true) | ||||||
| public class IotThingModelPageReqVO extends PageParam { | public class IotThingModelPageReqVO extends PageParam { | ||||||
|  |  | ||||||
|  |     @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|  |     @NotNull(message = "产品编号不能为空") | ||||||
|  |     private Long productId; | ||||||
|  |  | ||||||
|     @Schema(description = "功能标识") |     @Schema(description = "功能标识") | ||||||
|     private String identifier; |     private String identifier; | ||||||
|  |  | ||||||
| @ -25,8 +30,4 @@ public class IotThingModelPageReqVO extends PageParam { | |||||||
|     @InEnum(IotThingModelTypeEnum.class) |     @InEnum(IotThingModelTypeEnum.class) | ||||||
|     private Integer type; |     private Integer type; | ||||||
|  |  | ||||||
|     @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED) |  | ||||||
|     @NotNull(message = "产品ID不能为空") |  | ||||||
|     private Long productId; |  | ||||||
|  |  | ||||||
| } | } | ||||||
| @ -10,6 +10,7 @@ import lombok.Data; | |||||||
|  |  | ||||||
| import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||||
|  |  | ||||||
|  | // TODO @puhui999:部分字段,可以用 cursor 加上 example | ||||||
| @Schema(description = "管理后台 - IoT 产品物模型 Response VO") | @Schema(description = "管理后台 - IoT 产品物模型 Response VO") | ||||||
| @Data | @Data | ||||||
| @ExcelIgnoreUnannotated | @ExcelIgnoreUnannotated | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ import jakarta.validation.constraints.NotEmpty; | |||||||
| import jakarta.validation.constraints.NotNull; | import jakarta.validation.constraints.NotNull; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
|  | // TODO @puhui999:部分字段,可以用 cursor 加上 example | ||||||
| @Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO") | @Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO") | ||||||
| @Data | @Data | ||||||
| public class IotThingModelSaveReqVO { | public class IotThingModelSaveReqVO { | ||||||
|  | |||||||
| @ -79,4 +79,5 @@ public interface IotThingModelService { | |||||||
|      * @return 产品物模型列表 |      * @return 产品物模型列表 | ||||||
|      */ |      */ | ||||||
|     List<IotThingModelDO> getThingModelList(IotThingModelListReqVO reqVO); |     List<IotThingModelDO> getThingModelList(IotThingModelListReqVO reqVO); | ||||||
|  |  | ||||||
| } | } | ||||||
| @ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.service.thingmodel; | |||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.hutool.core.util.ObjectUtil; | import cn.hutool.core.util.ObjectUtil; | ||||||
|  | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.hutool.extra.spring.SpringUtil; | import cn.hutool.extra.spring.SpringUtil; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||||||
| @ -54,29 +55,26 @@ public class IotThingModelServiceImpl implements IotThingModelService { | |||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public Long createThingModel(IotThingModelSaveReqVO createReqVO) { |     public Long createThingModel(IotThingModelSaveReqVO createReqVO) { | ||||||
|         // 1. 校验功能标识符在同一产品下是否唯一 |         // 1.1 校验功能标识符在同一产品下是否唯一 | ||||||
|         validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier()); |         validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier()); | ||||||
|  |         // 1.2 功能名称在同一产品下是否唯一 | ||||||
|         // 2. 功能名称在同一产品下是否唯一 |  | ||||||
|         validateNameUnique(createReqVO.getProductId(), createReqVO.getName()); |         validateNameUnique(createReqVO.getProductId(), createReqVO.getName()); | ||||||
|  |         // 1.3 系统保留字段,不能用于标识符定义 | ||||||
|         // 3. 系统保留字段,不能用于标识符定义 |  | ||||||
|         validateNotDefaultEventAndService(createReqVO.getIdentifier()); |         validateNotDefaultEventAndService(createReqVO.getIdentifier()); | ||||||
|  |         // 1.4 校验产品状态,发布状态下,不允许新增功能 | ||||||
|         // 4. 校验产品状态,发布状态下,不允许新增功能 |  | ||||||
|         validateProductStatus(createReqVO.getProductId()); |         validateProductStatus(createReqVO.getProductId()); | ||||||
|  |  | ||||||
|         // 5. 插入数据库 |         // 2. 插入数据库 | ||||||
|         IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(createReqVO); |         IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(createReqVO); | ||||||
|         thingModelMapper.insert(thingModel); |         thingModelMapper.insert(thingModel); | ||||||
|  |  | ||||||
|         // 6. 如果创建的是属性,需要更新默认的事件和服务 |         // 3. 如果创建的是属性,需要更新默认的事件和服务 | ||||||
|         if (Objects.equals(createReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { |         if (Objects.equals(createReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { | ||||||
|             createDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey()); |             createDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey()); | ||||||
|         } |         } | ||||||
|         // TODO @puhui999: 服务和事件的情况 method 怎么设置?在前端设置还是后端设置? |         // TODO @puhui999: 服务和事件的情况 method 怎么设置?在前端设置还是后端设置? | ||||||
|  |  | ||||||
|         // 7. 删除缓存 |         // 4. 删除缓存 | ||||||
|         deleteThingModelListCache(createReqVO.getProductKey()); |         deleteThingModelListCache(createReqVO.getProductKey()); | ||||||
|         return thingModel.getId(); |         return thingModel.getId(); | ||||||
|     } |     } | ||||||
| @ -84,38 +82,35 @@ public class IotThingModelServiceImpl implements IotThingModelService { | |||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void updateThingModel(IotThingModelSaveReqVO updateReqVO) { |     public void updateThingModel(IotThingModelSaveReqVO updateReqVO) { | ||||||
|         // 1. 校验功能是否存在 |         // 1.1 校验功能是否存在 | ||||||
|         validateProductThingModelMapperExists(updateReqVO.getId()); |         validateProductThingModelMapperExists(updateReqVO.getId()); | ||||||
|  |         // 1.2 校验功能标识符是否唯一 | ||||||
|         // 2. 校验功能标识符是否唯一 |  | ||||||
|         validateIdentifierUniqueForUpdate(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier()); |         validateIdentifierUniqueForUpdate(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier()); | ||||||
|  |         // 1.3 校验产品状态,发布状态下,不允许操作功能 | ||||||
|         // 3. 校验产品状态,发布状态下,不允许操作功能 |  | ||||||
|         validateProductStatus(updateReqVO.getProductId()); |         validateProductStatus(updateReqVO.getProductId()); | ||||||
|  |  | ||||||
|         // 4. 更新数据库 |         // 2. 更新数据库 | ||||||
|         IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(updateReqVO); |         IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(updateReqVO); | ||||||
|         thingModelMapper.updateById(thingModel); |         thingModelMapper.updateById(thingModel); | ||||||
|  |  | ||||||
|         // 5. 如果更新的是属性,需要更新默认的事件和服务 |         // 3. 如果更新的是属性,需要更新默认的事件和服务 | ||||||
|         if (Objects.equals(updateReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { |         if (Objects.equals(updateReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { | ||||||
|             createDefaultEventsAndServices(updateReqVO.getProductId(), updateReqVO.getProductKey()); |             createDefaultEventsAndServices(updateReqVO.getProductId(), updateReqVO.getProductKey()); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 6. 删除缓存 |         // 4. 删除缓存 | ||||||
|         deleteThingModelListCache(updateReqVO.getProductKey()); |         deleteThingModelListCache(updateReqVO.getProductKey()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void deleteThingModel(Long id) { |     public void deleteThingModel(Long id) { | ||||||
|         // 1. 校验功能是否存在 |         // 1.1 校验功能是否存在 | ||||||
|         IotThingModelDO thingModel = thingModelMapper.selectById(id); |         IotThingModelDO thingModel = thingModelMapper.selectById(id); | ||||||
|         if (thingModel == null) { |         if (thingModel == null) { | ||||||
|             throw exception(THING_MODEL_NOT_EXISTS); |             throw exception(THING_MODEL_NOT_EXISTS); | ||||||
|         } |         } | ||||||
|  |         // 1.2 校验产品状态,发布状态下,不允许操作功能 | ||||||
|         // 3. 校验产品状态,发布状态下,不允许操作功能 |  | ||||||
|         validateProductStatus(thingModel.getProductId()); |         validateProductStatus(thingModel.getProductId()); | ||||||
|  |  | ||||||
|         // 2. 删除功能 |         // 2. 删除功能 | ||||||
| @ -168,6 +163,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // TODO @puhui999:这个方法,和 validateIdentifierUnique 可以融合下 | ||||||
|     private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) { |     private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) { | ||||||
|         IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); |         IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); | ||||||
|         if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) { |         if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) { | ||||||
| @ -176,15 +172,16 @@ public class IotThingModelServiceImpl implements IotThingModelService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void validateProductStatus(Long createReqVO) { |     private void validateProductStatus(Long createReqVO) { | ||||||
|         IotProductDO product = productService.getProduct(createReqVO); |         IotProductDO product = productService.validateProductExists(createReqVO); | ||||||
|         if (Objects.equals(product.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) { |         if (Objects.equals(product.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) { | ||||||
|             throw exception(PRODUCT_STATUS_NOT_ALLOW_THING_MODEL); |             throw exception(PRODUCT_STATUS_NOT_ALLOW_THING_MODEL); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // TODO @芋艿:在 review 下 | ||||||
|     private void validateNotDefaultEventAndService(String identifier) { |     private void validateNotDefaultEventAndService(String identifier) { | ||||||
|         // set, get, post, property, event, time, value 是系统保留字段,不能用于标识符定义 |         // 系统保留字段,不能用于标识符定义 | ||||||
|         if (CollUtil.containsAny(Arrays.asList("set", "get", "post", "property", "event", "time", "value"), Collections.singletonList(identifier))) { |         if (StrUtil.equalsAny(identifier, "set", "get", "post", "property", "event", "time", "value")) { | ||||||
|             throw exception(THING_MODEL_IDENTIFIER_INVALID); |             throw exception(THING_MODEL_IDENTIFIER_INVALID); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -205,6 +202,9 @@ public class IotThingModelServiceImpl implements IotThingModelService { | |||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 创建默认的事件和服务 |      * 创建默认的事件和服务 | ||||||
|  |      * | ||||||
|  |      * @param productId 产品编号 | ||||||
|  |      * @param productKey 产品标识 | ||||||
|      */ |      */ | ||||||
|     public void createDefaultEventsAndServices(Long productId, String productKey) { |     public void createDefaultEventsAndServices(Long productId, String productKey) { | ||||||
|         // 1. 获取当前属性列表 |         // 1. 获取当前属性列表 | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV