Commit 6abd67a38c671219f138a52a50d4d4ceda632af3
1 parent
d718f801
【代码优化】IoT: 物模型
Showing
14 changed files
with
148 additions
and
56 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotDataSpecsDataTypeEnum.java
| 1 | package cn.iocoder.yudao.module.iot.enums.thingmodel; | 1 | package cn.iocoder.yudao.module.iot.enums.thingmodel; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | ||
| 3 | import lombok.AllArgsConstructor; | 4 | import lombok.AllArgsConstructor; |
| 4 | import lombok.Getter; | 5 | import lombok.Getter; |
| 5 | 6 | ||
| 6 | -// TODO @puhui999:加个 ArrayValuable | 7 | +import java.util.Arrays; |
| 8 | + | ||
| 7 | /** | 9 | /** |
| 8 | * IoT 数据定义的数据类型枚举类 | 10 | * IoT 数据定义的数据类型枚举类 |
| 9 | * | 11 | * |
| @@ -11,7 +13,7 @@ import lombok.Getter; | @@ -11,7 +13,7 @@ import lombok.Getter; | ||
| 11 | */ | 13 | */ |
| 12 | @AllArgsConstructor | 14 | @AllArgsConstructor |
| 13 | @Getter | 15 | @Getter |
| 14 | -public enum IotDataSpecsDataTypeEnum { | 16 | +public enum IotDataSpecsDataTypeEnum implements ArrayValuable<String> { |
| 15 | 17 | ||
| 16 | INT("int"), | 18 | INT("int"), |
| 17 | FLOAT("float"), | 19 | FLOAT("float"), |
| @@ -23,6 +25,13 @@ public enum IotDataSpecsDataTypeEnum { | @@ -23,6 +25,13 @@ public enum IotDataSpecsDataTypeEnum { | ||
| 23 | STRUCT("struct"), | 25 | STRUCT("struct"), |
| 24 | ARRAY("array"); | 26 | ARRAY("array"); |
| 25 | 27 | ||
| 28 | + public static final String[] ARRAYS = Arrays.stream(values()).map(IotDataSpecsDataTypeEnum::getDataType).toArray(String[]::new); | ||
| 29 | + | ||
| 26 | private final String dataType; | 30 | private final String dataType; |
| 27 | 31 | ||
| 32 | + @Override | ||
| 33 | + public String[] array() { | ||
| 34 | + return ARRAYS; | ||
| 35 | + } | ||
| 36 | + | ||
| 28 | } | 37 | } |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelAccessModeEnum.java
| 1 | package cn.iocoder.yudao.module.iot.enums.thingmodel; | 1 | package cn.iocoder.yudao.module.iot.enums.thingmodel; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | ||
| 3 | import lombok.AllArgsConstructor; | 4 | import lombok.AllArgsConstructor; |
| 4 | import lombok.Getter; | 5 | import lombok.Getter; |
| 5 | 6 | ||
| 6 | -// TODO @puhui999:加个 ArrayValuable | 7 | +import java.util.Arrays; |
| 8 | + | ||
| 7 | /** | 9 | /** |
| 8 | * IOT 产品物模型属性读取类型枚举 | 10 | * IOT 产品物模型属性读取类型枚举 |
| 9 | * | 11 | * |
| @@ -11,11 +13,18 @@ import lombok.Getter; | @@ -11,11 +13,18 @@ import lombok.Getter; | ||
| 11 | */ | 13 | */ |
| 12 | @AllArgsConstructor | 14 | @AllArgsConstructor |
| 13 | @Getter | 15 | @Getter |
| 14 | -public enum IotThingModelAccessModeEnum { | 16 | +public enum IotThingModelAccessModeEnum implements ArrayValuable<String> { |
| 15 | 17 | ||
| 16 | READ_ONLY("r"), | 18 | READ_ONLY("r"), |
| 17 | READ_WRITE("rw"); | 19 | READ_WRITE("rw"); |
| 18 | 20 | ||
| 21 | + public static final String[] ARRAYS = Arrays.stream(values()).map(IotThingModelAccessModeEnum::getMode).toArray(String[]::new); | ||
| 22 | + | ||
| 19 | private final String mode; | 23 | private final String mode; |
| 20 | 24 | ||
| 25 | + @Override | ||
| 26 | + public String[] array() { | ||
| 27 | + return ARRAYS; | ||
| 28 | + } | ||
| 29 | + | ||
| 21 | } | 30 | } |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelParamDirectionEnum.java
| 1 | package cn.iocoder.yudao.module.iot.enums.thingmodel; | 1 | package cn.iocoder.yudao.module.iot.enums.thingmodel; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | ||
| 3 | import lombok.AllArgsConstructor; | 4 | import lombok.AllArgsConstructor; |
| 4 | import lombok.Getter; | 5 | import lombok.Getter; |
| 5 | 6 | ||
| 6 | -// TODO @puhui999:加个 ArrayValuable | 7 | +import java.util.Arrays; |
| 8 | + | ||
| 9 | + | ||
| 7 | /** | 10 | /** |
| 8 | * IOT 产品物模型参数是输入参数还是输出参数枚举 | 11 | * IOT 产品物模型参数是输入参数还是输出参数枚举 |
| 9 | * | 12 | * |
| @@ -11,11 +14,18 @@ import lombok.Getter; | @@ -11,11 +14,18 @@ import lombok.Getter; | ||
| 11 | */ | 14 | */ |
| 12 | @AllArgsConstructor | 15 | @AllArgsConstructor |
| 13 | @Getter | 16 | @Getter |
| 14 | -public enum IotThingModelParamDirectionEnum { | 17 | +public enum IotThingModelParamDirectionEnum implements ArrayValuable<String> { |
| 15 | 18 | ||
| 16 | INPUT("input"), // 输入参数 | 19 | INPUT("input"), // 输入参数 |
| 17 | OUTPUT("output"); // 输出参数 | 20 | OUTPUT("output"); // 输出参数 |
| 18 | 21 | ||
| 22 | + public static final String[] ARRAYS = Arrays.stream(values()).map(IotThingModelParamDirectionEnum::getDirection).toArray(String[]::new); | ||
| 23 | + | ||
| 19 | private final String direction; | 24 | private final String direction; |
| 20 | 25 | ||
| 26 | + @Override | ||
| 27 | + public String[] array() { | ||
| 28 | + return ARRAYS; | ||
| 29 | + } | ||
| 30 | + | ||
| 21 | } | 31 | } |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelServiceCallTypeEnum.java
| 1 | package cn.iocoder.yudao.module.iot.enums.thingmodel; | 1 | package cn.iocoder.yudao.module.iot.enums.thingmodel; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | ||
| 3 | import lombok.AllArgsConstructor; | 4 | import lombok.AllArgsConstructor; |
| 4 | import lombok.Getter; | 5 | import lombok.Getter; |
| 5 | 6 | ||
| 6 | -// TODO @puhui999:加个 ArrayValuable | 7 | +import java.util.Arrays; |
| 8 | + | ||
| 7 | /** | 9 | /** |
| 8 | * IOT 产品物模型服务调用方式枚举 | 10 | * IOT 产品物模型服务调用方式枚举 |
| 9 | * | 11 | * |
| @@ -11,11 +13,18 @@ import lombok.Getter; | @@ -11,11 +13,18 @@ import lombok.Getter; | ||
| 11 | */ | 13 | */ |
| 12 | @AllArgsConstructor | 14 | @AllArgsConstructor |
| 13 | @Getter | 15 | @Getter |
| 14 | -public enum IotThingModelServiceCallTypeEnum { | 16 | +public enum IotThingModelServiceCallTypeEnum implements ArrayValuable<String> { |
| 15 | 17 | ||
| 16 | ASYNC("async"), // 异步调用 | 18 | ASYNC("async"), // 异步调用 |
| 17 | SYNC("sync"); // 同步调用 | 19 | SYNC("sync"); // 同步调用 |
| 18 | 20 | ||
| 21 | + public static final String[] ARRAYS = Arrays.stream(values()).map(IotThingModelServiceCallTypeEnum::getType).toArray(String[]::new); | ||
| 22 | + | ||
| 19 | private final String type; | 23 | private final String type; |
| 20 | 24 | ||
| 25 | + @Override | ||
| 26 | + public String[] array() { | ||
| 27 | + return ARRAYS; | ||
| 28 | + } | ||
| 29 | + | ||
| 21 | } | 30 | } |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelServiceEventTypeEnum.java
| 1 | package cn.iocoder.yudao.module.iot.enums.thingmodel; | 1 | package cn.iocoder.yudao.module.iot.enums.thingmodel; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | ||
| 3 | import lombok.AllArgsConstructor; | 4 | import lombok.AllArgsConstructor; |
| 4 | import lombok.Getter; | 5 | import lombok.Getter; |
| 5 | 6 | ||
| 6 | -// TODO @puhui999:加个 ArrayValuable | 7 | +import java.util.Arrays; |
| 8 | + | ||
| 7 | /** | 9 | /** |
| 8 | * IOT 产品物模型事件类型枚举 | 10 | * IOT 产品物模型事件类型枚举 |
| 9 | * | 11 | * |
| @@ -11,12 +13,19 @@ import lombok.Getter; | @@ -11,12 +13,19 @@ import lombok.Getter; | ||
| 11 | */ | 13 | */ |
| 12 | @AllArgsConstructor | 14 | @AllArgsConstructor |
| 13 | @Getter | 15 | @Getter |
| 14 | -public enum IotThingModelServiceEventTypeEnum { | 16 | +public enum IotThingModelServiceEventTypeEnum implements ArrayValuable<String> { |
| 15 | 17 | ||
| 16 | INFO("info"), // 信息 | 18 | INFO("info"), // 信息 |
| 17 | ALERT("alert"), // 告警 | 19 | ALERT("alert"), // 告警 |
| 18 | ERROR("error"); // 故障 | 20 | ERROR("error"); // 故障 |
| 19 | 21 | ||
| 22 | + public static final String[] ARRAYS = Arrays.stream(values()).map(IotThingModelServiceEventTypeEnum::getType).toArray(String[]::new); | ||
| 23 | + | ||
| 20 | private final String type; | 24 | private final String type; |
| 21 | 25 | ||
| 26 | + @Override | ||
| 27 | + public String[] array() { | ||
| 28 | + return ARRAYS; | ||
| 29 | + } | ||
| 30 | + | ||
| 22 | } | 31 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelEvent.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 3 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelServiceEventTypeEnum; | 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelServiceEventTypeEnum; |
| 5 | +import jakarta.validation.Valid; | ||
| 6 | +import jakarta.validation.constraints.NotEmpty; | ||
| 7 | +import jakarta.validation.constraints.Pattern; | ||
| 4 | import lombok.Data; | 8 | import lombok.Data; |
| 5 | 9 | ||
| 6 | import java.util.List; | 10 | import java.util.List; |
| 7 | 11 | ||
| 8 | -// TODO @puhui999:必要的参数校验 | ||
| 9 | /** | 12 | /** |
| 10 | * 物模型中的事件 | 13 | * 物模型中的事件 |
| 11 | * | 14 | * |
| @@ -17,10 +20,13 @@ public class ThingModelEvent { | @@ -17,10 +20,13 @@ public class ThingModelEvent { | ||
| 17 | /** | 20 | /** |
| 18 | * 事件标识符 | 21 | * 事件标识符 |
| 19 | */ | 22 | */ |
| 23 | + @NotEmpty(message = "事件标识符不能为空") | ||
| 24 | + @Pattern(regexp = "^[a-zA-Z][a-zA-Z0-9_]{0,31}$", message = "事件标识符只能由字母、数字和下划线组成,必须以字母开头,长度不超过32个字符") | ||
| 20 | private String identifier; | 25 | private String identifier; |
| 21 | /** | 26 | /** |
| 22 | * 事件名称 | 27 | * 事件名称 |
| 23 | */ | 28 | */ |
| 29 | + @NotEmpty(message = "事件名称不能为空") | ||
| 24 | private String name; | 30 | private String name; |
| 25 | /** | 31 | /** |
| 26 | * 是否是标准品类的必选事件 | 32 | * 是否是标准品类的必选事件 |
| @@ -31,12 +37,15 @@ public class ThingModelEvent { | @@ -31,12 +37,15 @@ public class ThingModelEvent { | ||
| 31 | * | 37 | * |
| 32 | * 枚举 {@link IotThingModelServiceEventTypeEnum} | 38 | * 枚举 {@link IotThingModelServiceEventTypeEnum} |
| 33 | */ | 39 | */ |
| 40 | + @NotEmpty(message = "事件类型不能为空") | ||
| 41 | + @InEnum(IotThingModelServiceEventTypeEnum.class) | ||
| 34 | private String type; | 42 | private String type; |
| 35 | /** | 43 | /** |
| 36 | * 事件的输出参数 | 44 | * 事件的输出参数 |
| 37 | * | 45 | * |
| 38 | * 输出参数定义事件调用后返回的结果或反馈信息,用于确认操作结果或提供额外的信息。 | 46 | * 输出参数定义事件调用后返回的结果或反馈信息,用于确认操作结果或提供额外的信息。 |
| 39 | */ | 47 | */ |
| 48 | + @Valid | ||
| 40 | private List<ThingModelParam> outputParams; | 49 | private List<ThingModelParam> outputParams; |
| 41 | /** | 50 | /** |
| 42 | * 标识设备需要执行的具体操作 | 51 | * 标识设备需要执行的具体操作 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelParam.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 3 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs; |
| 5 | +import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; | ||
| 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelParamDirectionEnum; | 6 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelParamDirectionEnum; |
| 7 | +import jakarta.validation.constraints.NotEmpty; | ||
| 8 | +import jakarta.validation.constraints.Pattern; | ||
| 5 | import lombok.Data; | 9 | import lombok.Data; |
| 6 | 10 | ||
| 7 | import java.util.List; | 11 | import java.util.List; |
| 8 | 12 | ||
| 9 | -// TODO @puhui999:必要的参数校验 | ||
| 10 | /** | 13 | /** |
| 11 | * IOT 产品物模型中的参数 | 14 | * IOT 产品物模型中的参数 |
| 12 | * | 15 | * |
| @@ -18,16 +21,21 @@ public class ThingModelParam { | @@ -18,16 +21,21 @@ public class ThingModelParam { | ||
| 18 | /** | 21 | /** |
| 19 | * 参数标识符 | 22 | * 参数标识符 |
| 20 | */ | 23 | */ |
| 24 | + @NotEmpty(message = "参数标识符不能为空") | ||
| 25 | + @Pattern(regexp = "^[a-zA-Z][a-zA-Z0-9_]{0,31}$", message = "参数标识符只能由字母、数字和下划线组成,必须以字母开头,长度不超过32个字符") | ||
| 21 | private String identifier; | 26 | private String identifier; |
| 22 | /** | 27 | /** |
| 23 | * 参数名称 | 28 | * 参数名称 |
| 24 | */ | 29 | */ |
| 30 | + @NotEmpty(message = "参数名称不能为空") | ||
| 25 | private String name; | 31 | private String name; |
| 26 | /** | 32 | /** |
| 27 | * 用于区分输入或输出参数 | 33 | * 用于区分输入或输出参数 |
| 28 | * | 34 | * |
| 29 | * 枚举 {@link IotThingModelParamDirectionEnum} | 35 | * 枚举 {@link IotThingModelParamDirectionEnum} |
| 30 | */ | 36 | */ |
| 37 | + @NotEmpty(message = "参数方向不能为空") | ||
| 38 | + @InEnum(IotThingModelParamDirectionEnum.class) | ||
| 31 | private String direction; | 39 | private String direction; |
| 32 | /** | 40 | /** |
| 33 | * 参数的序号。从 0 开始排序,且不能重复。 | 41 | * 参数的序号。从 0 开始排序,且不能重复。 |
| @@ -37,7 +45,11 @@ public class ThingModelParam { | @@ -37,7 +45,11 @@ public class ThingModelParam { | ||
| 37 | private Integer paraOrder; | 45 | private Integer paraOrder; |
| 38 | /** | 46 | /** |
| 39 | * 参数值的数据类型,与 dataSpecs 的 dataType 保持一致 | 47 | * 参数值的数据类型,与 dataSpecs 的 dataType 保持一致 |
| 48 | + * | ||
| 49 | + * 枚举 {@link IotDataSpecsDataTypeEnum} | ||
| 40 | */ | 50 | */ |
| 51 | + @NotEmpty(message = "数据类型不能为空") | ||
| 52 | + @InEnum(IotDataSpecsDataTypeEnum.class) | ||
| 41 | private String dataType; | 53 | private String dataType; |
| 42 | /** | 54 | /** |
| 43 | * 参数值的数据类型(dataType)为非列表型(int、float、double、text、date、array)的数据规范存储在 dataSpecs 中 | 55 | * 参数值的数据类型(dataType)为非列表型(int、float、double、text、date、array)的数据规范存储在 dataSpecs 中 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelProperty.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 3 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs; |
| 5 | +import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; | ||
| 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelAccessModeEnum; | 6 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelAccessModeEnum; |
| 7 | +import jakarta.validation.constraints.NotEmpty; | ||
| 8 | +import jakarta.validation.constraints.Pattern; | ||
| 5 | import lombok.Data; | 9 | import lombok.Data; |
| 6 | 10 | ||
| 7 | import java.util.List; | 11 | import java.util.List; |
| 8 | 12 | ||
| 9 | -// TODO @puhui999:必要的参数校验 | ||
| 10 | /** | 13 | /** |
| 11 | * 物模型中的属性 | 14 | * 物模型中的属性 |
| 12 | * | 15 | * |
| @@ -20,26 +23,33 @@ public class ThingModelProperty { | @@ -20,26 +23,33 @@ public class ThingModelProperty { | ||
| 20 | /** | 23 | /** |
| 21 | * 属性标识符 | 24 | * 属性标识符 |
| 22 | */ | 25 | */ |
| 26 | + @NotEmpty(message = "属性标识符不能为空") | ||
| 27 | + @Pattern(regexp = "^[a-zA-Z][a-zA-Z0-9_]{0,31}$", message = "属性标识符只能由字母、数字和下划线组成,必须以字母开头,长度不超过32个字符") | ||
| 23 | private String identifier; | 28 | private String identifier; |
| 24 | /** | 29 | /** |
| 25 | * 属性名称 | 30 | * 属性名称 |
| 26 | */ | 31 | */ |
| 32 | + @NotEmpty(message = "属性名称不能为空") | ||
| 27 | private String name; | 33 | private String name; |
| 28 | /** | 34 | /** |
| 29 | * 云端可以对该属性进行的操作类型 | 35 | * 云端可以对该属性进行的操作类型 |
| 30 | * | 36 | * |
| 31 | * 枚举 {@link IotThingModelAccessModeEnum} | 37 | * 枚举 {@link IotThingModelAccessModeEnum} |
| 32 | */ | 38 | */ |
| 39 | + @NotEmpty(message = "操作类型不能为空") | ||
| 40 | + @InEnum(IotThingModelAccessModeEnum.class) | ||
| 33 | private String accessMode; | 41 | private String accessMode; |
| 34 | /** | 42 | /** |
| 35 | * 是否是标准品类的必选服务 | 43 | * 是否是标准品类的必选服务 |
| 36 | */ | 44 | */ |
| 37 | private Boolean required; | 45 | private Boolean required; |
| 38 | /** | 46 | /** |
| 39 | - * 数据类型,与 dataSpecs 的 dataType 保持一致 | 47 | + * 参数值的数据类型,与 dataSpecs 的 dataType 保持一致 |
| 40 | * | 48 | * |
| 41 | - * 枚举 {@link cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum} | 49 | + * 枚举 {@link IotDataSpecsDataTypeEnum} |
| 42 | */ | 50 | */ |
| 51 | + @NotEmpty(message = "数据类型不能为空") | ||
| 52 | + @InEnum(IotDataSpecsDataTypeEnum.class) | ||
| 43 | private String dataType; | 53 | private String dataType; |
| 44 | /** | 54 | /** |
| 45 | * 数据类型(dataType)为非列表型(int、float、double、text、date、array)的数据规范存储在 dataSpecs 中 | 55 | * 数据类型(dataType)为非列表型(int、float、double、text、date、array)的数据规范存储在 dataSpecs 中 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelService.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 3 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelServiceCallTypeEnum; | 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelServiceCallTypeEnum; |
| 5 | +import jakarta.validation.Valid; | ||
| 6 | +import jakarta.validation.constraints.NotEmpty; | ||
| 7 | +import jakarta.validation.constraints.Pattern; | ||
| 4 | import lombok.Data; | 8 | import lombok.Data; |
| 5 | 9 | ||
| 6 | import java.util.List; | 10 | import java.util.List; |
| 7 | 11 | ||
| 8 | -// TODO @puhui999:必要的参数校验 | ||
| 9 | /** | 12 | /** |
| 10 | * 物模型中的服务 | 13 | * 物模型中的服务 |
| 11 | * | 14 | * |
| @@ -17,10 +20,13 @@ public class ThingModelService { | @@ -17,10 +20,13 @@ public class ThingModelService { | ||
| 17 | /** | 20 | /** |
| 18 | * 服务标识符 | 21 | * 服务标识符 |
| 19 | */ | 22 | */ |
| 23 | + @NotEmpty(message = "服务标识符不能为空") | ||
| 24 | + @Pattern(regexp = "^[a-zA-Z][a-zA-Z0-9_]{0,31}$", message = "服务标识符只能由字母、数字和下划线组成,必须以字母开头,长度不超过32个字符") | ||
| 20 | private String identifier; | 25 | private String identifier; |
| 21 | /** | 26 | /** |
| 22 | * 服务名称 | 27 | * 服务名称 |
| 23 | */ | 28 | */ |
| 29 | + @NotEmpty(message = "服务名称不能为空") | ||
| 24 | private String name; | 30 | private String name; |
| 25 | /** | 31 | /** |
| 26 | * 是否是标准品类的必选服务 | 32 | * 是否是标准品类的必选服务 |
| @@ -31,18 +37,22 @@ public class ThingModelService { | @@ -31,18 +37,22 @@ public class ThingModelService { | ||
| 31 | * | 37 | * |
| 32 | * 枚举 {@link IotThingModelServiceCallTypeEnum} | 38 | * 枚举 {@link IotThingModelServiceCallTypeEnum} |
| 33 | */ | 39 | */ |
| 40 | + @NotEmpty(message = "调用类型不能为空") | ||
| 41 | + @InEnum(IotThingModelServiceCallTypeEnum.class) | ||
| 34 | private String callType; | 42 | private String callType; |
| 35 | /** | 43 | /** |
| 36 | * 服务的输入参数 | 44 | * 服务的输入参数 |
| 37 | * | 45 | * |
| 38 | * 输入参数定义服务调用时所需提供的信息,用于控制设备行为或执行特定任务 | 46 | * 输入参数定义服务调用时所需提供的信息,用于控制设备行为或执行特定任务 |
| 39 | */ | 47 | */ |
| 48 | + @Valid | ||
| 40 | private List<ThingModelParam> inputParams; | 49 | private List<ThingModelParam> inputParams; |
| 41 | /** | 50 | /** |
| 42 | * 服务的输出参数 | 51 | * 服务的输出参数 |
| 43 | * | 52 | * |
| 44 | * 输出参数定义服务调用后返回的结果或反馈信息,用于确认操作结果或提供额外的信息。 | 53 | * 输出参数定义服务调用后返回的结果或反馈信息,用于确认操作结果或提供额外的信息。 |
| 45 | */ | 54 | */ |
| 55 | + @Valid | ||
| 46 | private List<ThingModelParam> outputParams; | 56 | private List<ThingModelParam> outputParams; |
| 47 | /** | 57 | /** |
| 48 | * 标识设备需要执行的具体操作 | 58 | * 标识设备需要执行的具体操作 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelListReqVO.java
| @@ -6,19 +6,18 @@ import io.swagger.v3.oas.annotations.media.Schema; | @@ -6,19 +6,18 @@ 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 | -// TODO @puhui999:部分字段,可以用 cursor 加上 example | ||
| 10 | @Schema(description = "管理后台 - IoT 产品物模型 List Request VO") | 9 | @Schema(description = "管理后台 - IoT 产品物模型 List Request VO") |
| 11 | @Data | 10 | @Data |
| 12 | public class IotThingModelListReqVO { | 11 | public class IotThingModelListReqVO { |
| 13 | 12 | ||
| 14 | - @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED) | 13 | + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 15 | @NotNull(message = "产品编号不能为空") | 14 | @NotNull(message = "产品编号不能为空") |
| 16 | private Long productId; | 15 | private Long productId; |
| 17 | 16 | ||
| 18 | - @Schema(description = "功能标识") | 17 | + @Schema(description = "功能标识", example = "temperature") |
| 19 | private String identifier; | 18 | private String identifier; |
| 20 | 19 | ||
| 21 | - @Schema(description = "功能名称", example = "张三") | 20 | + @Schema(description = "功能名称", example = "温度") |
| 22 | private String name; | 21 | private String name; |
| 23 | 22 | ||
| 24 | @Schema(description = "功能类型", example = "1") | 23 | @Schema(description = "功能类型", example = "1") |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelPageReqVO.java
| @@ -9,21 +9,20 @@ import lombok.Data; | @@ -9,21 +9,20 @@ 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 | ||
| 13 | @Schema(description = "管理后台 - IoT 产品物模型分页 Request VO") | 12 | @Schema(description = "管理后台 - IoT 产品物模型分页 Request VO") |
| 14 | @Data | 13 | @Data |
| 15 | @EqualsAndHashCode(callSuper = true) | 14 | @EqualsAndHashCode(callSuper = true) |
| 16 | @ToString(callSuper = true) | 15 | @ToString(callSuper = true) |
| 17 | public class IotThingModelPageReqVO extends PageParam { | 16 | public class IotThingModelPageReqVO extends PageParam { |
| 18 | 17 | ||
| 19 | - @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED) | 18 | + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 20 | @NotNull(message = "产品编号不能为空") | 19 | @NotNull(message = "产品编号不能为空") |
| 21 | private Long productId; | 20 | private Long productId; |
| 22 | 21 | ||
| 23 | - @Schema(description = "功能标识") | 22 | + @Schema(description = "功能标识", example = "temperature") |
| 24 | private String identifier; | 23 | private String identifier; |
| 25 | 24 | ||
| 26 | - @Schema(description = "功能名称", example = "张三") | 25 | + @Schema(description = "功能名称", example = "温度") |
| 27 | private String name; | 26 | private String name; |
| 28 | 27 | ||
| 29 | @Schema(description = "功能类型", example = "1") | 28 | @Schema(description = "功能类型", example = "1") |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelRespVO.java
| @@ -10,7 +10,6 @@ import lombok.Data; | @@ -10,7 +10,6 @@ import lombok.Data; | ||
| 10 | 10 | ||
| 11 | import java.time.LocalDateTime; | 11 | import java.time.LocalDateTime; |
| 12 | 12 | ||
| 13 | -// TODO @puhui999:部分字段,可以用 cursor 加上 example | ||
| 14 | @Schema(description = "管理后台 - IoT 产品物模型 Response VO") | 13 | @Schema(description = "管理后台 - IoT 产品物模型 Response VO") |
| 15 | @Data | 14 | @Data |
| 16 | @ExcelIgnoreUnannotated | 15 | @ExcelIgnoreUnannotated |
| @@ -20,23 +19,23 @@ public class IotThingModelRespVO { | @@ -20,23 +19,23 @@ public class IotThingModelRespVO { | ||
| 20 | @ExcelProperty("产品ID") | 19 | @ExcelProperty("产品ID") |
| 21 | private Long id; | 20 | private Long id; |
| 22 | 21 | ||
| 23 | - @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) | 22 | + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 24 | private Long productId; | 23 | private Long productId; |
| 25 | 24 | ||
| 26 | - @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) | 25 | + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor") |
| 27 | @ExcelProperty("产品标识") | 26 | @ExcelProperty("产品标识") |
| 28 | private String productKey; | 27 | private String productKey; |
| 29 | 28 | ||
| 30 | - @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED) | 29 | + @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature") |
| 31 | private String identifier; | 30 | private String identifier; |
| 32 | 31 | ||
| 33 | - @Schema(description = "功能名称", requiredMode = Schema.RequiredMode.REQUIRED) | 32 | + @Schema(description = "功能名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "温度") |
| 34 | private String name; | 33 | private String name; |
| 35 | 34 | ||
| 36 | - @Schema(description = "功能描述", requiredMode = Schema.RequiredMode.REQUIRED) | 35 | + @Schema(description = "功能描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "测量当前环境温度") |
| 37 | private String description; | 36 | private String description; |
| 38 | 37 | ||
| 39 | - @Schema(description = "功能类型", requiredMode = Schema.RequiredMode.REQUIRED) | 38 | + @Schema(description = "功能类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 40 | private Integer type; | 39 | private Integer type; |
| 41 | 40 | ||
| 42 | @Schema(description = "属性", requiredMode = Schema.RequiredMode.REQUIRED) | 41 | @Schema(description = "属性", requiredMode = Schema.RequiredMode.REQUIRED) |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelSaveReqVO.java
| @@ -6,11 +6,11 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelP | @@ -6,11 +6,11 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelP | ||
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; | 6 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; |
| 7 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; | 7 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; |
| 8 | import io.swagger.v3.oas.annotations.media.Schema; | 8 | import io.swagger.v3.oas.annotations.media.Schema; |
| 9 | +import jakarta.validation.Valid; | ||
| 9 | import jakarta.validation.constraints.NotEmpty; | 10 | import jakarta.validation.constraints.NotEmpty; |
| 10 | import jakarta.validation.constraints.NotNull; | 11 | import jakarta.validation.constraints.NotNull; |
| 11 | import lombok.Data; | 12 | import lombok.Data; |
| 12 | 13 | ||
| 13 | -// TODO @puhui999:部分字段,可以用 cursor 加上 example | ||
| 14 | @Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO") | 14 | @Schema(description = "管理后台 - IoT 产品物模型新增/修改 Request VO") |
| 15 | @Data | 15 | @Data |
| 16 | public class IotThingModelSaveReqVO { | 16 | public class IotThingModelSaveReqVO { |
| @@ -22,33 +22,36 @@ public class IotThingModelSaveReqVO { | @@ -22,33 +22,36 @@ public class IotThingModelSaveReqVO { | ||
| 22 | @NotNull(message = "产品ID不能为空") | 22 | @NotNull(message = "产品ID不能为空") |
| 23 | private Long productId; | 23 | private Long productId; |
| 24 | 24 | ||
| 25 | - @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED) | 25 | + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_001") |
| 26 | @NotEmpty(message = "产品标识不能为空") | 26 | @NotEmpty(message = "产品标识不能为空") |
| 27 | private String productKey; | 27 | private String productKey; |
| 28 | 28 | ||
| 29 | - @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED) | 29 | + @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temp_monitor") |
| 30 | @NotEmpty(message = "功能标识不能为空") | 30 | @NotEmpty(message = "功能标识不能为空") |
| 31 | private String identifier; | 31 | private String identifier; |
| 32 | 32 | ||
| 33 | - @Schema(description = "功能名称", requiredMode = Schema.RequiredMode.REQUIRED) | 33 | + @Schema(description = "功能名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "温度监测器") |
| 34 | @NotEmpty(message = "功能名称不能为空") | 34 | @NotEmpty(message = "功能名称不能为空") |
| 35 | private String name; | 35 | private String name; |
| 36 | 36 | ||
| 37 | - @Schema(description = "功能描述", requiredMode = Schema.RequiredMode.REQUIRED) | 37 | + @Schema(description = "功能描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "用于监测环境温度的传感器") |
| 38 | private String description; | 38 | private String description; |
| 39 | 39 | ||
| 40 | - @Schema(description = "功能类型", requiredMode = Schema.RequiredMode.REQUIRED) | 40 | + @Schema(description = "功能类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 41 | @NotNull(message = "功能类型不能为空") | 41 | @NotNull(message = "功能类型不能为空") |
| 42 | @InEnum(IotThingModelTypeEnum.class) | 42 | @InEnum(IotThingModelTypeEnum.class) |
| 43 | private Integer type; | 43 | private Integer type; |
| 44 | 44 | ||
| 45 | @Schema(description = "属性", requiredMode = Schema.RequiredMode.REQUIRED) | 45 | @Schema(description = "属性", requiredMode = Schema.RequiredMode.REQUIRED) |
| 46 | + @Valid | ||
| 46 | private ThingModelProperty property; | 47 | private ThingModelProperty property; |
| 47 | 48 | ||
| 48 | @Schema(description = "服务", requiredMode = Schema.RequiredMode.REQUIRED) | 49 | @Schema(description = "服务", requiredMode = Schema.RequiredMode.REQUIRED) |
| 50 | + @Valid | ||
| 49 | private ThingModelService service; | 51 | private ThingModelService service; |
| 50 | 52 | ||
| 51 | @Schema(description = "事件", requiredMode = Schema.RequiredMode.REQUIRED) | 53 | @Schema(description = "事件", requiredMode = Schema.RequiredMode.REQUIRED) |
| 54 | + @Valid | ||
| 52 | private ThingModelEvent event; | 55 | private ThingModelEvent event; |
| 53 | 56 | ||
| 54 | } | 57 | } |
| 55 | \ No newline at end of file | 58 | \ 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
| @@ -55,7 +55,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -55,7 +55,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 55 | @Transactional(rollbackFor = Exception.class) | 55 | @Transactional(rollbackFor = Exception.class) |
| 56 | public Long createThingModel(IotThingModelSaveReqVO createReqVO) { | 56 | public Long createThingModel(IotThingModelSaveReqVO createReqVO) { |
| 57 | // 1.1 校验功能标识符在同一产品下是否唯一 | 57 | // 1.1 校验功能标识符在同一产品下是否唯一 |
| 58 | - validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier()); | 58 | + validateIdentifierUnique(null, createReqVO.getProductId(), createReqVO.getIdentifier()); |
| 59 | // 1.2 功能名称在同一产品下是否唯一 | 59 | // 1.2 功能名称在同一产品下是否唯一 |
| 60 | validateNameUnique(createReqVO.getProductId(), createReqVO.getName()); | 60 | validateNameUnique(createReqVO.getProductId(), createReqVO.getName()); |
| 61 | // 1.3 校验产品状态,发布状态下,不允许新增功能 | 61 | // 1.3 校验产品状态,发布状态下,不允许新增功能 |
| @@ -81,7 +81,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -81,7 +81,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 81 | // 1.1 校验功能是否存在 | 81 | // 1.1 校验功能是否存在 |
| 82 | validateProductThingModelMapperExists(updateReqVO.getId()); | 82 | validateProductThingModelMapperExists(updateReqVO.getId()); |
| 83 | // 1.2 校验功能标识符是否唯一 | 83 | // 1.2 校验功能标识符是否唯一 |
| 84 | - validateIdentifierUniqueForUpdate(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier()); | 84 | + validateIdentifierUnique(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier()); |
| 85 | // 1.3 校验产品状态,发布状态下,不允许操作功能 | 85 | // 1.3 校验产品状态,发布状态下,不允许操作功能 |
| 86 | validateProductStatus(updateReqVO.getProductId()); | 86 | validateProductStatus(updateReqVO.getProductId()); |
| 87 | 87 | ||
| @@ -159,8 +159,23 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -159,8 +159,23 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 159 | } | 159 | } |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | - // TODO @puhui999:这个方法,和 validateIdentifierUnique 可以融合下 | ||
| 163 | - private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) { | 162 | + private void validateIdentifierUnique(Long id, Long productId, String identifier) { |
| 163 | + // 1.0 情况一:创建时校验 | ||
| 164 | + if (id == null) { | ||
| 165 | + // 1.1 系统保留字段,不能用于标识符定义 | ||
| 166 | + if (StrUtil.equalsAny(identifier, "set", "get", "post", "property", "event", "time", "value")) { | ||
| 167 | + throw exception(THING_MODEL_IDENTIFIER_INVALID); | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + // 1.2 校验唯一 | ||
| 171 | + IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); | ||
| 172 | + if (thingModel != null) { | ||
| 173 | + throw exception(THING_MODEL_IDENTIFIER_EXISTS); | ||
| 174 | + } | ||
| 175 | + return; | ||
| 176 | + } | ||
| 177 | + | ||
| 178 | + // 2.0 情况二:更新时校验 | ||
| 164 | IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); | 179 | IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); |
| 165 | if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) { | 180 | if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) { |
| 166 | throw exception(THING_MODEL_IDENTIFIER_EXISTS); | 181 | throw exception(THING_MODEL_IDENTIFIER_EXISTS); |
| @@ -181,23 +196,10 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -181,23 +196,10 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 181 | } | 196 | } |
| 182 | } | 197 | } |
| 183 | 198 | ||
| 184 | - private void validateIdentifierUnique(Long productId, String identifier) { | ||
| 185 | - // 系统保留字段,不能用于标识符定义 | ||
| 186 | - if (StrUtil.equalsAny(identifier, "set", "get", "post", "property", "event", "time", "value")) { | ||
| 187 | - throw exception(THING_MODEL_IDENTIFIER_INVALID); | ||
| 188 | - } | ||
| 189 | - | ||
| 190 | - // 校验唯一 | ||
| 191 | - IotThingModelDO thingModel = thingModelMapper.selectByProductIdAndIdentifier(productId, identifier); | ||
| 192 | - if (thingModel != null) { | ||
| 193 | - throw exception(THING_MODEL_IDENTIFIER_EXISTS); | ||
| 194 | - } | ||
| 195 | - } | ||
| 196 | - | ||
| 197 | /** | 199 | /** |
| 198 | * 创建默认的事件和服务 | 200 | * 创建默认的事件和服务 |
| 199 | * | 201 | * |
| 200 | - * @param productId 产品编号 | 202 | + * @param productId 产品编号 |
| 201 | * @param productKey 产品标识 | 203 | * @param productKey 产品标识 |
| 202 | */ | 204 | */ |
| 203 | public void createDefaultEventsAndServices(Long productId, String productKey) { | 205 | public void createDefaultEventsAndServices(Long productId, String productKey) { |
| @@ -282,6 +284,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -282,6 +284,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 282 | } | 284 | } |
| 283 | 285 | ||
| 284 | // TODO @haohao:是不是不用生成这个?目前属性上报,是个批量接口 | 286 | // TODO @haohao:是不是不用生成这个?目前属性上报,是个批量接口 |
| 287 | + | ||
| 285 | /** | 288 | /** |
| 286 | * 生成属性上报事件 | 289 | * 生成属性上报事件 |
| 287 | */ | 290 | */ |
| @@ -298,6 +301,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -298,6 +301,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 298 | } | 301 | } |
| 299 | 302 | ||
| 300 | // TODO @haohao:是不是不用生成这个?目前属性上报,是个批量接口 | 303 | // TODO @haohao:是不是不用生成这个?目前属性上报,是个批量接口 |
| 304 | + | ||
| 301 | /** | 305 | /** |
| 302 | * 生成属性设置服务 | 306 | * 生成属性设置服务 |
| 303 | */ | 307 | */ |
| @@ -352,7 +356,8 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -352,7 +356,8 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 352 | } | 356 | } |
| 353 | 357 | ||
| 354 | @CacheEvict(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productKey") | 358 | @CacheEvict(value = RedisKeyConstants.THING_MODEL_LIST, key = "#productKey") |
| 355 | - public void deleteThingModelListCache0(String productKey) {} | 359 | + public void deleteThingModelListCache0(String productKey) { |
| 360 | + } | ||
| 356 | 361 | ||
| 357 | private IotThingModelServiceImpl getSelf() { | 362 | private IotThingModelServiceImpl getSelf() { |
| 358 | return SpringUtil.getBean(getClass()); | 363 | return SpringUtil.getBean(getClass()); |