Commit f4e9a586e3a0805d8d2834ae027908033ec5f99a
1 parent
94cfc4a1
【功能完善】IOT: ThingModel 服务和事件
Showing
3 changed files
with
141 additions
and
238 deletions
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 | } |