Преглед изворни кода

!1171 【功能完善】IOT: ThingModel 服务和事件
Merge pull request !1171 from puhui999/iot

芋道源码 пре 7 месеци
родитељ
комит
4075fde765
13 измењених фајлова са 293 додато и 282 уклоњено
  1. 1 1
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotProductThingModelAccessModeEnum.java
  2. 20 0
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotProductThingModelParamDirectionEnum.java
  3. 20 0
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotProductThingModelServiceCallTypeEnum.java
  4. 21 0
      yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotProductThingModelServiceEventTypeEnum.java
  5. 0 7
      yudao-module-iot/yudao-module-iot-biz/pom.xml
  6. 1 1
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotProductThingModelController.http
  7. 22 6
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelEvent.java
  8. 50 0
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelInputOutputParam.java
  9. 0 4
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelProperty.java
  10. 28 7
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelService.java
  11. 0 26
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelArgument.java
  12. 0 4
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelStructDataSpecs.java
  13. 130 226
      yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotProductThingModelServiceImpl.java

+ 1 - 1
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotProductThingModelAccessModeEnum.java

@@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
 import lombok.Getter;
 
 /**
- * IOT 访问方式枚举类
+ * IOT 产品物模型属性读取类型枚举
  *
  * @author ahh
  */

+ 20 - 0
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotProductThingModelParamDirectionEnum.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.iot.enums.thingmodel;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * IOT 产品物模型参数是输入参数还是输出参数枚举
+ *
+ * @author HUIHUI
+ */
+@AllArgsConstructor
+@Getter
+public enum IotProductThingModelParamDirectionEnum {
+
+    INPUT("input"), // 输入参数
+    OUTPUT("output"); // 输出参数
+
+    private final String direction;
+
+}

+ 20 - 0
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotProductThingModelServiceCallTypeEnum.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.iot.enums.thingmodel;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * IOT 产品物模型服务调用方式枚举
+ *
+ * @author HUIHUI
+ */
+@AllArgsConstructor
+@Getter
+public enum IotProductThingModelServiceCallTypeEnum {
+
+    ASYNC("async"), // 异步调用
+    SYNC("sync"); // 同步调用
+
+    private final String type;
+
+}

+ 21 - 0
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotProductThingModelServiceEventTypeEnum.java

@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.iot.enums.thingmodel;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * IOT 产品物模型事件类型枚举
+ *
+ * @author HUIHUI
+ */
+@AllArgsConstructor
+@Getter
+public enum IotProductThingModelServiceEventTypeEnum {
+
+    INFO("info"), // 信息
+    ALERT("alert"), // 告警
+    ERROR("error"); // 故障
+
+    private final String type;
+
+}

+ 0 - 7
yudao-module-iot/yudao-module-iot-biz/pom.xml

@@ -25,13 +25,6 @@
             <version>${revision}</version>
         </dependency>
 
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-iot-plugin-api</artifactId>
-            <version>0.0.1</version>
-            <scope>compile</scope>
-        </dependency>
-
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>

+ 1 - 1
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotProductThingModelController.http

@@ -176,7 +176,7 @@ tenant-id: {{adminTenentId}}
 Authorization: Bearer {{token}}
 
 ### 请求 /iot/product-thing-model/get 接口 => 成功
-GET {{baseUrl}}/iot/product-thing-model/get?id=40
+GET {{baseUrl}}/iot/product-thing-model/get?id=67
 tenant-id: {{adminTenentId}}
 Authorization: Bearer {{token}}
 

+ 22 - 6
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelEvent.java

@@ -1,9 +1,15 @@
 package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model;
 
-import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelArgument;
+import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelServiceEventTypeEnum;
 import lombok.Data;
+
 import java.util.List;
 
