Commit edc6a8ad4a77b122b88da4db31525aea4ae3d369

Authored by 安浩浩
1 parent c0e2bdbd

修改:IOT 物模型接口增加事物,优化创建默认的事件和服务

yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
@@ -18,4 +18,7 @@ public interface ErrorCodeConstants { @@ -18,4 +18,7 @@ public interface ErrorCodeConstants {
18 ErrorCode THINK_MODEL_FUNCTION_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在"); 18 ErrorCode THINK_MODEL_FUNCTION_NOT_EXISTS = new ErrorCode(1_050_002_000, "产品物模型不存在");
19 ErrorCode THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY = new ErrorCode(1_050_002_001, "ProductKey 对应的产品物模型已存在"); 19 ErrorCode THINK_MODEL_FUNCTION_EXISTS_BY_PRODUCT_KEY = new ErrorCode(1_050_002_001, "ProductKey 对应的产品物模型已存在");
20 ErrorCode THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER = new ErrorCode(1_050_002_002, "产品物模型标识已存在"); 20 ErrorCode THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER = new ErrorCode(1_050_002_002, "产品物模型标识已存在");
  21 +
  22 + // ========== IoT 设备 1-050-003-000 ============
  23 + ErrorCode DEVICE_NOT_EXISTS = new ErrorCode(1_050_003_000, "设备不存在");
21 } 24 }
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotAccessModeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.enums.product;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Getter;
  5 +
  6 +/**
  7 + * IOT 访问方式枚举类
  8 + *
  9 + * @author ahh
  10 + */
  11 +@AllArgsConstructor
  12 +@Getter
  13 +public enum IotAccessModeEnum {
  14 +
  15 + READ("r"),
  16 + WRITE("w"),
  17 + READ_WRITE("rw");
  18 +
  19 + private final String mode;
  20 +
  21 + public String getMode() {
  22 + return mode;
  23 + }
  24 +
  25 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/IotThinkModelFunctionController.http
@@ -37,7 +37,7 @@ tenant-id: {{adminTenentId}} @@ -37,7 +37,7 @@ tenant-id: {{adminTenentId}}
37 Authorization: Bearer {{token}} 37 Authorization: Bearer {{token}}
38 38
39 { 39 {
40 - "id": 3, 40 + "id": 1,
41 "productId": 1001, 41 "productId": 1001,
42 "productKey": "smart-sensor-001", 42 "productKey": "smart-sensor-001",
43 "identifier": "Temperature", 43 "identifier": "Temperature",
@@ -62,8 +62,13 @@ Authorization: Bearer {{token}} @@ -62,8 +62,13 @@ Authorization: Bearer {{token}}
62 } 62 }
63 } 63 }
64 64
  65 +### 请求 /iot/think-model-function/delete 接口 => 成功
  66 +DELETE {{baseUrl}}/iot/think-model-function/delete?id=1
  67 +tenant-id: {{adminTenentId}}
  68 +Authorization: Bearer {{token}}
  69 +
65 ### 请求 /iot/think-model-function/get 接口 => 成功 70 ### 请求 /iot/think-model-function/get 接口 => 成功
66 -GET {{baseUrl}}/iot/think-model-function/get?id=3 71 +GET {{baseUrl}}/iot/think-model-function/get?id=4
67 tenant-id: {{adminTenentId}} 72 tenant-id: {{adminTenentId}}
68 Authorization: Bearer {{token}} 73 Authorization: Bearer {{token}}
69 74
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thinkmodelfunction/IotThinkModelFunctionMapper.java
1 package cn.iocoder.yudao.module.iot.dal.mysql.thinkmodelfunction; 1 package cn.iocoder.yudao.module.iot.dal.mysql.thinkmodelfunction;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
4 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
5 import org.apache.ibatis.annotations.Mapper; 6 import org.apache.ibatis.annotations.Mapper;
6 7
@@ -28,4 +29,9 @@ public interface IotThinkModelFunctionMapper extends BaseMapperX<IotThinkModelFu @@ -28,4 +29,9 @@ public interface IotThinkModelFunctionMapper extends BaseMapperX<IotThinkModelFu
28 IotThinkModelFunctionDO::getType, type); 29 IotThinkModelFunctionDO::getType, type);
29 } 30 }
30 31
  32 + default List<IotThinkModelFunctionDO> selectListByProductIdAndTypes(Long productId, List<Integer> list) {
  33 + return selectList(new LambdaQueryWrapperX<IotThinkModelFunctionDO>()
  34 + .eq(IotThinkModelFunctionDO::getProductId, productId)
  35 + .in(IotThinkModelFunctionDO::getType, list));
  36 + }
