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

This commit is contained in:
YunaiV 2025-01-28 22:24:28 +08:00
parent 0b16f1678c
commit 76ab64a255
11 changed files with 42 additions and 83 deletions

View File

@ -5,6 +5,7 @@ import lombok.Data;
import java.util.List;
// TODO @puhui999必要的参数校验
/**
* 物模型中的事件
*

View File

@ -6,6 +6,7 @@ import lombok.Data;
import java.util.List;
// TODO @puhui999必要的参数校验
/**
* IOT 产品物模型中的参数
*

View File

@ -6,6 +6,7 @@ import lombok.Data;
import java.util.List;
// TODO @puhui999必要的参数校验
/**
* 物模型中的属性
*

View File

@ -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;
}
}

View File

@ -5,6 +5,7 @@ import lombok.Data;
import java.util.List;
// TODO @puhui999必要的参数校验
/**
* 物模型中的服务
*

View File

@ -6,10 +6,15 @@ import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - IoT 产品物模型List Request VO")
// TODO @puhui999部分字段可以用 cursor 加上 example
@Schema(description = "管理后台 - IoT 产品物模型 List Request VO")
@Data
public class IotThingModelListReqVO {
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "产品编号不能为空")
private Long productId;
@Schema(description = "功能标识")
private String identifier;
@ -20,8 +25,4 @@ public class IotThingModelListReqVO {
@InEnum(IotThingModelTypeEnum.class)
private Integer type;
@Schema(description = "产品 ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "产品 ID 不能为空")
private Long productId;
}

View File

@ -9,12 +9,17 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
// TODO @puhui999部分字段可以用 cursor 加上 example
@Schema(description = "管理后台 - IoT 产品物模型分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class IotThingModelPageReqVO extends PageParam {
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "产品编号不能为空")
private Long productId;
@Schema(description = "功能标识")
private String identifier;
@ -25,8 +30,4 @@ public class IotThingModelPageReqVO extends PageParam {
@InEnum(IotThingModelTypeEnum.class)
private Integer type;
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "产品ID不能为空")
private Long productId;
}

View File

@ -10,6 +10,7 @@ import lombok.Data;
import java.time.LocalDateTime;
// TODO @puhui999部分字段可以用 cursor 加上 example
@Schema(description = "管理后台 - IoT 产品物模型 Response VO")
@Data
@ExcelIgnoreUnannotated

View File

@ -10,6 +10,7 @@ import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
// TODO @puhui999部分字段可以用 cursor 加上 example
@Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO")
@Data
public class IotThingModelSaveReqVO {

View File

@ -79,4 +79,5 @@ public interface IotThingModelService {
* @return 产品物模型列表
*/
List<IotThingModelDO> getThingModelList(IotThingModelListReqVO reqVO);
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.service.thingmodel;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@ -54,29 +55,26 @@ public class IotThingModelServiceImpl implements IotThingModelService {
@Override
@Transactional(rollbackFor = Exception.class)
public Long createThingModel(IotThingModelSaveReqVO createReqVO) {
// 1. 校验功能标识符在同一产品下是否唯一
// 1.1 校验功能标识符在同一产品下是否唯一
validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier());
// 2. 功能名称在同一产品下是否唯一
// 1.2 功能名称在同一产品下是否唯一
validateNameUnique(createReqVO.getProductId(), createReqVO.getName());
// 3. 系统保留字段不能用于标识符定义
// 1.3 系统保留字段不能用于标识符定义
validateNotDefaultEventAndService(createReqVO.getIdentifier());
// 4. 校验产品状态发布状态下不允许新增功能
// 1.4 校验产品状态发布状态下不允许新增功能
validateProductStatus(createReqVO.getProductId());
// 5. 插入数据库
// 2. 插入数据库
IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(createReqVO);
thingModelMapper.insert(thingModel);
// 6. 如果创建的是属性需要更新默认的事件和服务
// 3. 如果创建的是属性需要更新默认的事件和服务
if (Objects.equals(createReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
createDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey());
}
// TODO @puhui999: 服务和事件的情况 method 怎么设置在前端设置还是后端设置
// 7. 删除缓存
// 4. 删除缓存
deleteThingModelListCache(createReqVO.getProductKey());
return thingModel.getId();
}
@ -84,38 +82,35 @@ public class IotThingModelServiceImpl implements IotThingModelService {
@Override
@Transactional(rollbackFor = Exception.class)
public void updateThingModel(IotThingModelSaveReqVO updateReqVO) {
// 1. 校验功能是否存在
// 1.1 校验功能是否存在
validateProductThingModelMapperExists(updateReqVO.getId());
// 2. 校验功能标识符是否唯一
// 1.2 校验功能标识符是否唯一
validateIdentifierUniqueForUpdate(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier());
// 3. 校验产品状态发布状态下不允许操作功能
// 1.3 校验产品状态发布状态下不允许操作功能
validateProductStatus(updateReqVO.getProductId());
// 4. 更新数据库
// 2. 更新数据库
IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(updateReqVO);
thingModelMapper.updateById(thingModel);
// 5. 如果更新的是属性需要更新默认的事件和服务
// 3. 如果更新的是属性需要更新默认的事件和服务
if (Objects.equals(updateReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
createDefaultEventsAndServices(updateReqVO.getProductId(), updateReqVO.getProductKey());
}
// 6. 删除缓存
// 4. 删除缓存
deleteThingModelListCache(updateReqVO.getProductKey());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteThingModel(Long id) {
// 1. 校验功能是否存在
// 1.1 校验功能是否存在
IotThingModelDO thingModel = thingModelMapper.selectById(id);
if (thingModel == null) {
throw exception(THING_MODEL_NOT_EXISTS);
}
// 3. 校验产品状态发布状态下不允许操作功能
// 1.2 校验产品状态发布状态下不允许操作功能
validateProductStatus(thingModel.getProductId());
// 2. 删除功能
@ -168,6 +163,7 @@ public class IotThingModelServiceImpl implements IotThingModelService {
}
}
// TODO @puhui999这个方法 validateIdentifierUnique 可以融合下
private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) {
IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier);
if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) {
@ -176,15 +172,16 @@ public class IotThingModelServiceImpl implements IotThingModelService {
}
private void validateProductStatus(Long createReqVO) {
IotProductDO product = productService.getProduct(createReqVO);
IotProductDO product = productService.validateProductExists(createReqVO);
if (Objects.equals(product.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) {
throw exception(PRODUCT_STATUS_NOT_ALLOW_THING_MODEL);
}
}
// TODO @芋艿 review
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);
}
}
@ -205,6 +202,9 @@ public class IotThingModelServiceImpl implements IotThingModelService {
/**
* 创建默认的事件和服务
*
* @param productId 产品编号
* @param productKey 产品标识
*/
public void createDefaultEventsAndServices(Long productId, String productKey) {
// 1. 获取当前属性列表