+/**
+ * 物模型中的事件
+ *
+ * @author HUIHUI
+ */
 @Data
 public class ThingModelEvent {
 
@@ -16,17 +22,27 @@ public class ThingModelEvent {
      */
     private String name;
     /**
-     * 事件描述
+     * 是否是标准品类的必选事件。
+     *
+     * - true:是
+     * - false:否
      */
-    private String description;
-
+    private Boolean required;
     /**
      * 事件类型
      *
-     * "info"、"alert"、"error"
+     * 关联枚举 {@link IotProductThingModelServiceEventTypeEnum}
      */
     private String type;
-    private List<ThingModelArgument> outputData;
+    /**
+     * 事件的输出参数
+     *
+     * 输出参数定义事件调用后返回的结果或反馈信息,用于确认操作结果或提供额外的信息。
+     */
+    private List<ThingModelInputOutputParam> outputParams;
+    /**
+     * 标识设备需要执行的具体操作
+     */
     private String method;
 
 }

+ 50 - 0
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelInputOutputParam.java

@@ -0,0 +1,50 @@
+package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model;
+
+import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDataSpecs;
+import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelParamDirectionEnum;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * IOT 产品物模型中的参数 // TODO @puhui999 考虑要不改成 ThingModelParam ?
+ *
+ * @author HUIHUI
+ */
+@Data
+public class ThingModelInputOutputParam {
+
+    /**
+     * 参数标识符
+     */
+    private String identifier;
+    /**
+     * 参数名称
+     */
+    private String name;
+    /**
+     * 用于区分输入或输出参数
+     *
+     * 关联枚举 {@link IotProductThingModelParamDirectionEnum}
+     */
+    private String direction;
+    /**
+     * 参数的序号。从 0 开始排序,且不能重复。
+     *
+     * TODO 考虑要不要序号,感觉是要的, 先留一手看看
+     */
+    private Integer paraOrder;
+    /**
+     * 参数值的数据类型,与 dataSpecs 的 dataType 保持一致
+     */
+    private String dataType;
+    /**
+     * 参数值的数据类型(dataType)为非列表型(int、float、double、text、date、array)的数据规范存储在 dataSpecs 中
+     */
+    private ThingModelDataSpecs dataSpecs;
+    /**
+     * 参数值的数据类型(dataType)为列表型(enum、bool、struct)的数据规范存储在 dataSpecsList 中
+     */
+    private List<ThingModelDataSpecs> dataSpecsList;
+
+}

+ 0 - 4
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelProperty.java

@@ -24,10 +24,6 @@ public class ThingModelProperty {
      * 属性名称
      */
     private String name;
-    /**
-     * 属性描述
-     */
-    private String description;
     /**
      * 云端可以对该属性进行的操作类型
      *

+ 28 - 7
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelService.java

@@ -1,9 +1,15 @@
 package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model;
 
-import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelArgument;
+import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelServiceCallTypeEnum;
 import lombok.Data;
+
 import java.util.List;
 
+/**
+ * 物模型中的服务
+ *
+ * @author HUIHUI
+ */
 @Data
 public class ThingModelService {
 
@@ -16,18 +22,33 @@ public class ThingModelService {
      */
     private String name;
     /**
-     * 服务描述
+     * 是否是标准品类的必选服务。
+     *
+     * - true:是
+     * - false:否
      */
-    private String description;
-
+    private Boolean required;
     /**
      * 调用类型
      *
-     * "sync"、"async"
+     * 关联枚举 {@link IotProductThingModelServiceCallTypeEnum}
      */
     private String callType;
-    private List<ThingModelArgument> inputData;
-    private List<ThingModelArgument> outputData;
+    /**
+     * 服务的输入参数
+     *
+     * 输入参数定义服务调用时所需提供的信息,用于控制设备行为或执行特定任务
+     */
+    private List<ThingModelInputOutputParam> inputParams;
+    /**
+     * 服务的输出参数
+     *
+     * 输出参数定义服务调用后返回的结果或反馈信息,用于确认操作结果或提供额外的信息。
+     */
+    private List<ThingModelInputOutputParam> outputParams;
+    /**
+     * 标识设备需要执行的具体操作
+     */
     private String method;
 
 }

+ 0 - 26
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelArgument.java

@@ -1,26 +0,0 @@
-package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType;
-
-import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class ThingModelArgument {
-
-    public static final String DIRECTION_INPUT = "input";
-    public static final String DIRECTION_OUTPUT = "output";
-
-    private String identifier;
-    private String name;
-    /**
-     * 物模型中的属性
-     */
-    private ThingModelProperty property;
-    /**
-     * 用于区分输入或输出参数,"input" 或 "output"
-     */
-    private String direction;
-    private String description;
-
-}

+ 0 - 4
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelStructDataSpecs.java

@@ -25,10 +25,6 @@ public class ThingModelStructDataSpecs extends ThingModelDataSpecs {
      * 属性名称
      */
     private String name;
-    /**
-     * 属性描述
-     */
-    private String description;
     /**
      * 云端可以对该属性进行的操作类型
      * 关联枚举 {@link IotProductThingModelAccessModeEnum}

+ 130 - 226
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotProductThingModelServiceImpl.java

@@ -3,14 +3,10 @@ package cn.iocoder.yudao.module.iot.service.thingmodel;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 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.ThingModelInputOutputParam;
 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
-import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelArgument;
-import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelArrayDataSpecs;
-import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs;
 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotProductThingModelPageReqVO;
 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotProductThingModelSaveReqVO;
 import cn.iocoder.yudao.module.iot.convert.thingmodel.IotProductThingModelConvert;
@@ -18,8 +14,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotProductThingModelDO;
 import cn.iocoder.yudao.module.iot.dal.mysql.thingmodel.IotProductThingModelMapper;
 import cn.iocoder.yudao.module.iot.enums.product.IotProductStatusEnum;
-import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelAccessModeEnum;
-import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelTypeEnum;
+import cn.iocoder.yudao.module.iot.enums.thingmodel.*;
 import cn.iocoder.yudao.module.iot.service.product.IotProductService;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
@@ -30,8 +25,7 @@ import org.springframework.validation.annotation.Validated;
 import java.util.*;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
 
 /**
@@ -73,37 +67,10 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
         if (Objects.equals(createReqVO.getType(), IotProductThingModelTypeEnum.PROPERTY.getType())) {
             createDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey());
         }
+        // TODO @puhui999: 服务和事件的情况 method 怎么设置?在前端设置还是后端设置?
         return thingModel.getId();
     }
 
-    private void validateProductStatus(Long createReqVO) {
-        IotProductDO product = productService.getProduct(createReqVO);
-        if (Objects.equals(product.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) {
-            throw exception(PRODUCT_STATUS_NOT_ALLOW_THING_MODEL);
-        }
-    }
-
-    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))) {
-            throw exception(THING_MODEL_IDENTIFIER_INVALID);
-        }
-    }
-
-    private void validateNameUnique(Long productId, String name) {
-        IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndName(productId, name);
-        if (thingModel != null) {
-            throw exception(THING_MODEL_NAME_EXISTS);
-        }
-    }
-
-    private void validateIdentifierUnique(Long productId, String identifier) {
-        IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndIdentifier(productId, identifier);
-        if (thingModel != null) {
-            throw exception(THING_MODEL_IDENTIFIER_EXISTS);
-        }
-    }
-
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void updateProductThingModel(IotProductThingModelSaveReqVO updateReqVO) {
@@ -126,13 +93,6 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
         }
     }
 
-    private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) {
-        IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndIdentifier(productId, identifier);
-        if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) {
-            throw exception(THING_MODEL_IDENTIFIER_EXISTS);
-        }
-    }
-
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void deleteProductThingModel(Long id) {
@@ -154,17 +114,6 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
         }
     }
 
-    /**
-     * 校验功能是否存在
-     *
-     * @param id 功能编号
-     */
-    private void validateProductThingModelMapperExists(Long id) {
-        if (productThingModelMapper.selectById(id) == null) {
-            throw exception(THING_MODEL_NOT_EXISTS);
-        }
-    }
-
     @Override
     public IotProductThingModelDO getProductThingModel(Long id) {
         return productThingModelMapper.selectById(id);
@@ -185,6 +134,52 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
         return productThingModelMapper.selectListByProductKey(productKey);
     }
 
+    /**
+     * 校验功能是否存在
+     *
+     * @param id 功能编号
+     */
+    private void validateProductThingModelMapperExists(Long id) {
+        if (productThingModelMapper.selectById(id) == null) {
+            throw exception(THING_MODEL_NOT_EXISTS);
+        }
+    }
+
+    private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) {
+        IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndIdentifier(productId, identifier);
+        if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) {
+            throw exception(THING_MODEL_IDENTIFIER_EXISTS);
+        }
+    }
+
+    private void validateProductStatus(Long createReqVO) {
+        IotProductDO product = productService.getProduct(createReqVO);
+        if (Objects.equals(product.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) {
+            throw exception(PRODUCT_STATUS_NOT_ALLOW_THING_MODEL);
+        }
+    }
+
+    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))) {
+            throw exception(THING_MODEL_IDENTIFIER_INVALID);
+        }
+    }
+
+    private void validateNameUnique(Long productId, String name) {
+        IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndName(productId, name);
+        if (thingModel != null) {
+            throw exception(THING_MODEL_NAME_EXISTS);
+        }
+    }
+
+    private void validateIdentifierUnique(Long productId, String identifier) {
+        IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndIdentifier(productId, identifier);
+        if (thingModel != null) {
+            throw exception(THING_MODEL_IDENTIFIER_EXISTS);
+        }
+    }
+
     /**
      * 创建默认的事件和服务
      */
