Commit 6abd67a38c671219f138a52a50d4d4ceda632af3

Authored by puhui999
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());