Sfoglia il codice sorgente

【功能优化】IoT:跨租户校验 ProductKey 和 DeviceKey,避免跨租户的 Tdengine 表冲突

YunaiV 7 mesi fa
parent
commit
7b64b7fc69

+ 3 - 1
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java

@@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
 import java.util.List;
@@ -47,7 +48,8 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> {
     }
 
     default IotDeviceDO selectByDeviceKey(String deviceKey) {
-        return selectOne(IotDeviceDO::getDeviceKey, deviceKey);
+        return selectOne(new LambdaQueryWrapper<IotDeviceDO>()
+                .apply("LOWER(device_key) = {0}", deviceKey.toLowerCase()));
     }
 
     default List<IotDeviceDO> selectList(Integer deviceType) {

+ 3 - 1
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/product/IotProductMapper.java

@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.product.IotProductPageReqVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
 /**
@@ -23,7 +24,8 @@ public interface IotProductMapper extends BaseMapperX<IotProductDO> {
     }
 
     default IotProductDO selectByProductKey(String productKey) {
-        return selectOne(IotProductDO::getProductKey, productKey);
+        return selectOne(new LambdaQueryWrapper<IotProductDO>()
+                .apply("LOWER(product_key) = {0}", productKey.toLowerCase()));
     }
 
 }

+ 6 - 4
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java

@@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
+import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceGroupDO;
@@ -60,10 +61,11 @@ public class IotDeviceServiceImpl implements IotDeviceService {
             throw exception(PRODUCT_NOT_EXISTS);
         }
         // 1.2 校验设备标识是否唯一
-        // TODO 芋艿:校验时,需要跨租户唯一,避免 TDEngine 无法处理;并且要忽略大小写
-        if (deviceMapper.selectByDeviceKey(createReqVO.getDeviceKey()) != null) {
-            throw exception(DEVICE_KEY_EXISTS);
-        }
+        TenantUtils.executeIgnore(() -> {
+            if (deviceMapper.selectByDeviceKey(createReqVO.getDeviceKey()) != null) {
+                throw exception(PRODUCT_KEY_EXISTS);
+            }
+        });
         // 1.3 校验设备名称在同一产品下是否唯一
         if (deviceMapper.selectByProductKeyAndDeviceName(product.getProductKey(), createReqVO.getDeviceKey()) != null) {
             throw exception(DEVICE_NAME_EXISTS);

+ 9 - 9
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductServiceImpl.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.service.product;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.product.IotProductPageReqVO;
 import cn.iocoder.yudao.module.iot.controller.admin.product.vo.product.IotProductSaveReqVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
@@ -9,7 +10,6 @@ import cn.iocoder.yudao.module.iot.dal.mysql.product.IotProductMapper;
 import cn.iocoder.yudao.module.iot.enums.product.IotProductStatusEnum;
 import cn.iocoder.yudao.module.iot.service.device.IotDevicePropertyDataService;
 import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService;
-import cn.iocoder.yudao.module.iot.service.thingmodel.IotProductThingModelService;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
 import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Lazy;
@@ -34,9 +34,6 @@ public class IotProductServiceImpl implements IotProductService {
     @Resource
     private IotProductMapper productMapper;
 
-    @Resource
-    @Lazy // 延迟加载,解决循环依赖
-    private IotProductThingModelService thingModelFunctionService;
     @Resource
     @Lazy  // 延迟加载,解决循环依赖
     private IotThingModelMessageService thingModelMessageService;
@@ -46,11 +43,14 @@ public class IotProductServiceImpl implements IotProductService {
 
     @Override
     public Long createProduct(IotProductSaveReqVO createReqVO) {
-        // 1. 生成 ProductKey
-        // TODO 芋艿:校验时,需要跨租户唯一,避免 TDEngine 无法处理;并且要忽略大小写
-        if (productMapper.selectByProductKey(createReqVO.getProductKey()) != null) {
-            throw exception(PRODUCT_KEY_EXISTS);
-        }
+        // 1. 校验 ProductKey
+        TenantUtils.executeIgnore(() -> {
+            // 为什么忽略租户?避免多个租户之间,productKey 重复,导致 TDengine 设备属性表重复
+            if (productMapper.selectByProductKey(createReqVO.getProductKey()) != null) {
+                throw exception(PRODUCT_KEY_EXISTS);
+            }
+        });
+
         // 2. 插入
         IotProductDO product = BeanUtils.toBean(createReqVO, IotProductDO.class)
                 .setStatus(IotProductStatusEnum.UNPUBLISHED.getStatus());