31 } 37 }
32 \ No newline at end of file 38 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/emq/service/EmqxServiceImpl.java
@@ -30,7 +30,7 @@ public class EmqxServiceImpl implements EmqxService { @@ -30,7 +30,7 @@ public class EmqxServiceImpl implements EmqxService {
30 public void subscribe(MqttClient client) { 30 public void subscribe(MqttClient client) {
31 try { 31 try {
32 // 订阅默认主题,可以根据需要修改 32 // 订阅默认主题,可以根据需要修改
33 - client.subscribe("$share/yudao/+/+/#", 1); 33 +// client.subscribe("$share/yudao/+/+/#", 1);
34 log.info("订阅默认主题成功"); 34 log.info("订阅默认主题成功");
35 } catch (Exception e) { 35 } catch (Exception e) {
36 log.error("订阅默认主题失败", e); 36 log.error("订阅默认主题失败", e);
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thinkmodelfunction/IotThinkModelFunctionServiceImpl.java
1 package cn.iocoder.yudao.module.iot.service.thinkmodelfunction; 1 package cn.iocoder.yudao.module.iot.service.thinkmodelfunction;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
3 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent; 5 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelEvent;
4 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty; 6 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelProperty;
5 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService; 7 import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.thingModel.ThingModelService;
@@ -11,18 +13,19 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThi @@ -11,18 +13,19 @@ import cn.iocoder.yudao.module.iot.controller.admin.thinkmodelfunction.vo.IotThi
11 import cn.iocoder.yudao.module.iot.convert.thinkmodelfunction.IotThinkModelFunctionConvert; 13 import cn.iocoder.yudao.module.iot.convert.thinkmodelfunction.IotThinkModelFunctionConvert;
12 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO; 14 import cn.iocoder.yudao.module.iot.dal.dataobject.thinkmodelfunction.IotThinkModelFunctionDO;
13 import cn.iocoder.yudao.module.iot.dal.mysql.thinkmodelfunction.IotThinkModelFunctionMapper; 15 import cn.iocoder.yudao.module.iot.dal.mysql.thinkmodelfunction.IotThinkModelFunctionMapper;
  16 +import cn.iocoder.yudao.module.iot.enums.product.IotAccessModeEnum;
14 import cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum; 17 import cn.iocoder.yudao.module.iot.enums.product.IotThingModelTypeEnum;
15 import jakarta.annotation.Resource; 18 import jakarta.annotation.Resource;
16 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
17 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
  21 +import org.springframework.transaction.annotation.Transactional;
18 import org.springframework.validation.annotation.Validated; 22 import org.springframework.validation.annotation.Validated;
19 23
20 -import java.util.ArrayList;  
21 -import java.util.Collections;  
22 -import java.util.List;  
23 -import java.util.Objects; 24 +import java.util.*;
  25 +import java.util.stream.Collectors;
24 26
25 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
26 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER; 29 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER;
27 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_NOT_EXISTS; 30 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.THINK_MODEL_FUNCTION_NOT_EXISTS;
28 31
@@ -40,7 +43,7 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -40,7 +43,7 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
40 private IotThinkModelFunctionMapper thinkModelFunctionMapper; 43 private IotThinkModelFunctionMapper thinkModelFunctionMapper;
41 44
42 @Override 45 @Override
43 - // TODO @haohao:事务 46 + @Transactional(rollbackFor = Exception.class)
44 public Long createThinkModelFunction(IotThinkModelFunctionSaveReqVO createReqVO) { 47 public Long createThinkModelFunction(IotThinkModelFunctionSaveReqVO createReqVO) {
45 // 1. 校验功能标识符在同一产品下是否唯一 48 // 1. 校验功能标识符在同一产品下是否唯一
46 validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier()); 49 validateIdentifierUnique(createReqVO.getProductId(), createReqVO.getIdentifier());
@@ -51,8 +54,11 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -51,8 +54,11 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
51 54
52 // 3. 如果创建的是属性,需要更新默认的事件和服务 55 // 3. 如果创建的是属性,需要更新默认的事件和服务
53 if (Objects.equals(createReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { 56 if (Objects.equals(createReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
54 - // TODO @haohao:最好使用 createDefaultEventsAndServices。原因是:generate 更多在目前项目里,是创建对象,不涉及到 insert db。  
55 - generateDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey()); 57 + // 获取当前属性列表,并添加新插入的属性
  58 + List<IotThinkModelFunctionDO> propertyList = thinkModelFunctionMapper
  59 + .selectListByProductIdAndType(createReqVO.getProductId(), IotThingModelTypeEnum.PROPERTY.getType());
  60 + propertyList.add(function);
  61 + createDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey(), propertyList);
56 } 62 }
57 return function.getId(); 63 return function.getId();
58 } 64 }
@@ -65,33 +71,41 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -65,33 +71,41 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
65 } 71 }
66 72
67 @Override 73 @Override
68 - // TODO @haohao:事务 74 + @Transactional(rollbackFor = Exception.class)
69 public void updateThinkModelFunction(IotThinkModelFunctionSaveReqVO updateReqVO) { 75 public void updateThinkModelFunction(IotThinkModelFunctionSaveReqVO updateReqVO) {
70 - // 1.1 校验功能是否存在 76 + // 1. 校验功能是否存在
71 validateThinkModelFunctionExists(updateReqVO.getId()); 77 validateThinkModelFunctionExists(updateReqVO.getId());
72 - // 1.2 校验功能标识符是否唯一 78 + // 2. 校验功能标识符是否唯一
73 validateIdentifierUniqueForUpdate(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier()); 79 validateIdentifierUniqueForUpdate(updateReqVO.getId(), updateReqVO.getProductId(), updateReqVO.getIdentifier());
74 80
75 - // 2. 更新数据库 81 + // 3. 更新数据库
76 IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(updateReqVO); 82 IotThinkModelFunctionDO thinkModelFunction = IotThinkModelFunctionConvert.INSTANCE.convert(updateReqVO);
77 thinkModelFunctionMapper.updateById(thinkModelFunction); 83 thinkModelFunctionMapper.updateById(thinkModelFunction);
78 84
79 - // 3. 如果更新的是属性,需要更新默认的事件和服务 85 + // 4. 如果更新的是属性,需要更新默认的事件和服务
80 if (Objects.equals(updateReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { 86 if (Objects.equals(updateReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
81 - generateDefaultEventsAndServices(updateReqVO.getProductId(), updateReqVO.getProductKey()); 87 + // 获取当前属性列表,更新其中的属性
  88 + List<IotThinkModelFunctionDO> propertyList = thinkModelFunctionMapper
  89 + .selectListByProductIdAndType(updateReqVO.getProductId(), IotThingModelTypeEnum.PROPERTY.getType());
  90 + for (int i = 0; i < propertyList.size(); i++) {
  91 + if (propertyList.get(i).getId().equals(thinkModelFunction.getId())) {
  92 + propertyList.set(i, thinkModelFunction);
  93 + break;
  94 + }
  95 + }
  96 + createDefaultEventsAndServices(updateReqVO.getProductId(), updateReqVO.getProductKey(), propertyList);
82 } 97 }
83 } 98 }
84 99
85 private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) { 100 private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) {
86 IotThinkModelFunctionDO function = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, identifier); 101 IotThinkModelFunctionDO function = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, identifier);
87 - // TODO !function.getId().equals(id) 使用 ObjectUtil.notEquals 。逻辑里,尽量避免 ! 取反。用不等于会比 ! 更容易理解  
88 - if (function != null && !function.getId().equals(id)) { 102 + if (function != null && ObjectUtil.notEqual(function.getId(), id)) {
89 throw exception(THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER); 103 throw exception(THINK_MODEL_FUNCTION_EXISTS_BY_IDENTIFIER);
90 } 104 }
91 } 105 }
92 106
93 @Override 107 @Override
94 - // TODO @haohao:事务 108 + @Transactional(rollbackFor = Exception.class)
95 public void deleteThinkModelFunction(Long id) { 109 public void deleteThinkModelFunction(Long id) {
96 // 1. 校验功能是否存在 110 // 1. 校验功能是否存在
97 IotThinkModelFunctionDO functionDO = thinkModelFunctionMapper.selectById(id); 111 IotThinkModelFunctionDO functionDO = thinkModelFunctionMapper.selectById(id);
@@ -104,7 +118,11 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -104,7 +118,11 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
104 118
105 // 3. 如果删除的是属性,需要更新默认的事件和服务 119 // 3. 如果删除的是属性,需要更新默认的事件和服务
106 if (Objects.equals(functionDO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) { 120 if (Objects.equals(functionDO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
107 - generateDefaultEventsAndServices(functionDO.getProductId(), functionDO.getProductKey()); 121 + // 获取当前属性列表,移除已删除的属性
  122 + List<IotThinkModelFunctionDO> propertyList = thinkModelFunctionMapper
  123 + .selectListByProductIdAndType(functionDO.getProductId(), IotThingModelTypeEnum.PROPERTY.getType());
  124 + propertyList.removeIf(property -> property.getId().equals(id));
  125 + createDefaultEventsAndServices(functionDO.getProductId(), functionDO.getProductKey(), propertyList);
108 } 126 }
109 } 127 }
110 128
@@ -130,58 +148,137 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -130,58 +148,137 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
130 } 148 }
131 149
132 /** 150 /**
133 - * 生成默认的事件和服务 151 + * 创建默认的事件和服务
134 */ 152 */
135 - public void generateDefaultEventsAndServices(Long productId, String productKey) {  
136 - // 获取当前产品的所有属性列表  
137 - List<IotThinkModelFunctionDO> propertyList = thinkModelFunctionMapper.selectListByProductIdAndType(productId, IotThingModelTypeEnum.PROPERTY.getType()); 153 + public void createDefaultEventsAndServices(Long productId, String productKey, List<IotThinkModelFunctionDO> propertyList) {
  154 + // 1. 生成新的事件和服务列表
  155 + List<IotThinkModelFunctionDO> newFunctionList = new ArrayList<>();
138 156
139 // 生成属性上报事件 157 // 生成属性上报事件
140 ThingModelEvent propertyPostEvent = generatePropertyPostEvent(propertyList); 158 ThingModelEvent propertyPostEvent = generatePropertyPostEvent(propertyList);
141 if (propertyPostEvent != null) { 159 if (propertyPostEvent != null) {
142 - saveOrUpdateEvent(productId, productKey, propertyPostEvent); 160 + IotThinkModelFunctionDO eventFunction = buildEventFunctionDO(productId, productKey, propertyPostEvent);
  161 + newFunctionList.add(eventFunction);
143 } 162 }
144 163
145 // 生成属性设置服务 164 // 生成属性设置服务
146 ThingModelService propertySetService = generatePropertySetService(propertyList); 165 ThingModelService propertySetService = generatePropertySetService(propertyList);
147 if (propertySetService != null) { 166 if (propertySetService != null) {
148 - saveOrUpdateService(productId, productKey, propertySetService); 167 + IotThinkModelFunctionDO setServiceFunction = buildServiceFunctionDO(productId, productKey, propertySetService);
  168 + newFunctionList.add(setServiceFunction);
149 } 169 }
150 170
151 // 生成属性获取服务 171 // 生成属性获取服务
152 ThingModelService propertyGetService = generatePropertyGetService(propertyList); 172 ThingModelService propertyGetService = generatePropertyGetService(propertyList);
153 if (propertyGetService != null) { 173 if (propertyGetService != null) {
154 - saveOrUpdateService(productId, productKey, propertyGetService); 174 + IotThinkModelFunctionDO getServiceFunction = buildServiceFunctionDO(productId, productKey, propertyGetService);
  175 + newFunctionList.add(getServiceFunction);
  176 + }
  177 +
  178 + // 2. 获取数据库中的旧事件和服务列表
  179 + List<IotThinkModelFunctionDO> oldFunctionList = thinkModelFunctionMapper.selectListByProductIdAndTypes(
  180 + productId,
  181 + Arrays.asList(IotThingModelTypeEnum.EVENT.getType(), IotThingModelTypeEnum.SERVICE.getType())
  182 + );
  183 +
  184 + // 3. 使用 diffList 方法比较新旧列表
  185 + List<List<IotThinkModelFunctionDO>> diffResult = diffList(
  186 + oldFunctionList,
  187 + newFunctionList,
  188 + (oldFunc, newFunc) -> Objects.equals(oldFunc.getIdentifier(), newFunc.getIdentifier())
  189 + && Objects.equals(oldFunc.getType(), newFunc.getType())
  190 + );
  191 +
  192 + List<IotThinkModelFunctionDO> createList = diffResult.get(0); // 需要新增的
  193 + List<IotThinkModelFunctionDO> updateList = diffResult.get(1); // 需要更新的
  194 + List<IotThinkModelFunctionDO> deleteList = diffResult.get(2); // 需要删除的
  195 +
  196 + // 4. 批量执行数据库操作
  197 + if (CollUtil.isNotEmpty(createList)) {
  198 + thinkModelFunctionMapper.insertBatch(createList);
155 } 199 }
  200 + if (CollUtil.isNotEmpty(updateList)) {
  201 + for (IotThinkModelFunctionDO updateFunc : updateList) {
  202 + // 设置 ID,以便更新
  203 + IotThinkModelFunctionDO oldFunc = findFunctionByIdentifierAndType(
  204 + oldFunctionList, updateFunc.getIdentifier(), updateFunc.getType()
  205 + );
  206 + if (oldFunc != null) {
  207 + updateFunc.setId(oldFunc.getId());
  208 + thinkModelFunctionMapper.updateById(updateFunc);
  209 + }
  210 + }
  211 + }
  212 + if (CollUtil.isNotEmpty(deleteList)) {
  213 + List<Long> idsToDelete = deleteList.stream().map(IotThinkModelFunctionDO::getId).collect(Collectors.toList());
  214 + thinkModelFunctionMapper.deleteByIds(idsToDelete);
  215 + }
  216 + }
  217 +
  218 + /**
  219 + * 根据标识符和类型查找功能对象
  220 + */
  221 + private IotThinkModelFunctionDO findFunctionByIdentifierAndType(List<IotThinkModelFunctionDO> functionList,
  222 + String identifier, Integer type) {
  223 + return functionList.stream()
  224 + .filter(func -> Objects.equals(func.getIdentifier(), identifier) && Objects.equals(func.getType(), type))
  225 + .findFirst()
  226 + .orElse(null);
  227 + }
  228 +
  229 + /**
  230 + * 构建事件功能对象
  231 + */
  232 + private IotThinkModelFunctionDO buildEventFunctionDO(Long productId, String productKey, ThingModelEvent event) {
  233 + return new IotThinkModelFunctionDO()
  234 + .setProductId(productId)
  235 + .setProductKey(productKey)
  236 + .setIdentifier(event.getIdentifier())
  237 + .setName(event.getName())
  238 + .setDescription(event.getDescription())
  239 + .setType(IotThingModelTypeEnum.EVENT.getType())
  240 + .setEvent(event);
  241 + }
  242 +
  243 + /**
  244 + * 构建服务功能对象
  245 + */
  246 + private IotThinkModelFunctionDO buildServiceFunctionDO(Long productId, String productKey, ThingModelService service) {
  247 + return new IotThinkModelFunctionDO()
  248 + .setProductId(productId)
  249 + .setProductKey(productKey)
  250 + .setIdentifier(service.getIdentifier())
  251 + .setName(service.getName())
  252 + .setDescription(service.getDescription())
  253 + .setType(IotThingModelTypeEnum.SERVICE.getType())
  254 + .setService(service);
156 } 255 }
157 256
158 /** 257 /**
159 * 生成属性上报事件 258 * 生成属性上报事件
160 */ 259 */
161 private ThingModelEvent generatePropertyPostEvent(List<IotThinkModelFunctionDO> propertyList) { 260 private ThingModelEvent generatePropertyPostEvent(List<IotThinkModelFunctionDO> propertyList) {
162 - // TODO @haohao:用 CollUtil.isNotEmpty 会更容易哈  
163 - if (propertyList == null || propertyList.isEmpty()) { 261 + if (CollUtil.isEmpty(propertyList)) {
164 return null; 262 return null;
165 } 263 }
166 264
167 - // TODO @haohao:可以考虑链式调用,简化整个方法的长度;然后,把相同类型的户型,尽量再放同一行,看起来轻松点;其它类似的,也可以试试看哈  
168 - ThingModelEvent event = new ThingModelEvent();  
169 - event.setIdentifier("post");  
170 - event.setName("属性上报");  
171 - event.setType("info");  
172 - event.setDescription("属性上报事件");  
173 - event.setMethod("thing.event.property.post"); 265 + ThingModelEvent event = new ThingModelEvent()
  266 + .setIdentifier("post")
  267 + .setName("属性上报")
  268 + .setType("info")
  269 + .setDescription("属性上报事件")
  270 + .setMethod("thing.event.property.post");
174 271
175 // 将属性列表转换为事件的输出参数 272 // 将属性列表转换为事件的输出参数
176 List<ThingModelArgument> outputData = new ArrayList<>(); 273 List<ThingModelArgument> outputData = new ArrayList<>();
177 for (IotThinkModelFunctionDO functionDO : propertyList) { 274 for (IotThinkModelFunctionDO functionDO : propertyList) {
178 ThingModelProperty property = functionDO.getProperty(); 275 ThingModelProperty property = functionDO.getProperty();
179 - ThingModelArgument arg = new ThingModelArgument();  
180 - arg.setIdentifier(property.getIdentifier());  
181 - arg.setName(property.getName());  
182 - arg.setDataType(property.getDataType());  
183 - arg.setDescription(property.getDescription());  
184 - arg.setDirection("output"); // 设置为输出参数 276 + ThingModelArgument arg = new ThingModelArgument()
  277 + .setIdentifier(property.getIdentifier())
  278 + .setName(property.getName())
  279 + .setDataType(property.getDataType())
  280 + .setDescription(property.getDescription())
  281 + .setDirection("output"); // 设置为输出参数
185 outputData.add(arg); 282 outputData.add(arg);
186 } 283 }
187 event.setOutputData(outputData); 284 event.setOutputData(outputData);
@@ -199,13 +296,13 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -199,13 +296,13 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
199 List<ThingModelArgument> inputData = new ArrayList<>(); 296 List<ThingModelArgument> inputData = new ArrayList<>();
200 for (IotThinkModelFunctionDO functionDO : propertyList) { 297 for (IotThinkModelFunctionDO functionDO : propertyList) {
201 ThingModelProperty property = functionDO.getProperty(); 298 ThingModelProperty property = functionDO.getProperty();
202 - if ("w".equals(property.getAccessMode()) || "rw".equals(property.getAccessMode())) {  
203 - ThingModelArgument arg = new ThingModelArgument();  
204 - arg.setIdentifier(property.getIdentifier());  
205 - arg.setName(property.getName());  
206 - arg.setDataType(property.getDataType());  
207 - arg.setDescription(property.getDescription());  
208 - arg.setDirection("input"); // 设置为输入参数 299 + if (IotAccessModeEnum.WRITE.getMode().equals(property.getAccessMode()) || IotAccessModeEnum.READ_WRITE.getMode().equals(property.getAccessMode())) {
  300 + ThingModelArgument arg = new ThingModelArgument()
  301 + .setIdentifier(property.getIdentifier())
  302 + .setName(property.getName())
  303 + .setDataType(property.getDataType())
  304 + .setDescription(property.getDescription())
  305 + .setDirection("input"); // 设置为输入参数
209 inputData.add(arg); 306 inputData.add(arg);
210 } 307 }
211 } 308 }
@@ -214,16 +311,16 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -214,16 +311,16 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
214 return null; 311 return null;
215 } 312 }
216 313
217 - ThingModelService service = new ThingModelService();  
218 - service.setIdentifier("set");  
219 - service.setName("属性设置");  
220 - service.setCallType("async");  
221 - service.setDescription("属性设置服务");  
222 - service.setMethod("thing.service.property.set");  
223 - service.setInputData(inputData);  
224 // 属性设置服务一般不需要输出参数 314 // 属性设置服务一般不需要输出参数
225 - service.setOutputData(new ArrayList<>());  
226 - return service; 315 + return new ThingModelService()
  316 + .setIdentifier("set")
  317 + .setName("属性设置")
  318 + .setCallType("async")
  319 + .setDescription("属性设置服务")
  320 + .setMethod("thing.service.property.set")
  321 + .setInputData(inputData)
  322 + // 属性设置服务一般不需要输出参数
  323 + .setOutputData(new ArrayList<>());
227 } 324 }
228 325
229 /** 326 /**
@@ -237,14 +334,13 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -237,14 +334,13 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
237 List<ThingModelArgument> outputData = new ArrayList<>(); 334 List<ThingModelArgument> outputData = new ArrayList<>();
238 for (IotThinkModelFunctionDO functionDO : propertyList) { 335 for (IotThinkModelFunctionDO functionDO : propertyList) {
239 ThingModelProperty property = functionDO.getProperty(); 336 ThingModelProperty property = functionDO.getProperty();
240 - // TODO @haohao:r、rw 是不是枚举起来  
241 - if ("r".equals(property.getAccessMode()) || "rw".equals(property.getAccessMode())) {  
242 - ThingModelArgument arg = new ThingModelArgument();  
243 - arg.setIdentifier(property.getIdentifier());  
244 - arg.setName(property.getName());  
245 - arg.setDataType(property.getDataType());  
246 - arg.setDescription(property.getDescription());  
247 - arg.setDirection("output"); // 设置为输出参数 337 + if (IotAccessModeEnum.READ.getMode().equals(property.getAccessMode()) || IotAccessModeEnum.READ_WRITE.getMode().equals(property.getAccessMode())) {
  338 + ThingModelArgument arg = new ThingModelArgument()
  339 + .setIdentifier(property.getIdentifier())
  340 + .setName(property.getName())
  341 + .setDataType(property.getDataType())
  342 + .setDescription(property.getDescription())
  343 + .setDirection("output"); // 设置为输出参数
248 outputData.add(arg); 344 outputData.add(arg);
249 } 345 }
250 } 346 }
@@ -253,19 +349,19 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -253,19 +349,19 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
253 return null; 349 return null;
254 } 350 }
255 351
256 - ThingModelService service = new ThingModelService();  
257 - service.setIdentifier("get");  
258 - service.setName("属性获取");  
259 - service.setCallType("async");  
260 - service.setDescription("属性获取服务");  
261 - service.setMethod("thing.service.property.get"); 352 + ThingModelService service = new ThingModelService()
  353 + .setIdentifier("get")
  354 + .setName("属性获取")
  355 + .setCallType("async")
  356 + .setDescription("属性获取服务")
  357 + .setMethod("thing.service.property.get");
262 358
263 // 定义输入参数:属性标识符列表 359 // 定义输入参数:属性标识符列表
264 - ThingModelArgument inputArg = new ThingModelArgument();  
265 - inputArg.setIdentifier("properties");  
266 - inputArg.setName("属性标识符列表");  
267 - inputArg.setDescription("需要获取的属性标识符列表");  
268 - inputArg.setDirection("input"); // 设置为输入参数 360 + ThingModelArgument inputArg = new ThingModelArgument()
  361 + .setIdentifier("properties")
  362 + .setName("属性标识符列表")
  363 + .setDescription("需要获取的属性标识符列表")
  364 + .setDirection("input"); // 设置为输入参数
269 365
270 // 创建数组类型,元素类型为文本类型(字符串) 366 // 创建数组类型,元素类型为文本类型(字符串)
271 ThingModelArrayType arrayType = new ThingModelArrayType(); 367 ThingModelArrayType arrayType = new ThingModelArrayType();
@@ -283,54 +379,4 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe @@ -283,54 +379,4 @@ public class IotThinkModelFunctionServiceImpl implements IotThinkModelFunctionSe
283 return service; 379 return service;
284 } 380 }
285 381
286 - /**  
287 - * 保存或更新事件  
288 - */  
289 - private void saveOrUpdateEvent(Long productId, String productKey, ThingModelEvent event) {  
290 - // 检查是否已存在相同的事件  
291 - IotThinkModelFunctionDO existingEvent = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, event.getIdentifier());  
292 - IotThinkModelFunctionDO functionDO = new IotThinkModelFunctionDO();  
293 - functionDO.setProductId(productId);  
294 - functionDO.setProductKey(productKey);  
295 - functionDO.setIdentifier(event.getIdentifier());  
296 - functionDO.setName(event.getName());  
297 - functionDO.setDescription(event.getDescription());  
298 - functionDO.setType(IotThingModelTypeEnum.EVENT.getType());  
299 - functionDO.setEvent(event);  
300 -  
301 - // TODO @haohao:会不会存在删除的情况哈?另外,项目里有 diffList 方法,看看是不是可以方便的,适合这个场景。具体怎么用,可以全局搜  
302 - if (existingEvent != null) {  
303 - // 更新事件  
304 - functionDO.setId(existingEvent.getId());  
305 - thinkModelFunctionMapper.updateById(functionDO);  
306 - } else {  
307 - // 创建新的事件  
308 - thinkModelFunctionMapper.insert(functionDO);  
309 - }  
310 - }  
311 -  
312 - /**  
313 - * 保存或更新事服务  
314 - */  
315 - private void saveOrUpdateService(Long productId, String productKey, ThingModelService service) {  
316 - // 检查是否已存在相同的服务  
317 - IotThinkModelFunctionDO existingService = thinkModelFunctionMapper.selectByProductIdAndIdentifier(productId, service.getIdentifier());  
318 - IotThinkModelFunctionDO functionDO = new IotThinkModelFunctionDO();  
319 - functionDO.setProductId(productId);  
320 - functionDO.setProductKey(productKey);  
321 - functionDO.setIdentifier(service.getIdentifier());  
322 - functionDO.setName(service.getName());  
323 - functionDO.setDescription(service.getDescription());  
324 - functionDO.setType(IotThingModelTypeEnum.SERVICE.getType());  
325 - functionDO.setService(service);  
326 -  
327 - if (existingService != null) {  
328 - // 更新服务  
329 - functionDO.setId(existingService.getId());  
330 - thinkModelFunctionMapper.updateById(functionDO);  
331 - } else {  
332 - // 创建新的服务  
333 - thinkModelFunctionMapper.insert(functionDO);  
334 - }  
335 - }  
336 } 382 }