【代码评审】IoT:物模型的实现

This commit is contained in:
YunaiV 2025-02-04 16:35:55 +08:00
parent d24e3ad773
commit d23be86164
4 changed files with 22 additions and 36 deletions

View File

@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelL
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelRespVO; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO;
import cn.iocoder.yudao.module.iot.convert.thingmodel.IotThingModelConvert;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -62,7 +61,7 @@ public class IotThingModelController {
@PreAuthorize("@ss.hasPermission('iot:thing-model:query')") @PreAuthorize("@ss.hasPermission('iot:thing-model:query')")
public CommonResult<IotThingModelRespVO> getThingModel(@RequestParam("id") Long id) { public CommonResult<IotThingModelRespVO> getThingModel(@RequestParam("id") Long id) {
IotThingModelDO thingModel = thingModelService.getThingModel(id); IotThingModelDO thingModel = thingModelService.getThingModel(id);
return success(IotThingModelConvert.INSTANCE.convert(thingModel)); return success(BeanUtils.toBean(thingModel, IotThingModelRespVO.class));
} }
@GetMapping("/list-by-product-id") @GetMapping("/list-by-product-id")
@ -71,7 +70,7 @@ public class IotThingModelController {
@PreAuthorize("@ss.hasPermission('iot:thing-model:query')") @PreAuthorize("@ss.hasPermission('iot:thing-model:query')")
public CommonResult<List<IotThingModelRespVO>> getThingModelListByProductId(@RequestParam("productId") Long productId) { public CommonResult<List<IotThingModelRespVO>> getThingModelListByProductId(@RequestParam("productId") Long productId) {
List<IotThingModelDO> list = thingModelService.getThingModelListByProductId(productId); List<IotThingModelDO> list = thingModelService.getThingModelListByProductId(productId);
return success(IotThingModelConvert.INSTANCE.convertList(list)); return success(BeanUtils.toBean(list, IotThingModelRespVO.class));
} }
// TODO @puhui @supergetThingModelListByProductId getThingModelListByProductId 可以融合么 // TODO @puhui @supergetThingModelListByProductId getThingModelListByProductId 可以融合么
@ -80,7 +79,7 @@ public class IotThingModelController {
@PreAuthorize("@ss.hasPermission('iot:thing-model:query')") @PreAuthorize("@ss.hasPermission('iot:thing-model:query')")
public CommonResult<List<IotThingModelRespVO>> getThingModelListByProductId(@Valid IotThingModelListReqVO reqVO) { public CommonResult<List<IotThingModelRespVO>> getThingModelListByProductId(@Valid IotThingModelListReqVO reqVO) {
List<IotThingModelDO> list = thingModelService.getThingModelList(reqVO); List<IotThingModelDO> list = thingModelService.getThingModelList(reqVO);
return success(IotThingModelConvert.INSTANCE.convertList(list)); return success(BeanUtils.toBean(list, IotThingModelRespVO.class));
} }
@GetMapping("/page") @GetMapping("/page")

View File

@ -1,4 +1,6 @@
/** /**
* TODO 芋艿占位 * 提供 POJO 类的实体转换
*
* 目前使用 MapStruct 框架
*/ */
package cn.iocoder.yudao.module.iot.convert; package cn.iocoder.yudao.module.iot.convert;

View File

@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.iot.convert.thingmodel;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum;
@ -12,7 +11,6 @@ import org.mapstruct.Mapping;
import org.mapstruct.Named; import org.mapstruct.Named;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Objects; import java.util.Objects;
@Mapper @Mapper
@ -20,21 +18,11 @@ public interface IotThingModelConvert {
IotThingModelConvert INSTANCE = Mappers.getMapper(IotThingModelConvert.class); IotThingModelConvert INSTANCE = Mappers.getMapper(IotThingModelConvert.class);
// SaveReqVO 转换为 DO
@Mapping(target = "property", expression = "java(convertToProperty(bean))") @Mapping(target = "property", expression = "java(convertToProperty(bean))")
@Mapping(target = "event", expression = "java(convertToEvent(bean))") @Mapping(target = "event", expression = "java(convertToEvent(bean))")
@Mapping(target = "service", expression = "java(convertToService(bean))") @Mapping(target = "service", expression = "java(convertToService(bean))")
IotThingModelDO convert(IotThingModelSaveReqVO bean); IotThingModelDO convert(IotThingModelSaveReqVO bean);
// DO 转换为 RespVO
@Mapping(target = "property", source = "property")
@Mapping(target = "event", source = "event")
@Mapping(target = "service", source = "service")
IotThingModelRespVO convert(IotThingModelDO bean);
// 批量转换
List<IotThingModelRespVO> convertList(List<IotThingModelDO> list);
@Named("convertToProperty") @Named("convertToProperty")
default ThingModelProperty convertToProperty(IotThingModelSaveReqVO bean) { default ThingModelProperty convertToProperty(IotThingModelSaveReqVO bean) {
if (Objects.equals(bean.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { if (Objects.equals(bean.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {

View File

@ -58,9 +58,7 @@ public class IotThingModelServiceImpl implements IotThingModelService {
validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier()); validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier());
// 1.2 功能名称在同一产品下是否唯一 // 1.2 功能名称在同一产品下是否唯一
validateNameUnique(createReqVO.getProductId(), createReqVO.getName()); validateNameUnique(createReqVO.getProductId(), createReqVO.getName());
// 1.3 系统保留字段不能用于标识符定义 // 1.3 校验产品状态发布状态下不允许新增功能
validateNotDefaultEventAndService(createReqVO.getIdentifier());
// 1.4 校验产品状态发布状态下不允许新增功能
validateProductStatus(createReqVO.getProductId()); validateProductStatus(createReqVO.getProductId());
// 2. 插入数据库 // 2. 插入数据库
@ -71,7 +69,6 @@ public class IotThingModelServiceImpl implements IotThingModelService {
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 怎么设置在前端设置还是后端设置
// 4. 删除缓存 // 4. 删除缓存
deleteThingModelListCache(createReqVO.getProductKey()); deleteThingModelListCache(createReqVO.getProductKey());
@ -177,14 +174,6 @@ public class IotThingModelServiceImpl implements IotThingModelService {
} }
} }
// TODO @芋艿 review
private void validateNotDefaultEventAndService(String identifier) {
// 系统保留字段不能用于标识符定义
if (StrUtil.equalsAny(identifier, "set", "get", "post", "property", "event", "time", "value")) {
throw exception(THING_MODEL_IDENTIFIER_INVALID);
}
}
private void validateNameUnique(Long productId, String name) { private void validateNameUnique(Long productId, String name) {
IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndName(productId, name); IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndName(productId, name);
if (thingModel != null) { if (thingModel != null) {
@ -193,6 +182,12 @@ public class IotThingModelServiceImpl implements IotThingModelService {
} }
private void validateIdentifierUnique(Long productId, String identifier) { private void validateIdentifierUnique(Long productId, String identifier) {
// 系统保留字段不能用于标识符定义
if (StrUtil.equalsAny(identifier, "set", "get", "post", "property", "event", "time", "value")) {
throw exception(THING_MODEL_IDENTIFIER_INVALID);
}
// 校验唯一
IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier);
if (thingModel != null) { if (thingModel != null) {
throw exception(THING_MODEL_IDENTIFIER_EXISTS); throw exception(THING_MODEL_IDENTIFIER_EXISTS);
@ -215,17 +210,17 @@ public class IotThingModelServiceImpl implements IotThingModelService {
// 2.1 生成属性上报事件 // 2.1 生成属性上报事件
ThingModelEvent propertyPostEvent = generatePropertyPostEvent(properties); ThingModelEvent propertyPostEvent = generatePropertyPostEvent(properties);
if (propertyPostEvent != null) { if (propertyPostEvent != null) {
newThingModels.add(buildEventThingModelDO(productId, productKey, propertyPostEvent, "属性上报事件")); newThingModels.add(buildEventThingModel(productId, productKey, propertyPostEvent, "属性上报事件"));
} }
// 2.2 生成属性设置服务 // 2.2 生成属性设置服务
ThingModelService propertySetService = generatePropertySetService(properties); ThingModelService propertySetService = generatePropertySetService(properties);
if (propertySetService != null) { if (propertySetService != null) {
newThingModels.add(buildServiceThingModelDO(productId, productKey, propertySetService, "属性设置服务")); newThingModels.add(buildServiceThingModel(productId, productKey, propertySetService, "属性设置服务"));
} }
// 2.3 生成属性获取服务 // 2.3 生成属性获取服务
ThingModelService propertyGetService = generatePropertyGetService(properties); ThingModelService propertyGetService = generatePropertyGetService(properties);
if (propertyGetService != null) { if (propertyGetService != null) {
newThingModels.add(buildServiceThingModelDO(productId, productKey, propertyGetService, "属性获取服务")); newThingModels.add(buildServiceThingModel(productId, productKey, propertyGetService, "属性获取服务"));
} }
// 3.1 获取数据库中的默认的旧事件和服务列表 // 3.1 获取数据库中的默认的旧事件和服务列表
@ -269,8 +264,8 @@ public class IotThingModelServiceImpl implements IotThingModelService {
/** /**
* 构建事件功能对象 * 构建事件功能对象
*/ */
private IotThingModelDO buildEventThingModelDO(Long productId, String productKey, private IotThingModelDO buildEventThingModel(Long productId, String productKey,
ThingModelEvent event, String description) { ThingModelEvent event, String description) {
return new IotThingModelDO().setProductId(productId).setProductKey(productKey) return new IotThingModelDO().setProductId(productId).setProductKey(productKey)
.setIdentifier(event.getIdentifier()).setName(event.getName()).setDescription(description) .setIdentifier(event.getIdentifier()).setName(event.getName()).setDescription(description)
.setType(IotThingModelTypeEnum.EVENT.getType()).setEvent(event); .setType(IotThingModelTypeEnum.EVENT.getType()).setEvent(event);
@ -279,13 +274,14 @@ public class IotThingModelServiceImpl implements IotThingModelService {
/** /**
* 构建服务功能对象 * 构建服务功能对象
*/ */
private IotThingModelDO buildServiceThingModelDO(Long productId, String productKey, private IotThingModelDO buildServiceThingModel(Long productId, String productKey,
ThingModelService service, String description) { ThingModelService service, String description) {
return new IotThingModelDO().setProductId(productId).setProductKey(productKey) return new IotThingModelDO().setProductId(productId).setProductKey(productKey)
.setIdentifier(service.getIdentifier()).setName(service.getName()).setDescription(description) .setIdentifier(service.getIdentifier()).setName(service.getName()).setDescription(description)
.setType(IotThingModelTypeEnum.SERVICE.getType()).setService(service); .setType(IotThingModelTypeEnum.SERVICE.getType()).setService(service);
} }
// TODO @haohao是不是不用生成这个目前属性上报是个批量接口
/** /**
* 生成属性上报事件 * 生成属性上报事件
*/ */
@ -301,6 +297,7 @@ public class IotThingModelServiceImpl implements IotThingModelService {
.setOutputParams(buildInputOutputParam(thingModels, IotThingModelParamDirectionEnum.OUTPUT)); .setOutputParams(buildInputOutputParam(thingModels, IotThingModelParamDirectionEnum.OUTPUT));
} }
// TODO @haohao是不是不用生成这个目前属性上报是个批量接口
/** /**
* 生成属性设置服务 * 生成属性设置服务
*/ */