Commit f4e9a586e3a0805d8d2834ae027908033ec5f99a

Authored by puhui999
1 parent 94cfc4a1

【功能完善】IOT: ThingModel 服务和事件

yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/ThingModelInputOutputParam.java
@@ -34,6 +34,8 @@ public class ThingModelInputOutputParam { @@ -34,6 +34,8 @@ public class ThingModelInputOutputParam {
34 private String direction; 34 private String direction;
35 /** 35 /**
36 * 参数的序号。从 0 开始排序,且不能重复。 36 * 参数的序号。从 0 开始排序,且不能重复。
  37 + *
  38 + * TODO 考虑要不要序号,感觉是要的, 先留一手看看
37 */ 39 */
38 private Integer paraOrder; 40 private Integer paraOrder;
39 /** 41 /**
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotProductThingModelService.java
@@ -24,6 +24,13 @@ public interface IotProductThingModelService { @@ -24,6 +24,13 @@ public interface IotProductThingModelService {
24 Long createProductThingModel(@Valid IotProductThingModelSaveReqVO createReqVO); 24 Long createProductThingModel(@Valid IotProductThingModelSaveReqVO createReqVO);
25 25
26 /** 26 /**
  27 + * 创建超级表数据模型
  28 + *
  29 + * @param productId 产品编号
  30 + */
  31 + void createSuperTableDataModel(Long productId);
  32 +
  33 + /**
27 * 更新产品物模型 34 * 更新产品物模型
28 * 35 *
29 * @param updateReqVO 更新信息 36 * @param updateReqVO 更新信息
@@ -62,13 +69,6 @@ public interface IotProductThingModelService { @@ -62,13 +69,6 @@ public interface IotProductThingModelService {
62 PageResult<IotProductThingModelDO> getProductThingModelPage(IotProductThingModelPageReqVO pageReqVO); 69 PageResult<IotProductThingModelDO> getProductThingModelPage(IotProductThingModelPageReqVO pageReqVO);
63 70
64 /** 71 /**
65 - * 创建超级表数据模型  
66 - *  
67 - * @param productId 产品编号  
68 - */  
69 - void createSuperTableDataModel(Long productId);  
70 -  
71 - /**  
72 * 获得产品物模型列表 72 * 获得产品物模型列表
73 * 73 *
74 * @param productKey 产品 Key 74 * @param productKey 产品 Key
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; @@ -3,14 +3,10 @@ package cn.iocoder.yudao.module.iot.service.thingmodel;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
7 -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; 7 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent;
9 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; 8 +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelInputOutputParam;
10 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; 9 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
11 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelArgument;  
12 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelArrayDataSpecs;  
13 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs;  
14 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotProductThingModelPageReqVO; 10 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotProductThingModelPageReqVO;
15 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotProductThingModelSaveReqVO; 11 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotProductThingModelSaveReqVO;
16 import cn.iocoder.yudao.module.iot.convert.thingmodel.IotProductThingModelConvert; 12 import cn.iocoder.yudao.module.iot.convert.thingmodel.IotProductThingModelConvert;
@@ -18,8 +14,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; @@ -18,8 +14,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
18 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotProductThingModelDO; 14 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotProductThingModelDO;
19 import cn.iocoder.yudao.module.iot.dal.mysql.thingmodel.IotProductThingModelMapper; 15 import cn.iocoder.yudao.module.iot.dal.mysql.thingmodel.IotProductThingModelMapper;
20 import cn.iocoder.yudao.module.iot.enums.product.IotProductStatusEnum; 16 import cn.iocoder.yudao.module.iot.enums.product.IotProductStatusEnum;
21 -import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelAccessModeEnum;  
22 -import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelTypeEnum; 17 +import cn.iocoder.yudao.module.iot.enums.thingmodel.*;
23 import cn.iocoder.yudao.module.iot.service.product.IotProductService; 18 import cn.iocoder.yudao.module.iot.service.product.IotProductService;
24 import cn.iocoder.yudao.module.iot.service.tdengine.IotSuperTableService; 19 import cn.iocoder.yudao.module.iot.service.tdengine.IotSuperTableService;
25 import jakarta.annotation.Resource; 20 import jakarta.annotation.Resource;
@@ -31,8 +26,7 @@ import org.springframework.validation.annotation.Validated; @@ -31,8 +26,7 @@ import org.springframework.validation.annotation.Validated;
31 import java.util.*; 26 import java.util.*;
32 27
33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 28 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
34 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;  
35 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; 29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
36 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; 30 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
37 31
38 /** 32 /**
@@ -51,7 +45,7 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ @@ -51,7 +45,7 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
51 @Resource 45 @Resource
52 private IotProductService productService; 46 private IotProductService productService;
53 @Resource 47 @Resource
54 - private IotSuperTableService dbStructureDataService; 48 + private IotSuperTableService superTableService;
55 49
56 @Override 50 @Override
57 @Transactional(rollbackFor = Exception.class) 51 @Transactional(rollbackFor = Exception.class)
@@ -79,32 +73,16 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ @@ -79,32 +73,16 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
79 return thingModel.getId(); 73 return thingModel.getId();
80 } 74 }
81 75
82 - private void validateProductStatus(Long createReqVO) {  
83 - IotProductDO product = productService.getProduct(createReqVO);  
84 - if (Objects.equals(product.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) {  
85 - throw exception(PRODUCT_STATUS_NOT_ALLOW_THING_MODEL);  
86 - }  
87 - }  
88 -  
89 - private void validateNotDefaultEventAndService(String identifier) {  
90 - // set, get, post, property, event, time, value 是系统保留字段,不能用于标识符定义  
91 - if (CollUtil.containsAny(Arrays.asList("set", "get", "post", "property", "event", "time", "value"), Collections.singletonList(identifier))) {  
92 - throw exception(THING_MODEL_IDENTIFIER_INVALID);  
93 - }  
94 - } 76 + @Override
  77 + public void createSuperTableDataModel(Long productId) {
  78 + // 1. 查询产品
  79 + IotProductDO product = productService.getProduct(productId);
95 80
96 - private void validateNameUnique(Long productId, String name) {  
97 - IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndName(productId, name);  
98 - if (thingModel != null) {  
99 - throw exception(THING_MODEL_NAME_EXISTS);  
100 - }  
101 - } 81 + // 2. 查询产品的物模型功能列表
  82 + List<IotProductThingModelDO> thingModelList = productThingModelMapper.selectListByProductId(productId);
102 83
103 - private void validateIdentifierUnique(Long productId, String identifier) {  
104 - IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndIdentifier(productId, identifier);  
105 - if (thingModel != null) {  
106 - throw exception(THING_MODEL_IDENTIFIER_EXISTS);  
107 - } 84 + // 3. 生成 TDengine 的数据模型
  85 + superTableService.createSuperTableDataModel(product, thingModelList);
108 } 86 }
109 87
110 @Override 88 @Override
@@ -129,13 +107,6 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ @@ -129,13 +107,6 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
129 } 107 }
130 } 108 }
131 109
132 - private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) {  
133 - IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndIdentifier(productId, identifier);  
134 - if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) {  
135 - throw exception(THING_MODEL_IDENTIFIER_EXISTS);  
136 - }  
137 - }  
138 -  
139 @Override 110 @Override
140 @Transactional(rollbackFor = Exception.class) 111 @Transactional(rollbackFor = Exception.class)
141 public void deleteProductThingModel(Long id) { 112 public void deleteProductThingModel(Long id) {
@@ -157,17 +128,6 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ @@ -157,17 +128,6 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
157 } 128 }
158 } 129 }
159 130
160 - /**  
161 - * 校验功能是否存在  
162 - *  
163 - * @param id 功能编号  
164 - */  
165 - private void validateProductThingModelMapperExists(Long id) {  
166 - if (productThingModelMapper.selectById(id) == null) {  
167 - throw exception(THING_MODEL_NOT_EXISTS);  
168 - }  
169 - }  
170 -  
171 @Override 131 @Override
172 public IotProductThingModelDO getProductThingModel(Long id) { 132 public IotProductThingModelDO getProductThingModel(Long id) {
173 return productThingModelMapper.selectById(id); 133 return productThingModelMapper.selectById(id);
@@ -184,20 +144,54 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ @@ -184,20 +144,54 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
184 } 144 }
185 145
186 @Override 146 @Override
187 - public void createSuperTableDataModel(Long productId) {  
188 - // 1. 查询产品  
189 - IotProductDO product = productService.getProduct(productId); 147 + public List<IotProductThingModelDO> getProductThingModelListByProductKey(String productKey) {
  148 + return productThingModelMapper.selectListByProductKey(productKey);
  149 + }
190 150
191 - // 2. 查询产品的物模型功能列表  
192 - List<IotProductThingModelDO> thingModelList = productThingModelMapper.selectListByProductId(productId); 151 + /**
  152 + * 校验功能是否存在
  153 + *
  154 + * @param id 功能编号
  155 + */
  156 + private void validateProductThingModelMapperExists(Long id) {
  157 + if (productThingModelMapper.selectById(id) == null) {
  158 + throw exception(THING_MODEL_NOT_EXISTS);
  159 + }
  160 + }
193 161
194 - // 3. 生成 TDengine 的数据模型  
195 - dbStructureDataService.createSuperTableDataModel(product, thingModelList); 162 + private void validateIdentifierUniqueForUpdate(Long id, Long productId, String identifier) {
  163 + IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndIdentifier(productId, identifier);
  164 + if (thingModel != null && ObjectUtil.notEqual(thingModel.getId(), id)) {
  165 + throw exception(THING_MODEL_IDENTIFIER_EXISTS);
  166 + }
196 } 167 }
197 168
198 - @Override  
199 - public List<IotProductThingModelDO> getProductThingModelListByProductKey(String productKey) {  
200 - return productThingModelMapper.selectListByProductKey(productKey); 169 + private void validateProductStatus(Long createReqVO) {
  170 + IotProductDO product = productService.getProduct(createReqVO);
  171 + if (Objects.equals(product.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) {
  172 + throw exception(PRODUCT_STATUS_NOT_ALLOW_THING_MODEL);
  173 + }
  174 + }
  175 +
  176 + private void validateNotDefaultEventAndService(String identifier) {
  177 + // set, get, post, property, event, time, value 是系统保留字段,不能用于标识符定义
  178 + if (CollUtil.containsAny(Arrays.asList("set", "get", "post", "property", "event", "time", "value"), Collections.singletonList(identifier))) {
  179 + throw exception(THING_MODEL_IDENTIFIER_INVALID);
  180 + }
  181 + }
  182 +
  183 + private void validateNameUnique(Long productId, String name) {
  184 + IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndName(productId, name);
  185 + if (thingModel != null) {
  186 + throw exception(THING_MODEL_NAME_EXISTS);
  187 + }
  188 + }
  189 +
  190 + private void validateIdentifierUnique(Long productId, String identifier) {
  191 + IotProductThingModelDO thingModel = productThingModelMapper.selectByProductIdAndIdentifier(productId, identifier);
  192 + if (thingModel != null) {
  193 + throw exception(THING_MODEL_IDENTIFIER_EXISTS);
  194 + }
201 } 195 }
202 196
203 /** 197 /**
@@ -210,231 +204,138 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ @@ -210,231 +204,138 @@ public class IotProductThingModelServiceImpl implements IotProductThingModelServ
210 204
211 // 2. 生成新的事件和服务列表 205 // 2. 生成新的事件和服务列表
212 List<IotProductThingModelDO> newThingModelList = new ArrayList<>(); 206 List<IotProductThingModelDO> newThingModelList = new ArrayList<>();
213 - // 生成属性上报事件 207 + // 2.1 生成属性上报事件
214 ThingModelEvent propertyPostEvent = generatePropertyPostEvent(propertyList); 208 ThingModelEvent propertyPostEvent = generatePropertyPostEvent(propertyList);
215 if (propertyPostEvent != null) { 209 if (propertyPostEvent != null) {
216 - IotProductThingModelDO eventThingModel = buildEventThingModelDO(productId, productKey, propertyPostEvent);  
217 - newThingModelList.add(eventThingModel); 210 + newThingModelList.add(buildEventThingModelDO(productId, productKey, propertyPostEvent));
218 } 211 }
219 - // 生成属性设置服务 212 + // 2.2 生成属性设置服务
220 ThingModelService propertySetService = generatePropertySetService(propertyList); 213 ThingModelService propertySetService = generatePropertySetService(propertyList);
221 if (propertySetService != null) { 214 if (propertySetService != null) {
222 - IotProductThingModelDO setServiceThingModel = buildServiceThingModelDO(productId, productKey, propertySetService);  
223 - newThingModelList.add(setServiceThingModel); 215 + newThingModelList.add(buildServiceThingModelDO(productId, productKey, propertySetService));
224 } 216 }
225 - // 生成属性获取服务 217 + // 2.3 生成属性获取服务
226 ThingModelService propertyGetService = generatePropertyGetService(propertyList); 218 ThingModelService propertyGetService = generatePropertyGetService(propertyList);
227 if (propertyGetService != null) { 219 if (propertyGetService != null) {
228 - IotProductThingModelDO getServiceThingModel = buildServiceThingModelDO(productId, productKey, propertyGetService);  
229 - newThingModelList.add(getServiceThingModel); 220 + newThingModelList.add(buildServiceThingModelDO(productId, productKey, propertyGetService));
230 } 221 }
231 222
232 - // 3. 获取数据库中的默认的旧事件和服务列表 223 + // 3.1 获取数据库中的默认的旧事件和服务列表
233 List<IotProductThingModelDO> oldThingModelList = productThingModelMapper.selectListByProductIdAndIdentifiersAndTypes( 224 List<IotProductThingModelDO> oldThingModelList = productThingModelMapper.selectListByProductIdAndIdentifiersAndTypes(
234 productId, 225 productId,
235 Arrays.asList("post", "set", "get"), 226 Arrays.asList("post", "set", "get"),
236 Arrays.asList(IotProductThingModelTypeEnum.EVENT.getType(), IotProductThingModelTypeEnum.SERVICE.getType()) 227 Arrays.asList(IotProductThingModelTypeEnum.EVENT.getType(), IotProductThingModelTypeEnum.SERVICE.getType())
237 ); 228 );
  229 + // 3.2 创建默认的事件和服务
  230 + createDefaultEventsAndServices(oldThingModelList, newThingModelList);
  231 + }
238 232
239 - // 3.1 使用 diffList 方法比较新旧列表 233 + /**
  234 + * 创建默认的事件和服务
  235 + */
  236 + private void createDefaultEventsAndServices(List<IotProductThingModelDO> oldThingModelList, List<IotProductThingModelDO> newThingModelList) {
  237 + // 1.1 使用 diffList 方法比较新旧列表
240 List<List<IotProductThingModelDO>> diffResult = diffList(oldThingModelList, newThingModelList, 238 List<List<IotProductThingModelDO>> diffResult = diffList(oldThingModelList, newThingModelList,
241 - // 继续使用 identifier 和 type 进行比较:这样可以准确地匹配对应的功能对象。  
242 - (oldFunc, newFunc) -> Objects.equals(oldFunc.getIdentifier(), newFunc.getIdentifier())  
243 - && Objects.equals(oldFunc.getType(), newFunc.getType()));  
244 - List<IotProductThingModelDO> createList = diffResult.get(0); // 需要新增的  
245 - List<IotProductThingModelDO> updateList = diffResult.get(1); // 需要更新的  
246 - List<IotProductThingModelDO> deleteList = diffResult.get(2); // 需要删除的  
247 -  
248 - // 3.2 批量执行数据库操作  
249 - // 新增数据库中的新事件和服务列表  
250 - if (CollUtil.isNotEmpty(createList)) {  
251 - productThingModelMapper.insertBatch(createList); 239 + (oldVal, newVal) -> {
  240 + // 继续使用 identifier 和 type 进行比较:这样可以准确地匹配对应的功能对象。
  241 + boolean same = Objects.equals(oldVal.getIdentifier(), newVal.getIdentifier())
  242 + && Objects.equals(oldVal.getType(), newVal.getType());
  243 + if (same) {
  244 + newVal.setId(oldVal.getId()); // 设置编号
  245 + }
  246 + return same;
  247 + });
  248 + // 1.2 批量添加、修改、删除
  249 + if (CollUtil.isNotEmpty(diffResult.get(0))) {
  250 + productThingModelMapper.insertBatch(diffResult.get(0));
252 } 251 }
253 - // 更新数据库中的事件和服务列表  
254 - if (CollUtil.isNotEmpty(updateList)) {  
255 - // 首先,为每个需要更新的对象设置其对应的 ID  
256 - updateList.forEach(updateFunc -> {  
257 - IotProductThingModelDO oldFunc = findThingModelByIdentifierAndType(  
258 - oldThingModelList, updateFunc.getIdentifier(), updateFunc.getType());  
259 - if (oldFunc != null) {  
260 - updateFunc.setId(oldFunc.getId());  
261 - }  
262 - });  
263 - // 过滤掉没有设置 ID 的对象  
264 - List<IotProductThingModelDO> validUpdateList = filterList(updateList, thingModel -> thingModel.getId() != null);  
265 - // 执行批量更新  
266 - if (CollUtil.isNotEmpty(validUpdateList)) {  
267 - productThingModelMapper.updateBatch(validUpdateList);  
268 - } 252 + if (CollUtil.isNotEmpty(diffResult.get(1))) {
  253 + productThingModelMapper.updateBatch(diffResult.get(1));
269 } 254 }
270 -  
271 - // 删除数据库中的旧事件和服务列表  
272 - if (CollUtil.isNotEmpty(deleteList)) {  
273 - Set<Long> idsToDelete = CollectionUtils.convertSet(deleteList, IotProductThingModelDO::getId);  
274 - productThingModelMapper.deleteByIds(idsToDelete); 255 + if (CollUtil.isNotEmpty(diffResult.get(2))) {
  256 + productThingModelMapper.deleteByIds(convertSet(diffResult.get(2), IotProductThingModelDO::getId));
275 } 257 }
276 } 258 }
277 259
278 /** 260 /**
279 - * 根据标识符和类型查找功能对象  
280 - */  
281 - private IotProductThingModelDO findThingModelByIdentifierAndType(List<IotProductThingModelDO> thingModelList,  
282 - String identifier, Integer type) {  
283 - return CollUtil.findOne(thingModelList, func ->  
284 - Objects.equals(func.getIdentifier(), identifier) && Objects.equals(func.getType(), type));  
285 - }  
286 -  
287 - /**  
288 * 构建事件功能对象 261 * 构建事件功能对象
289 */ 262 */
290 private IotProductThingModelDO buildEventThingModelDO(Long productId, String productKey, ThingModelEvent event) { 263 private IotProductThingModelDO buildEventThingModelDO(Long productId, String productKey, ThingModelEvent event) {
291 - return new IotProductThingModelDO()  
292 - .setProductId(productId)  
293 - .setProductKey(productKey)  
294 - .setIdentifier(event.getIdentifier())  
295 - .setName(event.getName())  
296 - .setDescription(event.getDescription())  
297 - .setType(IotProductThingModelTypeEnum.EVENT.getType())  
298 - .setEvent(event); 264 + return new IotProductThingModelDO().setProductId(productId).setProductKey(productKey)
  265 + .setIdentifier(event.getIdentifier()).setName(event.getName()).setDescription(event.getDescription())
  266 + .setType(IotProductThingModelTypeEnum.EVENT.getType()).setEvent(event);
299 } 267 }
300 268
301 /** 269 /**
302 * 构建服务功能对象 270 * 构建服务功能对象
303 */ 271 */
304 private IotProductThingModelDO buildServiceThingModelDO(Long productId, String productKey, ThingModelService service) { 272 private IotProductThingModelDO buildServiceThingModelDO(Long productId, String productKey, ThingModelService service) {
305 - return new IotProductThingModelDO()  
306 - .setProductId(productId)  
307 - .setProductKey(productKey)  
308 - .setIdentifier(service.getIdentifier())  
309 - .setName(service.getName())  
310 - .setDescription(service.getDescription())  
311 - .setType(IotProductThingModelTypeEnum.SERVICE.getType())  
312 - .setService(service); 273 + return new IotProductThingModelDO().setProductId(productId).setProductKey(productKey)
  274 + .setIdentifier(service.getIdentifier()).setName(service.getName()).setDescription(service.getDescription())
  275 + .setType(IotProductThingModelTypeEnum.SERVICE.getType()).setService(service);
313 } 276 }
314 277
315 /** 278 /**
316 * 生成属性上报事件 279 * 生成属性上报事件
317 */ 280 */
318 - private ThingModelEvent generatePropertyPostEvent(List<IotProductThingModelDO> propertyList) {  
319 - if (CollUtil.isEmpty(propertyList)) { 281 + private ThingModelEvent generatePropertyPostEvent(List<IotProductThingModelDO> thingModelList) {
  282 + // 1.1 没有属性则不生成
  283 + if (CollUtil.isEmpty(thingModelList)) {
320 return null; 284 return null;
321 } 285 }
322 286
323 - ThingModelEvent event = new ThingModelEvent()  
324 - .setIdentifier("post")  
325 - .setName("属性上报")  
326 - .setType("info")  
327 - .setDescription("属性上报事件")  
328 - .setMethod("thing.event.property.post");  
329 -  
330 - // 将属性列表转换为事件的输出参数  
331 - List<ThingModelArgument> outputData = new ArrayList<>();  
332 - for (IotProductThingModelDO thingModel : propertyList) {  
333 - ThingModelArgument arg = new ThingModelArgument()  
334 - .setIdentifier(thingModel.getIdentifier())  
335 - .setName(thingModel.getName())  
336 - .setProperty(thingModel.getProperty())  
337 - .setDescription(thingModel.getDescription())  
338 - .setDirection("output"); // 设置为输出参数  
339 - outputData.add(arg);  
340 - }  
341 - event.setOutputData(outputData);  
342 - return event; 287 + // 1.2 生成属性上报事件
  288 + return new ThingModelEvent().setIdentifier("post").setName("属性上报").setDescription("属性上报事件")
  289 + .setEventType(IotProductThingModelServiceEventTypeEnum.INFO.getType()).setMethod("thing.event.property.post")
  290 + .setOutputParams(buildInputOutputParam(thingModelList, IotProductThingModelParamDirectionEnum.OUTPUT));
343 } 291 }
344 292
345 /** 293 /**
346 * 生成属性设置服务 294 * 生成属性设置服务
347 */ 295 */
348 - private ThingModelService generatePropertySetService(List<IotProductThingModelDO> propertyList) {  
349 - if (propertyList == null || propertyList.isEmpty()) {  
350 - return null;  
351 - }  
352 -  
353 - List<ThingModelArgument> inputData = new ArrayList<>();  
354 - for (IotProductThingModelDO thingModel : propertyList) {  
355 - ThingModelProperty property = thingModel.getProperty();  
356 - if (IotProductThingModelAccessModeEnum.READ_WRITE.getMode().equals(property.getAccessMode())) {  
357 - ThingModelArgument arg = new ThingModelArgument()  
358 - .setIdentifier(property.getIdentifier())  
359 - .setName(property.getName())  
360 - .setProperty(property)  
361 - .setDescription(property.getDescription())  
362 - .setDirection("input"); // 设置为输入参数  
363 - inputData.add(arg);  
364 - }  
365 - }  
366 - if (inputData.isEmpty()) {  
367 - // 如果没有可写属性,不生成属性设置服务 296 + private ThingModelService generatePropertySetService(List<IotProductThingModelDO> thingModelList) {
  297 + // 1.1 过滤出所有可写属性
  298 + thingModelList = filterList(thingModelList, thingModel ->
  299 + IotProductThingModelAccessModeEnum.READ_WRITE.getMode().equals(thingModel.getProperty().getAccessMode()));
  300 + // 1.2 没有可写属性则不生成
  301 + if (CollUtil.isEmpty(thingModelList)) {
368 return null; 302 return null;
369 } 303 }
370 304
371 - // 属性设置服务一般不需要输出参数  
372 - return new ThingModelService()  
373 - .setIdentifier("set")  
374 - .setName("属性设置")  
375 - .setCallType("async")  
376 - .setDescription("属性设置服务")  
377 - .setMethod("thing.service.property.set")  
378 - .setInputData(inputData)  
379 - // 属性设置服务一般不需要输出参数  
380 - .setOutputData(new ArrayList<>()); 305 + // 2. 生成属性设置服务
  306 + return new ThingModelService().setIdentifier("set").setName("属性设置").setDescription("属性设置服务")
  307 + .setCallType(IotProductThingModelServiceCallTypeEnum.ASYNC.getType()).setMethod("thing.service.property.set")
  308 + .setInputParams(buildInputOutputParam(thingModelList, IotProductThingModelParamDirectionEnum.INPUT))
  309 + .setOutputParams(Collections.emptyList()); // 属性设置服务一般不需要输出参数
381 } 310 }
382 311
383 /** 312 /**
384 * 生成属性获取服务 313 * 生成属性获取服务
385 */ 314 */
386 - private ThingModelService generatePropertyGetService(List<IotProductThingModelDO> propertyList) {  
387 - if (propertyList == null || propertyList.isEmpty()) { 315 + private ThingModelService generatePropertyGetService(List<IotProductThingModelDO> thingModelList) {
  316 + // 1.1 没有属性则不生成
  317 + if (CollUtil.isEmpty(thingModelList)) {
388 return null; 318 return null;
389 } 319 }
390 320
391 - List<ThingModelArgument> outputData = new ArrayList<>();  
392 - for (IotProductThingModelDO thingModelDO : propertyList) {  
393 - ThingModelProperty property = thingModelDO.getProperty();  
394 - if (ObjectUtils.equalsAny(property.getAccessMode(),  
395 - IotProductThingModelAccessModeEnum.READ_ONLY.getMode(), IotProductThingModelAccessModeEnum.READ_WRITE.getMode())) {  
396 - ThingModelArgument arg = new ThingModelArgument()  
397 - .setIdentifier(property.getIdentifier())  
398 - .setName(property.getName())  
399 - .setProperty(property)  
400 - .setDescription(property.getDescription())  
401 - .setDirection("output"); // 设置为输出参数  
402 - outputData.add(arg);  
403 - }  
404 - }  
405 - if (outputData.isEmpty()) {  
406 - // 如果没有可读属性,不生成属性获取服务  
407 - return null;  
408 - } 321 + // 1.2 生成属性获取服务
  322 + return new ThingModelService().setIdentifier("get").setName("属性获取").setDescription("属性获取服务")
  323 + .setCallType(IotProductThingModelServiceCallTypeEnum.ASYNC.getType()).setMethod("thing.service.property.get")
  324 + .setInputParams(buildInputOutputParam(thingModelList, IotProductThingModelParamDirectionEnum.INPUT))
  325 + .setOutputParams(buildInputOutputParam(thingModelList, IotProductThingModelParamDirectionEnum.OUTPUT));
  326 + }
409 327
410 - ThingModelService service = new ThingModelService()  
411 - .setIdentifier("get")  
412 - .setName("属性获取")  
413 - .setCallType("async")  
414 - .setDescription("属性获取服务")  
415 - .setMethod("thing.service.property.get");  
416 -  
417 - // 定义输入参数:属性标识符列表  
418 - ThingModelArgument inputArg = new ThingModelArgument()  
419 - .setIdentifier("properties")  
420 - .setName("属性标识符列表")  
421 - .setDescription("需要获取的属性标识符列表")  
422 - .setDirection("input"); // 设置为输入参数  
423 -  
424 - // 创建数组类型,元素类型为文本类型(字符串)TODO @puhui999: 还得研究研究  
425 - ThingModelArrayDataSpecs arrayType = new ThingModelArrayDataSpecs();  
426 - arrayType.setDataType("array");  
427 - inputArg.setProperty(new ThingModelProperty().setIdentifier(inputArg.getIdentifier()).setName(inputArg.getName())  
428 - .setDescription(inputArg.getDescription()).setDataSpecs(arrayType));  
429 -  
430 - ThingModelDateOrTextDataSpecs textType = new ThingModelDateOrTextDataSpecs();  
431 - textType.setDataType("text");  
432 - inputArg.setProperty(new ThingModelProperty().setIdentifier(inputArg.getIdentifier()).setName(inputArg.getName())  
433 - .setDescription(inputArg.getDescription()).setDataSpecs(textType));  
434 -  
435 - service.setInputData(Collections.singletonList(inputArg));  
436 - service.setOutputData(outputData);  
437 - return service; 328 + /**
  329 + * 构建输入/输出参数列表
  330 + *
  331 + * @param thingModelList 属性列表
  332 + * @return 输入/输出参数列表
  333 + */
  334 + private List<ThingModelInputOutputParam> buildInputOutputParam(List<IotProductThingModelDO> thingModelList,
  335 + IotProductThingModelParamDirectionEnum directionEnum) {
  336 + return convertList(thingModelList, thingModel ->
  337 + BeanUtils.toBean(thingModel.getProperty(), ThingModelInputOutputParam.class).setParaOrder(0) // TODO @puhui999: 先搞个默认值看看怎么个事
  338 + .setDirection(directionEnum.getDirection()));
438 } 339 }
439 340
440 } 341 }