Commit 4ebaa3d60c51a03bf5a82e4958a01634f512fbcb

Authored by YunaiV
1 parent 0faee76f

reactor:【IoT 物联网】简化物模型的 CRUD 逻辑

yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotThingModelMapper.java
@@ -25,8 +25,6 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> { @@ -25,8 +25,6 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> {
25 .likeIfPresent(IotThingModelDO::getName, reqVO.getName()) 25 .likeIfPresent(IotThingModelDO::getName, reqVO.getName())
26 .eqIfPresent(IotThingModelDO::getType, reqVO.getType()) 26 .eqIfPresent(IotThingModelDO::getType, reqVO.getType())
27 .eqIfPresent(IotThingModelDO::getProductId, reqVO.getProductId()) 27 .eqIfPresent(IotThingModelDO::getProductId, reqVO.getProductId())
28 - // TODO @芋艿:看看要不要加枚举  
29 - .notIn(IotThingModelDO::getIdentifier, "get", "set", "post")  
30 .orderByDesc(IotThingModelDO::getId)); 28 .orderByDesc(IotThingModelDO::getId));
31 } 29 }
32 30
@@ -36,8 +34,6 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> { @@ -36,8 +34,6 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> {
36 .likeIfPresent(IotThingModelDO::getName, reqVO.getName()) 34 .likeIfPresent(IotThingModelDO::getName, reqVO.getName())
37 .eqIfPresent(IotThingModelDO::getType, reqVO.getType()) 35 .eqIfPresent(IotThingModelDO::getType, reqVO.getType())
38 .eqIfPresent(IotThingModelDO::getProductId, reqVO.getProductId()) 36 .eqIfPresent(IotThingModelDO::getProductId, reqVO.getProductId())
39 - // TODO @芋艿:看看要不要加枚举  
40 - .notIn(IotThingModelDO::getIdentifier, "get", "set", "post")  
41 .orderByDesc(IotThingModelDO::getId)); 37 .orderByDesc(IotThingModelDO::getId));
42 } 38 }
43 39
@@ -61,15 +57,6 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> { @@ -61,15 +57,6 @@ public interface IotThingModelMapper extends BaseMapperX<IotThingModelDO> {
61 IotThingModelDO::getType, type); 57 IotThingModelDO::getType, type);
62 } 58 }
63 59
64 - default List<IotThingModelDO> selectListByProductIdAndIdentifiersAndTypes(Long productId,  
65 - List<String> identifiers,  
66 - List<Integer> types) {  
67 - return selectList(new LambdaQueryWrapperX<IotThingModelDO>()  
68 - .eq(IotThingModelDO::getProductId, productId)  
69 - .in(IotThingModelDO::getIdentifier, identifiers)  
70 - .in(IotThingModelDO::getType, types));  
71 - }  
72 -  
73 default IotThingModelDO selectByProductIdAndName(Long productId, String name) { 60 default IotThingModelDO selectByProductIdAndName(Long productId, String name) {
74 return selectOne(IotThingModelDO::getProductId, productId, 61 return selectOne(IotThingModelDO::getProductId, productId,
75 IotThingModelDO::getName, name); 62 IotThingModelDO::getName, name);
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java
@@ -5,11 +5,7 @@ import cn.hutool.core.util.ObjectUtil; @@ -5,11 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
5 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
6 import cn.hutool.extra.spring.SpringUtil; 6 import cn.hutool.extra.spring.SpringUtil;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
9 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; 8 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
10 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent;  
11 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelParam;  
12 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;  
13 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; 9 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO;
14 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; 10 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO;
15 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; 11 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO;
@@ -19,7 +15,6 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; @@ -19,7 +15,6 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
19 import cn.iocoder.yudao.module.iot.dal.mysql.thingmodel.IotThingModelMapper; 15 import cn.iocoder.yudao.module.iot.dal.mysql.thingmodel.IotThingModelMapper;
20 import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants; 16 import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants;
21 import cn.iocoder.yudao.module.iot.enums.product.IotProductStatusEnum; 17 import cn.iocoder.yudao.module.iot.enums.product.IotProductStatusEnum;
22 -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 jakarta.annotation.Resource; 19 import jakarta.annotation.Resource;
25 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
@@ -29,10 +24,13 @@ import org.springframework.stereotype.Service; @@ -29,10 +24,13 @@ import org.springframework.stereotype.Service;
29 import org.springframework.transaction.annotation.Transactional; 24 import org.springframework.transaction.annotation.Transactional;
30 import org.springframework.validation.annotation.Validated; 25 import org.springframework.validation.annotation.Validated;
31 26
32 -import java.util.*; 27 +import java.util.Collection;
  28 +import java.util.List;
  29 +import java.util.Objects;
  30 +import java.util.Set;
33 31
34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 32 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
35 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 33 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
36 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; 34 import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
37 35
38 /** 36 /**
@@ -65,12 +63,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { @@ -65,12 +63,7 @@ public class IotThingModelServiceImpl implements IotThingModelService {
65 IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(createReqVO); 63 IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(createReqVO);
66 thingModelMapper.insert(thingModel); 64 thingModelMapper.insert(thingModel);
67 65
68 - // 3. 如果创建的是属性,需要更新默认的事件和服务  
69 - if (Objects.equals(createReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {  
70 - createDefaultEventsAndServices(createReqVO.getProductId(), createReqVO.getProductKey());  
71 - }  
72 -  
73 - // 4. 删除缓存 66 + // 3. 删除缓存
74 deleteThingModelListCache(createReqVO.getProductKey()); 67 deleteThingModelListCache(createReqVO.getProductKey());
75 return thingModel.getId(); 68 return thingModel.getId();
76 } 69 }
@@ -89,12 +82,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { @@ -89,12 +82,7 @@ public class IotThingModelServiceImpl implements IotThingModelService {
89 IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(updateReqVO); 82 IotThingModelDO thingModel = IotThingModelConvert.INSTANCE.convert(updateReqVO);
90 thingModelMapper.updateById(thingModel); 83 thingModelMapper.updateById(thingModel);
91 84
92 - // 3. 如果更新的是属性,需要更新默认的事件和服务  
93 - if (Objects.equals(updateReqVO.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {  
94 - createDefaultEventsAndServices(updateReqVO.getProductId(), updateReqVO.getProductKey());  
95 - }  
96 -  
97 - // 4. 删除缓存 85 + // 3. 删除缓存
98 deleteThingModelListCache(updateReqVO.getProductKey()); 86 deleteThingModelListCache(updateReqVO.getProductKey());
99 } 87 }
100 88
@@ -112,12 +100,7 @@ public class IotThingModelServiceImpl implements IotThingModelService { @@ -112,12 +100,7 @@ public class IotThingModelServiceImpl implements IotThingModelService {
112 // 2. 删除功能 100 // 2. 删除功能
113 thingModelMapper.deleteById(id); 101 thingModelMapper.deleteById(id);
114 102
115 - // 3. 如果删除的是属性,需要更新默认的事件和服务  
116 - if (Objects.equals(thingModel.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {  
117 - createDefaultEventsAndServices(thingModel.getProductId(), thingModel.getProductKey());  
118 - }  
119 -  
120 - // 4. 删除缓存 103 + // 3. 删除缓存
121 deleteThingModelListCache(thingModel.getProductKey()); 104 deleteThingModelListCache(thingModel.getProductKey());
122 } 105 }
123 106
@@ -221,160 +204,6 @@ public class IotThingModelServiceImpl implements IotThingModelService { @@ -221,160 +204,6 @@ public class IotThingModelServiceImpl implements IotThingModelService {
221 } 204 }
222 } 205 }
223 206
224 - /**  
225 - * 创建默认的事件和服务  
226 - *  
227 - * @param productId 产品编号  
228 - * @param productKey 产品标识  
229 - */  
230 - public void createDefaultEventsAndServices(Long productId, String productKey) {  
231 - // 1. 获取当前属性列表  
232 - List<IotThingModelDO> properties = thingModelMapper  
233 - .selectListByProductIdAndType(productId, IotThingModelTypeEnum.PROPERTY.getType());  
234 -  
235 - // 2. 生成新的事件和服务列表  
236 - List<IotThingModelDO> newThingModels = new ArrayList<>();  
237 - // 2.1 生成属性上报事件  
238 - ThingModelEvent propertyPostEvent = generatePropertyPostEvent(properties);  
239 - if (propertyPostEvent != null) {  
240 - newThingModels.add(buildEventThingModel(productId, productKey, propertyPostEvent, "属性上报事件"));  
241 - }  
242 - // 2.2 生成属性设置服务  
243 - ThingModelService propertySetService = generatePropertySetService(properties);  
244 - if (propertySetService != null) {  
245 - newThingModels.add(buildServiceThingModel(productId, productKey, propertySetService, "属性设置服务"));  
246 - }  
247 - // 2.3 生成属性获取服务  
248 - ThingModelService propertyGetService = generatePropertyGetService(properties);  
249 - if (propertyGetService != null) {  
250 - newThingModels.add(buildServiceThingModel(productId, productKey, propertyGetService, "属性获取服务"));  
251 - }  
252 -  
253 - // 3.1 获取数据库中的默认的旧事件和服务列表  
254 - List<IotThingModelDO> oldThingModels = thingModelMapper.selectListByProductIdAndIdentifiersAndTypes(  
255 - productId,  
256 - Arrays.asList("post", "set", "get"),  
257 - Arrays.asList(IotThingModelTypeEnum.EVENT.getType(), IotThingModelTypeEnum.SERVICE.getType())  
258 - );  
259 - // 3.2 创建默认的事件和服务  
260 - createDefaultEventsAndServices(oldThingModels, newThingModels);  
261 - }  
262 -  
263 - /**  
264 - * 创建默认的事件和服务  
265 - */  
266 - private void createDefaultEventsAndServices(List<IotThingModelDO> oldThingModels,  
267 - List<IotThingModelDO> newThingModels) {  
268 - // 使用 diffList 方法比较新旧列表  
269 - List<List<IotThingModelDO>> diffResult = diffList(oldThingModels, newThingModels,  
270 - (oldVal, newVal) -> {  
271 - // 继续使用 identifier 和 type 进行比较:这样可以准确地匹配对应的功能对象。  
272 - boolean same = Objects.equals(oldVal.getIdentifier(), newVal.getIdentifier())  
273 - && Objects.equals(oldVal.getType(), newVal.getType());  
274 - if (same) {  
275 - newVal.setId(oldVal.getId()); // 设置编号  
276 - }  
277 - return same;  
278 - });  
279 - // 批量添加、修改、删除  
280 - if (CollUtil.isNotEmpty(diffResult.get(0))) {  
281 - thingModelMapper.insertBatch(diffResult.get(0));  
282 - }  
283 - if (CollUtil.isNotEmpty(diffResult.get(1))) {  
284 - thingModelMapper.updateBatch(diffResult.get(1));  
285 - }  
286 - if (CollUtil.isNotEmpty(diffResult.get(2))) {  
287 - thingModelMapper.deleteByIds(convertSet(diffResult.get(2), IotThingModelDO::getId));  
288 - }  
289 - }  
290 -  
291 - /**  
292 - * 构建事件功能对象  
293 - */  
294 - private IotThingModelDO buildEventThingModel(Long productId, String productKey,  
295 - ThingModelEvent event, String description) {  
296 - return new IotThingModelDO().setProductId(productId).setProductKey(productKey)  
297 - .setIdentifier(event.getIdentifier()).setName(event.getName()).setDescription(description)  
298 - .setType(IotThingModelTypeEnum.EVENT.getType()).setEvent(event);  
299 - }  
300 -  
301 - /**  
302 - * 构建服务功能对象  
303 - */  
304 - private IotThingModelDO buildServiceThingModel(Long productId, String productKey,  
305 - ThingModelService service, String description) {  
306 - return new IotThingModelDO().setProductId(productId).setProductKey(productKey)  
307 - .setIdentifier(service.getIdentifier()).setName(service.getName()).setDescription(description)  
308 - .setType(IotThingModelTypeEnum.SERVICE.getType()).setService(service);  
309 - }  
310 -  
311 - // TODO @haohao:是不是不用生成这个?目前属性上报,是个批量接口  
312 -  
313 - /**  
314 - * 生成属性上报事件  
315 - */  
316 - private ThingModelEvent generatePropertyPostEvent(List<IotThingModelDO> thingModels) {  
317 - // 没有属性则不生成  
318 - if (CollUtil.isEmpty(thingModels)) {  
319 - return null;  
320 - }  
321 -  
322 - // 生成属性上报事件  
323 - return new ThingModelEvent().setIdentifier("post").setName("属性上报").setMethod("thing.event.property.post")  
324 - .setType(IotThingModelServiceEventTypeEnum.INFO.getType())  
325 - .setOutputParams(buildInputOutputParam(thingModels, IotThingModelParamDirectionEnum.OUTPUT));  
326 - }  
327 -  
328 - // TODO @haohao:是不是不用生成这个?目前属性上报,是个批量接口  
329 -  
330 - /**  
331 - * 生成属性设置服务  
332 - */  
333 - private ThingModelService generatePropertySetService(List<IotThingModelDO> thingModels) {  
334 - // 1.1 过滤出所有可写属性  
335 - thingModels = filterList(thingModels, thingModel ->  
336 - IotThingModelAccessModeEnum.READ_WRITE.getMode().equals(thingModel.getProperty().getAccessMode()));  
337 - // 1.2 没有可写属性则不生成  
338 - if (CollUtil.isEmpty(thingModels)) {  
339 - return null;  
340 - }  
341 -  
342 - // 2. 生成属性设置服务  
343 - return new ThingModelService().setIdentifier("set").setName("属性设置").setMethod("thing.service.property.set")  
344 - .setCallType(IotThingModelServiceCallTypeEnum.ASYNC.getType())  
345 - .setInputParams(buildInputOutputParam(thingModels, IotThingModelParamDirectionEnum.INPUT))  
346 - .setOutputParams(Collections.emptyList()); // 属性设置服务一般不需要输出参数  
347 - }  
348 -  
349 - /**  
350 - * 生成属性获取服务  
351 - */  
352 - private ThingModelService generatePropertyGetService(List<IotThingModelDO> thingModels) {  
353 - // 1.1 没有属性则不生成  
354 - if (CollUtil.isEmpty(thingModels)) {  
355 - return null;  
356 - }  
357 -  
358 - // 1.2 生成属性获取服务  
359 - return new ThingModelService().setIdentifier("get").setName("属性获取").setMethod("thing.service.property.get")  
360 - .setCallType(IotThingModelServiceCallTypeEnum.ASYNC.getType())  
361 - .setInputParams(buildInputOutputParam(thingModels, IotThingModelParamDirectionEnum.INPUT))  
362 - .setOutputParams(buildInputOutputParam(thingModels, IotThingModelParamDirectionEnum.OUTPUT));  
363 - }  
364 -  
365 - /**  
366 - * 构建输入/输出参数列表  
367 - *  
368 - * @param thingModels 属性列表  
369 - * @return 输入/输出参数列表  
370 - */  
371 - private List<ThingModelParam> buildInputOutputParam(List<IotThingModelDO> thingModels,  
372 - IotThingModelParamDirectionEnum direction) {  
373 - return convertList(thingModels, thingModel ->  
374 - BeanUtils.toBean(thingModel.getProperty(), ThingModelParam.class).setParaOrder(0) // TODO @puhui999: 先搞个默认值看看怎么个事  
375 - .setDirection(direction.getDirection()));  
376 - }  
377 -  
378 private void deleteThingModelListCache(String productKey) { 207 private void deleteThingModelListCache(String productKey) {
379 // 保证 Spring AOP 触发 208 // 保证 Spring AOP 触发
380 getSelf().deleteThingModelListCache0(productKey); 209 getSelf().deleteThingModelListCache0(productKey);