@@ -195,231 +190,140 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
 
         // 2. 生成新的事件和服务列表
         List<IotProductThingModelDO> newThingModelList = new ArrayList<>();
-        // 生成属性上报事件
+        // 2.1 生成属性上报事件
         ThingModelEvent propertyPostEvent = generatePropertyPostEvent(propertyList);
         if (propertyPostEvent != null) {
-            IotProductThingModelDO eventThingModel = buildEventThingModelDO(productId, productKey, propertyPostEvent);
-            newThingModelList.add(eventThingModel);
+            newThingModelList.add(buildEventThingModelDO(productId, productKey, propertyPostEvent, "属性上报事件"));
         }
-        // 生成属性设置服务
+        // 2.2 生成属性设置服务
         ThingModelService propertySetService = generatePropertySetService(propertyList);
         if (propertySetService != null) {
-            IotProductThingModelDO setServiceThingModel = buildServiceThingModelDO(productId, productKey, propertySetService);
-            newThingModelList.add(setServiceThingModel);
+            newThingModelList.add(buildServiceThingModelDO(productId, productKey, propertySetService, "属性设置服务"));
         }
-        // 生成属性获取服务
+        // 2.3 生成属性获取服务
         ThingModelService propertyGetService = generatePropertyGetService(propertyList);
         if (propertyGetService != null) {
-            IotProductThingModelDO getServiceThingModel = buildServiceThingModelDO(productId, productKey, propertyGetService);
-            newThingModelList.add(getServiceThingModel);
+            newThingModelList.add(buildServiceThingModelDO(productId, productKey, propertyGetService,"属性获取服务"));
         }
 
-        // 3. 获取数据库中的默认的旧事件和服务列表
+        // 3.1 获取数据库中的默认的旧事件和服务列表
         List<IotProductThingModelDO> oldThingModelList = productThingModelMapper.selectListByProductIdAndIdentifiersAndTypes(
                 productId,
                 Arrays.asList("post", "set", "get"),
                 Arrays.asList(IotProductThingModelTypeEnum.EVENT.getType(), IotProductThingModelTypeEnum.SERVICE.getType())
         );
+        // 3.2 创建默认的事件和服务
+        createDefaultEventsAndServices(oldThingModelList, newThingModelList);
+    }
 
-        // 3.1 使用 diffList 方法比较新旧列表
+    /**
+     * 创建默认的事件和服务
+     */
+    private void createDefaultEventsAndServices(List<IotProductThingModelDO> oldThingModelList, List<IotProductThingModelDO> newThingModelList) {
+        // 1.1 使用 diffList 方法比较新旧列表
         List<List<IotProductThingModelDO>> diffResult = diffList(oldThingModelList, newThingModelList,
-                // 继续使用 identifier 和 type 进行比较:这样可以准确地匹配对应的功能对象。
-                (oldFunc, newFunc) -> Objects.equals(oldFunc.getIdentifier(), newFunc.getIdentifier())
-                        && Objects.equals(oldFunc.getType(), newFunc.getType()));
-        List<IotProductThingModelDO> createList = diffResult.get(0); // 需要新增的
-        List<IotProductThingModelDO> updateList = diffResult.get(1); // 需要更新的
-        List<IotProductThingModelDO> deleteList = diffResult.get(2); // 需要删除的
-
-        // 3.2 批量执行数据库操作
-        // 新增数据库中的新事件和服务列表
-        if (CollUtil.isNotEmpty(createList)) {
-            productThingModelMapper.insertBatch(createList);
+                (oldVal, newVal) -> {
+                    // 继续使用 identifier 和 type 进行比较:这样可以准确地匹配对应的功能对象。
+                    boolean same = Objects.equals(oldVal.getIdentifier(), newVal.getIdentifier())
+                            && Objects.equals(oldVal.getType(), newVal.getType());
+                    if (same) {
+                        newVal.setId(oldVal.getId()); // 设置编号
+                    }
+                    return same;
+                });
+        // 1.2 批量添加、修改、删除
+        if (CollUtil.isNotEmpty(diffResult.get(0))) {
+            productThingModelMapper.insertBatch(diffResult.get(0));
         }
-        // 更新数据库中的事件和服务列表
-        if (CollUtil.isNotEmpty(updateList)) {
-            // 首先,为每个需要更新的对象设置其对应的 ID
-            updateList.forEach(updateFunc -> {
-                IotProductThingModelDO oldFunc = findThingModelByIdentifierAndType(
-                        oldThingModelList, updateFunc.getIdentifier(), updateFunc.getType());
-                if (oldFunc != null) {
-                    updateFunc.setId(oldFunc.getId());
-                }
-            });
-            // 过滤掉没有设置 ID 的对象
-            List<IotProductThingModelDO> validUpdateList = filterList(updateList, thingModel -> thingModel.getId() != null);
-            // 执行批量更新
-            if (CollUtil.isNotEmpty(validUpdateList)) {
-                productThingModelMapper.updateBatch(validUpdateList);
-            }
+        if (CollUtil.isNotEmpty(diffResult.get(1))) {
+            productThingModelMapper.updateBatch(diffResult.get(1));
         }
-
-        // 删除数据库中的旧事件和服务列表
-        if (CollUtil.isNotEmpty(deleteList)) {
-            Set<Long> idsToDelete = CollectionUtils.convertSet(deleteList, IotProductThingModelDO::getId);
-            productThingModelMapper.deleteByIds(idsToDelete);
+        if (CollUtil.isNotEmpty(diffResult.get(2))) {
+            productThingModelMapper.deleteByIds(convertSet(diffResult.get(2), IotProductThingModelDO::getId));
         }
     }
 
-    /**
-     * 根据标识符和类型查找功能对象
-     */
-    private IotProductThingModelDO findThingModelByIdentifierAndType(List<IotProductThingModelDO> thingModelList,
-                                                                     String identifier, Integer type) {
-        return CollUtil.findOne(thingModelList, func ->
-                Objects.equals(func.getIdentifier(), identifier) && Objects.equals(func.getType(), type));
-    }
-
     /**
      * 构建事件功能对象
      */
-    private IotProductThingModelDO buildEventThingModelDO(Long productId, String productKey, ThingModelEvent event) {
-        return new IotProductThingModelDO()
-                .setProductId(productId)
-                .setProductKey(productKey)
-                .setIdentifier(event.getIdentifier())
-                .setName(event.getName())
-                .setDescription(event.getDescription())
-                .setType(IotProductThingModelTypeEnum.EVENT.getType())
-                .setEvent(event);
+    private IotProductThingModelDO buildEventThingModelDO(Long productId, String productKey, ThingModelEvent event,
+                                                          String description) {
+        return new IotProductThingModelDO().setProductId(productId).setProductKey(productKey)
+                .setIdentifier(event.getIdentifier()).setName(event.getName()).setDescription(description)
+                .setType(IotProductThingModelTypeEnum.EVENT.getType()).setEvent(event);
     }
 
     /**
      * 构建服务功能对象
      */
-    private IotProductThingModelDO buildServiceThingModelDO(Long productId, String productKey, ThingModelService service) {
-        return new IotProductThingModelDO()
-                .setProductId(productId)
-                .setProductKey(productKey)
-                .setIdentifier(service.getIdentifier())
-                .setName(service.getName())
-                .setDescription(service.getDescription())
-                .setType(IotProductThingModelTypeEnum.SERVICE.getType())
-                .setService(service);
+    private IotProductThingModelDO buildServiceThingModelDO(Long productId, String productKey, ThingModelService service,
+                                                            String description) {
+        return new IotProductThingModelDO().setProductId(productId).setProductKey(productKey)
+                .setIdentifier(service.getIdentifier()).setName(service.getName()).setDescription(description)
+                .setType(IotProductThingModelTypeEnum.SERVICE.getType()).setService(service);
     }
 
     /**
      * 生成属性上报事件
      */
-    private ThingModelEvent generatePropertyPostEvent(List<IotProductThingModelDO> propertyList) {
-        if (CollUtil.isEmpty(propertyList)) {
+    private ThingModelEvent generatePropertyPostEvent(List<IotProductThingModelDO> thingModelList) {
+        // 1.1 没有属性则不生成
+        if (CollUtil.isEmpty(thingModelList)) {
             return null;
         }
 
-        ThingModelEvent event = new ThingModelEvent()
-                .setIdentifier("post")
-                .setName("属性上报")
-                .setType("info")
-                .setDescription("属性上报事件")
-                .setMethod("thing.event.property.post");
-
-        // 将属性列表转换为事件的输出参数
-        List<ThingModelArgument> outputData = new ArrayList<>();
-        for (IotProductThingModelDO thingModel : propertyList) {
-            ThingModelArgument arg = new ThingModelArgument()
-                    .setIdentifier(thingModel.getIdentifier())
-                    .setName(thingModel.getName())
-                    .setProperty(thingModel.getProperty())
-                    .setDescription(thingModel.getDescription())
-                    .setDirection("output"); // 设置为输出参数
-            outputData.add(arg);
-        }
-        event.setOutputData(outputData);
-        return event;
+        // 1.2 生成属性上报事件
+        return new ThingModelEvent().setIdentifier("post").setName("属性上报").setMethod("thing.event.property.post")
+                .setType(IotProductThingModelServiceEventTypeEnum.INFO.getType())
+                .setOutputParams(buildInputOutputParam(thingModelList, IotProductThingModelParamDirectionEnum.OUTPUT));
     }
 
     /**
      * 生成属性设置服务
      */
-    private ThingModelService generatePropertySetService(List<IotProductThingModelDO> propertyList) {
-        if (propertyList == null || propertyList.isEmpty()) {
-            return null;
-        }
-
-        List<ThingModelArgument> inputData = new ArrayList<>();
-        for (IotProductThingModelDO thingModel : propertyList) {
-            ThingModelProperty property = thingModel.getProperty();
-            if (IotProductThingModelAccessModeEnum.READ_WRITE.getMode().equals(property.getAccessMode())) {
-                ThingModelArgument arg = new ThingModelArgument()
-                        .setIdentifier(property.getIdentifier())
-                        .setName(property.getName())
-                        .setProperty(property)
-                        .setDescription(property.getDescription())
-                        .setDirection("input"); // 设置为输入参数
-                inputData.add(arg);
-            }
-        }
-        if (inputData.isEmpty()) {
-            // 如果没有可写属性,不生成属性设置服务
+    private ThingModelService generatePropertySetService(List<IotProductThingModelDO> thingModelList) {
+        // 1.1 过滤出所有可写属性
+        thingModelList = filterList(thingModelList, thingModel ->
+                IotProductThingModelAccessModeEnum.READ_WRITE.getMode().equals(thingModel.getProperty().getAccessMode()));
+        // 1.2 没有可写属性则不生成
+        if (CollUtil.isEmpty(thingModelList)) {
             return null;
         }
 
-        // 属性设置服务一般不需要输出参数
-        return new ThingModelService()
-                .setIdentifier("set")
-                .setName("属性设置")
-                .setCallType("async")
-                .setDescription("属性设置服务")
-                .setMethod("thing.service.property.set")
-                .setInputData(inputData)
-                // 属性设置服务一般不需要输出参数
-                .setOutputData(new ArrayList<>());
+        // 2. 生成属性设置服务
+        return new ThingModelService().setIdentifier("set").setName("属性设置").setMethod("thing.service.property.set")
+                .setCallType(IotProductThingModelServiceCallTypeEnum.ASYNC.getType())
+                .setInputParams(buildInputOutputParam(thingModelList, IotProductThingModelParamDirectionEnum.INPUT))
+                .setOutputParams(Collections.emptyList()); // 属性设置服务一般不需要输出参数
     }
 
     /**
      * 生成属性获取服务
      */
-    private ThingModelService generatePropertyGetService(List<IotProductThingModelDO> propertyList) {
-        if (propertyList == null || propertyList.isEmpty()) {
+    private ThingModelService generatePropertyGetService(List<IotProductThingModelDO> thingModelList) {
+        // 1.1 没有属性则不生成
+        if (CollUtil.isEmpty(thingModelList)) {
             return null;
         }
 
-        List<ThingModelArgument> outputData = new ArrayList<>();
-        for (IotProductThingModelDO thingModelDO : propertyList) {
-            ThingModelProperty property = thingModelDO.getProperty();
-            if (ObjectUtils.equalsAny(property.getAccessMode(),
-                    IotProductThingModelAccessModeEnum.READ_ONLY.getMode(), IotProductThingModelAccessModeEnum.READ_WRITE.getMode())) {
-                ThingModelArgument arg = new ThingModelArgument()
-                        .setIdentifier(property.getIdentifier())
-                        .setName(property.getName())
-                        .setProperty(property)
-                        .setDescription(property.getDescription())
-                        .setDirection("output"); // 设置为输出参数
-                outputData.add(arg);
-            }
-        }
-        if (outputData.isEmpty()) {
-            // 如果没有可读属性,不生成属性获取服务
-            return null;
-        }
+        // 1.2 生成属性获取服务
+        return new ThingModelService().setIdentifier("get").setName("属性获取").setMethod("thing.service.property.get")
+                .setCallType(IotProductThingModelServiceCallTypeEnum.ASYNC.getType())
+                .setInputParams(buildInputOutputParam(thingModelList, IotProductThingModelParamDirectionEnum.INPUT))
+                .setOutputParams(buildInputOutputParam(thingModelList, IotProductThingModelParamDirectionEnum.OUTPUT));
+    }
 
-        ThingModelService service = new ThingModelService()
-                .setIdentifier("get")
-                .setName("属性获取")
-                .setCallType("async")
-                .setDescription("属性获取服务")
-                .setMethod("thing.service.property.get");
-
-        // 定义输入参数:属性标识符列表
-        ThingModelArgument inputArg = new ThingModelArgument()
-                .setIdentifier("properties")
-                .setName("属性标识符列表")
-                .setDescription("需要获取的属性标识符列表")
-                .setDirection("input"); // 设置为输入参数
-
-        // 创建数组类型,元素类型为文本类型(字符串)TODO @puhui999: 还得研究研究
-        ThingModelArrayDataSpecs arrayType = new ThingModelArrayDataSpecs();
-        arrayType.setDataType("array");
-        inputArg.setProperty(new ThingModelProperty().setIdentifier(inputArg.getIdentifier()).setName(inputArg.getName())
-                .setDescription(inputArg.getDescription()).setDataSpecs(arrayType));
-
-        ThingModelDateOrTextDataSpecs textType = new ThingModelDateOrTextDataSpecs();
-        textType.setDataType("text");
-        inputArg.setProperty(new ThingModelProperty().setIdentifier(inputArg.getIdentifier()).setName(inputArg.getName())
-                .setDescription(inputArg.getDescription()).setDataSpecs(textType));
-
-        service.setInputData(Collections.singletonList(inputArg));
-        service.setOutputData(outputData);
-        return service;
+    /**
+     * 构建输入/输出参数列表
+     *
+     * @param thingModelList 属性列表
+     * @return 输入/输出参数列表
+     */
+    private List<ThingModelInputOutputParam> buildInputOutputParam(List<IotProductThingModelDO> thingModelList,
+                                                                   IotProductThingModelParamDirectionEnum directionEnum) {
+        return convertList(thingModelList, thingModel ->
+                BeanUtils.toBean(thingModel.getProperty(), ThingModelInputOutputParam.class).setParaOrder(0) // TODO @puhui999: 先搞个默认值看看怎么个事
+                        .setDirection(directionEnum.getDirection()));
     }
 
 }