list);
@Named("convertToProperty")
- default ThingModelProperty convertToProperty(IotProductThingModelSaveReqVO bean) {
- if (Objects.equals(bean.getType(), IotProductThingModelTypeEnum.PROPERTY.getType())) {
+ default ThingModelProperty convertToProperty(IotThingModelSaveReqVO bean) {
+ if (Objects.equals(bean.getType(), IotThingModelTypeEnum.PROPERTY.getType())) {
return bean.getProperty();
}
return null;
}
@Named("convertToEvent")
- default ThingModelEvent convertToEvent(IotProductThingModelSaveReqVO bean) {
- if (Objects.equals(bean.getType(), IotProductThingModelTypeEnum.EVENT.getType())) {
+ default ThingModelEvent convertToEvent(IotThingModelSaveReqVO bean) {
+ if (Objects.equals(bean.getType(), IotThingModelTypeEnum.EVENT.getType())) {
return bean.getEvent();
}
return null;
}
@Named("convertToService")
- default ThingModelService convertToService(IotProductThingModelSaveReqVO bean) {
- if (Objects.equals(bean.getType(), IotProductThingModelTypeEnum.SERVICE.getType())) {
+ default ThingModelService convertToService(IotThingModelSaveReqVO bean) {
+ if (Objects.equals(bean.getType(), IotThingModelTypeEnum.SERVICE.getType())) {
return bean.getService();
}
return null;
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDataDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDataDO.java
index ab1934edb..63b732d20 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDataDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDataDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.device;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotProductThingModelDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -30,7 +30,7 @@ public class IotDeviceDataDO {
/**
* 物模型编号
*
- * 关联 {@link IotProductThingModelDO#getId()}
+ * 关联 {@link IotThingModelDO#getId()}
*/
private Long thingModelId;
@@ -51,21 +51,21 @@ public class IotDeviceDataDO {
/**
* 属性标识符
*
- * 关联 {@link IotProductThingModelDO#getIdentifier()}
+ * 关联 {@link IotThingModelDO#getIdentifier()}
*/
private String identifier;
/**
* 属性名称
*
- * 关联 {@link IotProductThingModelDO#getName()}
+ * 关联 {@link IotThingModelDO#getName()}
*/
private String name;
/**
* 数据类型
*
- * 关联 {@link IotProductThingModelDO#getProperty()#getDataType()}
+ * 关联 {@link IotThingModelDO#getProperty()#getDataType()}
*/
private String dataType;
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugininfo/PluginInfoDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugininfo/PluginInfoDO.java
index 043cdb9c8..fbdf2a1dc 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugininfo/PluginInfoDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugininfo/PluginInfoDO.java
@@ -1,6 +1,9 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum;
+import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
+import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -26,11 +29,10 @@ public class PluginInfoDO extends BaseDO {
*/
@TableId
private Long id;
- // TODO @haohao:这个是不是改成类似 key 之类的字段哈?
/**
- * 插件包 ID
+ * 插件包标识符
*/
- private String pluginId;
+ private String pluginKey;
/**
* 插件名称
*/
@@ -41,22 +43,23 @@ public class PluginInfoDO extends BaseDO {
private String description;
/**
* 部署方式
+ *
+ * 枚举 {@link IotPluginDeployTypeEnum}
*/
- // TODO @haohao:枚举
private Integer deployType;
/**
* 插件包文件名
*/
- // TODO @haohao:是不是叫 fileName 哈?避免后续有别的字段,类似 fileUrl?
- private String file;
+ private String fileName;
/**
* 插件版本
*/
private String version;
/**
* 插件类型
+ *
+ * 枚举 {@link IotPluginTypeEnum}
*/
- // TODO @haohao:枚举
private Integer type;
/**
* 设备插件协议类型
@@ -64,8 +67,9 @@ public class PluginInfoDO extends BaseDO {
private String protocol;
/**
* 状态
+ *
+ * 枚举 {@link IotPluginStatusEnum}
*/
- // TODO @haohao:枚举
private Integer status;
/**
* 插件配置项描述信息
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugininstance/PluginInstanceDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugininstance/PluginInstanceDO.java
index 17f295a55..507b91f2a 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugininstance/PluginInstanceDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugininstance/PluginInstanceDO.java
@@ -1,12 +1,13 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.plugininstance;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
-// TODO @haohao:一些必要的关联、枚举
+
/**
* IoT 插件实例 DO
*
@@ -33,6 +34,8 @@ public class PluginInstanceDO extends BaseDO {
private String mainId;
/**
* 插件id
+ *
+ * 关联 {@link PluginInfoDO#getId()}
*/
private Long pluginId;
/**
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/FieldParser.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/FieldParser.java
index 9157920e0..2e4e0f507 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/FieldParser.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/FieldParser.java
@@ -5,7 +5,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelR
import java.util.HashMap;
import java.util.List;
-import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
/**
* FieldParser 类用于解析和转换物模型字段到 TDengine 字段
@@ -15,6 +16,7 @@ public class FieldParser {
/**
* 物模型到td数据类型映射
*/
+ @Deprecated
private static final HashMap TYPE_MAPPING = new HashMap<>() {
{
put("INT", "INT");
@@ -52,10 +54,7 @@ public class FieldParser {
* @return 字段列表
*/
public static List parse(ThingModelRespVO thingModel) {
- // TODO @puhui999:是不是使用 convertList
- return thingModel.getModel().getProperties().stream()
- .map(FieldParser::parse)
- .collect(Collectors.toList());
+ return convertList(thingModel.getModel().getProperties(), FieldParser::parse);
}
/**
@@ -65,18 +64,18 @@ public class FieldParser {
* @return 转换后的 TDengine 字段对象列表
*/
public static List parse(List> rows) {
- // TODO @puhui999:是不是使用 convertList
- return rows.stream().map(row -> {
+ return convertList(rows, row -> {
String type = row.get(1).toString().toUpperCase();
// TODO @puhui999:"NCHAR" 最好枚举下
int dataLength = "NCHAR".equals(type) ? Integer.parseInt(row.get(2).toString()) : -1;
return new TdFieldDO(row.get(0).toString(), type, dataLength);
- }).collect(Collectors.toList());
+ });
}
/**
* 获取字段字义
*/
+ @Deprecated
public static String getFieldDefine(TdFieldDO field) {
return "`" + field.getFieldName() + "`" + " "
+ (field.getDataLength() > 0 ? String.format("%s(%d)", field.getDataType(), field.getDataLength())
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectDO.java
index 542dd1e7b..fb4cd459a 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectDO.java
@@ -2,13 +2,12 @@ package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
import lombok.Data;
-import java.util.Set;
-
// TODO @haohao:类似这个,其实可以参考 mybatis plus,querywrapper,搞个 TdEngineQueryWrapper。这样看起来会更好懂。
/**
* 查询DO
*/
@Data
+@Deprecated
public class SelectDO {
// TODO @haoha:database 是个单词
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java
index 44acc3ac5..584562bfa 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java
@@ -6,6 +6,7 @@ import java.util.Map;
// TODO @haohao:类似 SelectDO 的想法,只是它是返回。ps:貌似可以在 tdengine 里面,创建一个 query 包,放这种比较特殊的查询和结果对象。dataobject 更多还是实际存储的结构化的 do
@Data
+@Deprecated
public class SelectVisualDO {
/**
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TagsSelectDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TagsSelectDO.java
index 9fae91599..353830824 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TagsSelectDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TagsSelectDO.java
@@ -6,6 +6,7 @@ import lombok.Data;
* tags查询DO
*/
@Data
+@Deprecated
public class TagsSelectDO {
/**
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdFieldDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdFieldDO.java
index 2e1751509..10c9b9fe7 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdFieldDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdFieldDO.java
@@ -5,6 +5,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
+// TODO 芋艿:看看是不是后续简化掉。
/**
* TD 引擎的字段
*/
@@ -12,6 +13,7 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Builder
+@Deprecated
public class TdFieldDO {
/**
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdResponse.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdResponse.java
index aca5cece5..8b64f6854 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdResponse.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdResponse.java
@@ -12,6 +12,7 @@ import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
+@Deprecated
public class TdResponse {
public static final int CODE_SUCCESS = 0;
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdRestApi.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdRestApi.java
index b2d1ac029..1bb793a45 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdRestApi.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdRestApi.java
@@ -13,6 +13,7 @@ import org.springframework.stereotype.Service;
*/
@Slf4j
@Service
+@Deprecated // TODO 芋艿:貌似没用到
public class TdRestApi {
@Value("${spring.datasource.dynamic.datasource.tdengine.url}")
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java
index 3b30352e4..3265c3ebe 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/TdTableDO.java
@@ -7,6 +7,7 @@ import lombok.NoArgsConstructor;
import java.util.List;
+@Deprecated
/**
* TD 引擎的数据库
*/
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/IotProductThingModelDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/IotThingModelDO.java
similarity index 77%
rename from yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/IotProductThingModelDO.java
rename to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/IotThingModelDO.java
index 3d9e5e5fe..e3b4a6d9a 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/IotProductThingModelDO.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/thingmodel/IotThingModelDO.java
@@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelE
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
-import cn.iocoder.yudao.module.iot.enums.thingmodel.IotProductThingModelTypeEnum;
+import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -19,17 +19,17 @@ import lombok.NoArgsConstructor;
/**
* IoT 产品物模型功能 DO
*
- * 每个 {@link IotProductDO} 和 {@link IotProductThingModelDO} 是“一对多”的关系,它的每个属性、事件、服务都对应一条记录
+ * 每个 {@link IotProductDO} 和 {@link IotThingModelDO} 是“一对多”的关系,它的每个属性、事件、服务都对应一条记录
*
* @author 芋道源码
*/
-@TableName(value = "iot_product_thing_model", autoResultMap = true)
-@KeySequence("iot_product_thing_model_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@TableName(value = "iot_thing_model", autoResultMap = true)
+@KeySequence("iot_thing_model_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class IotProductThingModelDO extends BaseDO {
+public class IotThingModelDO extends BaseDO {
/**
* 物模型功能编号
@@ -66,7 +66,7 @@ public class IotProductThingModelDO extends BaseDO {
/**
* 功能类型
*
- * 枚举 {@link IotProductThingModelTypeEnum}
+ * 枚举 {@link IotThingModelTypeEnum}
*/
private Integer type;
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java
index 893d7eefd..2ed10eee5 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java
+++ b/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 {
}
default IotDeviceDO selectByDeviceKey(String deviceKey) {
- return selectOne(IotDeviceDO::getDeviceKey, deviceKey);
+ return selectOne(new LambdaQueryWrapper()
+ .apply("LOWER(device_key) = {0}", deviceKey.toLowerCase()));
}
default List selectList(Integer deviceType) {
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/PluginInfoMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/PluginInfoMapper.java
new file mode 100644
index 000000000..228519fb6
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/PluginInfoMapper.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.iot.dal.mysql.plugin;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
+import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.*;
+
+/**
+ * IoT 插件信息 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface PluginInfoMapper extends BaseMapperX {
+
+ default PageResult selectPage(PluginInfoPageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .likeIfPresent(PluginInfoDO::getName, reqVO.getName())
+ .eqIfPresent(PluginInfoDO::getStatus, reqVO.getStatus())
+ .orderByDesc(PluginInfoDO::getId));
+ }
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugininstance/PluginInstanceMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/PluginInstanceMapper.java
similarity index 73%
rename from yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugininstance/PluginInstanceMapper.java
rename to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/PluginInstanceMapper.java
index 6c7f1d231..249082032 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugininstance/PluginInstanceMapper.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/PluginInstanceMapper.java
@@ -1,11 +1,11 @@
-package cn.iocoder.yudao.module.iot.dal.mysql.plugininstance;
+package cn.iocoder.yudao.module.iot.dal.mysql.plugin;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.PluginInstancePageReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininstance.PluginInstanceDO;
import org.apache.ibatis.annotations.Mapper;
-import cn.iocoder.yudao.module.iot.controller.admin.plugininstance.vo.*;
/**
* IoT 插件实例 Mapper
@@ -15,6 +15,12 @@ import cn.iocoder.yudao.module.iot.controller.admin.plugininstance.vo.*;
@Mapper
public interface PluginInstanceMapper extends BaseMapperX {
+ default PluginInstanceDO selectByMainIdAndPluginId(String mainId, Long pluginId) {
+ return selectOne(new LambdaQueryWrapperX()
+ .eq(PluginInstanceDO::getMainId, mainId)
+ .eq(PluginInstanceDO::getPluginId, pluginId));
+ }
+
default PageResult selectPage(PluginInstancePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX()
.eqIfPresent(PluginInstanceDO::getMainId, reqVO.getMainId())
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugininfo/PluginInfoMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugininfo/PluginInfoMapper.java
deleted file mode 100644
index 69c0bd392..000000000
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugininfo/PluginInfoMapper.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.mysql.plugininfo;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
-import org.apache.ibatis.annotations.Mapper;
-import cn.iocoder.yudao.module.iot.controller.admin.plugininfo.vo.*;
-
-/**
- * IoT 插件信息 Mapper
- *
- * @author 芋道源码
- */
-@Mapper
-public interface PluginInfoMapper extends BaseMapperX {
-
- default PageResult selectPage(PluginInfoPageReqVO reqVO) {
- return selectPage(reqVO, new LambdaQueryWrapperX()
- .eqIfPresent(PluginInfoDO::getPluginId, reqVO.getPluginId())
- .likeIfPresent(PluginInfoDO::getName, reqVO.getName())
- .eqIfPresent(PluginInfoDO::getDescription, reqVO.getDescription())
- .eqIfPresent(PluginInfoDO::getDeployType, reqVO.getDeployType())
- .eqIfPresent(PluginInfoDO::getFile, reqVO.getFile())
- .eqIfPresent(PluginInfoDO::getVersion, reqVO.getVersion())
- .eqIfPresent(PluginInfoDO::getType, reqVO.getType())
- .eqIfPresent(PluginInfoDO::getProtocol, reqVO.getProtocol())
- .eqIfPresent(PluginInfoDO::getStatus, reqVO.getStatus())
- .eqIfPresent(PluginInfoDO::getConfigSchema, reqVO.getConfigSchema())
- .eqIfPresent(PluginInfoDO::getConfig, reqVO.getConfig())
- .eqIfPresent(PluginInfoDO::getScript, reqVO.getScript())
- .betweenIfPresent(PluginInfoDO::getCreateTime, reqVO.getCreateTime())
- .orderByDesc(PluginInfoDO::getId));
- }
-
-}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/product/IotProductMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/product/IotProductMapper.java
index aef149ae7..0f5625100 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/product/IotProductMapper.java
+++ b/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 {
}
default IotProductDO selectByProductKey(String productKey) {
- return selectOne(IotProductDO::getProductKey, productKey);
+ return selectOne(new LambdaQueryWrapper()
+ .apply("LOWER(product_key) = {0}", productKey.toLowerCase()));
}
}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotProductThingModelMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotProductThingModelMapper.java
deleted file mode 100644
index 175f66f40..000000000
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotProductThingModelMapper.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.mysql.thingmodel;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-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.thingmodel.vo.IotProductThingModelPageReqVO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotProductThingModelDO;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-
-/**
- * IoT 产品物模型 Mapper
- *
- * @author 芋道源码
- */
-@Mapper
-public interface IotProductThingModelMapper extends BaseMapperX {
-
- default PageResult selectPage(IotProductThingModelPageReqVO reqVO) {
- return selectPage(reqVO, new LambdaQueryWrapperX()
- .eqIfPresent(IotProductThingModelDO::getIdentifier, reqVO.getIdentifier())
- .likeIfPresent(IotProductThingModelDO::getName, reqVO.getName())
- .eqIfPresent(IotProductThingModelDO::getType, reqVO.getType())
- .eqIfPresent(IotProductThingModelDO::getProductId, reqVO.getProductId())
- .notIn(IotProductThingModelDO::getIdentifier, "get", "set", "post")
- .orderByDesc(IotProductThingModelDO::getId));
- }
-
- default IotProductThingModelDO selectByProductIdAndIdentifier(Long productId, String identifier) {
- return selectOne(IotProductThingModelDO::getProductId, productId,
- IotProductThingModelDO::getIdentifier, identifier);
- }
-
- default List selectListByProductId(Long productId) {
- return selectList(IotProductThingModelDO::getProductId, productId);
- }
-
- default List selectListByProductIdAndType(Long productId, Integer type) {
- return selectList(IotProductThingModelDO::getProductId, productId,
- IotProductThingModelDO::getType, type);
- }
-
- default List selectListByProductIdAndIdentifiersAndTypes(Long productId,
- List identifiers,
- List types) {
- return selectList(new LambdaQueryWrapperX()
- .eq(IotProductThingModelDO::getProductId, productId)
- .in(IotProductThingModelDO::getIdentifier, identifiers)
- .in(IotProductThingModelDO::getType, types));
- }
-
- default IotProductThingModelDO selectByProductIdAndName(Long productId, String name) {
- return selectOne(IotProductThingModelDO::getProductId, productId,
- IotProductThingModelDO::getName, name);
- }
-
- default List selectListByProductKey(String productKey) {
- return selectList(IotProductThingModelDO::getProductKey, productKey);
- }
-
-}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotThingModelMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotThingModelMapper.java
new file mode 100644
index 000000000..b68732634
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/thingmodel/IotThingModelMapper.java
@@ -0,0 +1,63 @@
+package cn.iocoder.yudao.module.iot.dal.mysql.thingmodel;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+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.thingmodel.vo.IotThingModelPageReqVO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * IoT 产品物模型 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface IotThingModelMapper extends BaseMapperX {
+
+ default PageResult selectPage(IotThingModelPageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .eqIfPresent(IotThingModelDO::getIdentifier, reqVO.getIdentifier())
+ .likeIfPresent(IotThingModelDO::getName, reqVO.getName())
+ .eqIfPresent(IotThingModelDO::getType, reqVO.getType())
+ .eqIfPresent(IotThingModelDO::getProductId, reqVO.getProductId())
+ // TODO @芋艿:看看要不要加枚举
+ .notIn(IotThingModelDO::getIdentifier, "get", "set", "post")
+ .orderByDesc(IotThingModelDO::getId));
+ }
+
+ default IotThingModelDO selectByProductIdAndIdentifier(Long productId, String identifier) {
+ return selectOne(IotThingModelDO::getProductId, productId,
+ IotThingModelDO::getIdentifier, identifier);
+ }
+
+ default List selectListByProductId(Long productId) {
+ return selectList(IotThingModelDO::getProductId, productId);
+ }
+
+ default List selectListByProductIdAndType(Long productId, Integer type) {
+ return selectList(IotThingModelDO::getProductId, productId,
+ IotThingModelDO::getType, type);
+ }
+
+ default List selectListByProductIdAndIdentifiersAndTypes(Long productId,
+ List identifiers,
+ List types) {
+ return selectList(new LambdaQueryWrapperX()
+ .eq(IotThingModelDO::getProductId, productId)
+ .in(IotThingModelDO::getIdentifier, identifiers)
+ .in(IotThingModelDO::getType, types));
+ }
+
+ default IotThingModelDO selectByProductIdAndName(Long productId, String name) {
+ return selectOne(IotThingModelDO::getProductId, productId,
+ IotThingModelDO::getName, name);
+ }
+
+ default List selectListByProductKey(String productKey) {
+ return selectList(IotThingModelDO::getProductKey, productKey);
+ }
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java
new file mode 100644
index 000000000..6053444fe
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyDataMapper.java
@@ -0,0 +1,77 @@
+package cn.iocoder.yudao.module.iot.dal.tdengine;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField;
+import cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation.TDengineDS;
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Mapper
+@TDengineDS
+@InterceptorIgnore(tenantLine = "true") // 避免 SQL 解析,因为 JSqlParser 对 TDengine 的 SQL 解析会报错
+public interface IotDevicePropertyDataMapper {
+
+ List getProductPropertySTableFieldList(@Param("productKey") String productKey);
+
+ void createProductPropertySTable(@Param("productKey") String productKey,
+ @Param("fields") List fields);
+
+ @SuppressWarnings("SimplifyStreamApiCallChains") // 保持 JDK8 兼容性
+ default void alterProductPropertySTable(String productKey,
+ List oldFields,
+ List newFields) {
+ oldFields.removeIf(field -> TDengineTableField.FIELD_TS.equals(field.getField())
+ || TDengineTableField.FIELD_DEVICE_KEY.equals(field.getField()));
+ List addFields = newFields.stream().filter( // 新增的字段
+ newField -> oldFields.stream().noneMatch(oldField -> oldField.getField().equals(newField.getField())))
+ .collect(Collectors.toList());
+ List dropFields = oldFields.stream().filter( // 删除的字段
+ oldField -> newFields.stream().noneMatch(n -> n.getField().equals(oldField.getField())))
+ .collect(Collectors.toList());
+ List modifyTypeFields = new ArrayList<>(); // 变更类型的字段
+ List modifyLengthFields = new ArrayList<>(); // 变更长度的字段
+ newFields.forEach(newField -> {
+ TDengineTableField oldField = CollUtil.findOne(oldFields, field -> field.getField().equals(newField.getField()));
+ if (oldField == null) {
+ return;
+ }
+ if (ObjectUtil.notEqual(oldField.getType(), newField.getType())) {
+ modifyTypeFields.add(newField);
+ return;
+ }
+ if (newField.getLength()!= null) {
+ if (newField.getLength() > oldField.getLength()) {
+ modifyLengthFields.add(newField);
+ } else if (newField.getLength() < oldField.getLength()) {
+ // 特殊:TDengine 长度修改时,只允许变长,所以此时认为是修改类型
+ modifyTypeFields.add(newField);
+ }
+ }
+ });
+
+ // 执行
+ addFields.forEach(field -> alterProductPropertySTableAddField(productKey, field));
+ dropFields.forEach(field -> alterProductPropertySTableDropField(productKey, field));
+ modifyLengthFields.forEach(field -> alterProductPropertySTableModifyField(productKey, field));
+ modifyTypeFields.forEach(field -> {
+ alterProductPropertySTableDropField(productKey, field);
+ alterProductPropertySTableAddField(productKey, field);
+ });
+ }
+
+ void alterProductPropertySTableAddField(@Param("productKey") String productKey,
+ @Param("field") TDengineTableField field);
+
+ void alterProductPropertySTableModifyField(@Param("productKey") String productKey,
+ @Param("field") TDengineTableField field);
+
+ void alterProductPropertySTableDropField(@Param("productKey") String productKey,
+ @Param("field") TDengineTableField field);
+
+}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDDLMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDDLMapper.java
index 3d7aa84dd..eeb061cc5 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDDLMapper.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/TdEngineDDLMapper.java
@@ -96,7 +96,6 @@ public interface TdEngineDDLMapper {
@TenantIgnore
void modifyColumnWidthForSuperTable(TdTableDO superTable);
-
/**
* 修改超级表 - 为超级表添加标签
*
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/emq/service/EmqxServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/emq/service/EmqxServiceImpl.java
index 343f9ba21..46217a22b 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/emq/service/EmqxServiceImpl.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/emq/service/EmqxServiceImpl.java
@@ -1,7 +1,6 @@
package cn.iocoder.yudao.module.iot.emq.service;
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.module.iot.service.device.IotDeviceDataService;
+import cn.iocoder.yudao.module.iot.service.device.IotDevicePropertyDataService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
@@ -21,7 +20,7 @@ import org.springframework.stereotype.Service;
public class EmqxServiceImpl implements EmqxService {
@Resource
- private IotDeviceDataService iotDeviceDataService;
+ private IotDevicePropertyDataService iotDeviceDataService;
// TODO 多线程处理消息
@Override
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/ServiceRegistryConfiguration.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/ServiceRegistryConfiguration.java
deleted file mode 100644
index 385c8aee5..000000000
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/ServiceRegistryConfiguration.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.module.iot.framework.plugin;
-
-import cn.iocoder.yudao.module.iot.api.DeviceDataApi;
-import cn.iocoder.yudao.module.iot.api.ServiceRegistry;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.Resource;
-
-@Slf4j
-@Configuration
-public class ServiceRegistryConfiguration {
-
- @Resource
- private DeviceDataApi deviceDataApi;
-
- @PostConstruct
- public void init() {
- // 将主程序中的 DeviceDataApi 实例注册到 ServiceRegistry
- ServiceRegistry.registerService(DeviceDataApi.class, deviceDataApi);
- log.info("[init][将 DeviceDataApi 实例注册到 ServiceRegistry 中]");
- }
-
- /**
- * 定义一个标记用的 Bean,用于表示 ServiceRegistry 已初始化完成
- */
- @Bean("serviceRegistryInitializedMarker")
- public Object serviceRegistryInitializedMarker() {
- // 返回任意对象即可,这里返回null都可以,但最好返回个实际对象
- return new Object();
- }
-}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/SpringConfiguration.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/SpringConfiguration.java
deleted file mode 100644
index d87a94f31..000000000
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/SpringConfiguration.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package cn.iocoder.yudao.module.iot.framework.plugin;
-
-import org.pf4j.spring.SpringPluginManager;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.DependsOn;
-
-@Configuration
-public class SpringConfiguration {
-
- @Bean
- @DependsOn("serviceRegistryInitializedMarker")
- public SpringPluginManager pluginManager() {
- return new SpringPluginManager();
- }
-
-}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/UnifiedConfiguration.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/UnifiedConfiguration.java
new file mode 100644
index 000000000..4f1d5e3e2
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/UnifiedConfiguration.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.iot.framework.plugin;
+
+import cn.iocoder.yudao.module.iot.api.ServiceRegistry;
+import cn.iocoder.yudao.module.iot.api.device.DeviceDataApi;
+import cn.iocoder.yudao.module.iot.framework.plugin.listener.CustomPluginStateListener;
+import lombok.extern.slf4j.Slf4j;
+import org.pf4j.spring.SpringPluginManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+
+import javax.annotation.Resource;
+
+@Slf4j
+@Configuration
+public class UnifiedConfiguration {
+
+ private static final String SERVICE_REGISTRY_INITIALIZED_MARKER = "serviceRegistryInitializedMarker";
+
+ @Resource
+ private DeviceDataApi deviceDataApi;
+
+ @Bean(SERVICE_REGISTRY_INITIALIZED_MARKER)
+ public Object serviceRegistryInitializedMarker() {
+ ServiceRegistry.registerService(DeviceDataApi.class, deviceDataApi);
+ log.info("[init][将 DeviceDataApi 实例注册到 ServiceRegistry 中]");
+ return new Object();
+ }
+
+ @Bean
+ @DependsOn(SERVICE_REGISTRY_INITIALIZED_MARKER)
+ public SpringPluginManager pluginManager() {
+ log.info("[init][实例化 SpringPluginManager]");
+ SpringPluginManager springPluginManager = new SpringPluginManager();
+ springPluginManager.addPluginStateListener(new CustomPluginStateListener());
+ return springPluginManager;
+ }
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/listener/CustomPluginStateListener.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/listener/CustomPluginStateListener.java
new file mode 100644
index 000000000..c0802d7f5
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/listener/CustomPluginStateListener.java
@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.iot.framework.plugin.listener;
+
+import lombok.extern.slf4j.Slf4j;
+import org.pf4j.PluginStateEvent;
+import org.pf4j.PluginStateListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+public class CustomPluginStateListener implements PluginStateListener {
+
+ @Override
+ public void pluginStateChanged(PluginStateEvent event) {
+ // 1. 获取插件ID
+ String pluginId = event.getPlugin().getPluginId();
+ // 2. 获取插件旧状态
+ String oldState = event.getOldState().toString();
+ // 3. 获取插件新状态
+ String newState = event.getPluginState().toString();
+ // 4. 打印日志信息
+ log.info("插件的状态 '{}' 已更改为 '{}' 至 '{}'", pluginId, oldState, newState);
+ }
+
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/core/TDengineTableField.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/core/TDengineTableField.java
new file mode 100644
index 000000000..427c68189
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/core/TDengineTableField.java
@@ -0,0 +1,63 @@
+package cn.iocoder.yudao.module.iot.framework.tdengine.core;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * TDEngine 表字段
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TDengineTableField {
+
+ /**
+ * 字段名 - TDengine 默认 ts 字段,默认会被 TDengine 创建
+ */
+ public static final String FIELD_TS = "ts";
+
+ /**
+ * 字段名 - 我们系统定义的 device_key 字段,非 TDengine 默认字段
+ */
+ public static final String FIELD_DEVICE_KEY = "device_key";
+
+ public static final String TYPE_TINYINT = "TINYINT";
+ public static final String TYPE_INT = "INT";
+ public static final String TYPE_FLOAT = "FLOAT";
+ public static final String TYPE_DOUBLE = "DOUBLE";
+ public static final String TYPE_BOOL = "BOOL";
+ public static final String TYPE_NCHAR = "NCHAR";
+ public static final String TYPE_TIMESTAMP = "TIMESTAMP";
+
+ /**
+ * 注释 - TAG 字段
+ */
+ public static final String NOTE_TAG = "TAG";
+
+ /**
+ * 字段名
+ */
+ private String field;
+
+ /**
+ * 字段类型
+ */
+ private String type;
+
+ /**
+ * 字段长度
+ */
+ private Integer length;
+
+ /**
+ * 注释
+ */
+ private String note;
+
+ public TDengineTableField(String field, String type) {
+ this.field = field;
+ this.type = type;
+ }
+
+}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/core/annotation/TDengineDS.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/core/annotation/TDengineDS.java
new file mode 100644
index 000000000..e3960d026
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/core/annotation/TDengineDS.java
@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.module.iot.framework.tdengine.core.annotation;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+
+import java.lang.annotation.*;
+
+/**
+ * TDEngine 数据源
+ *
+ * @author 芋道源码
+ */
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@DS("tdengine")
+public @interface TDengineDS {
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/package-info.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/package-info.java
new file mode 100644
index 000000000..f92428f7b
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/tdengine/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * iot 模块的 tdengine 拓展封装
+ */
+package cn.iocoder.yudao.module.iot.framework.tdengine;
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/plugin/PluginInstancesJob.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/plugin/PluginInstancesJob.java
new file mode 100644
index 000000000..ca8398e51
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/plugin/PluginInstancesJob.java
@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.iot.job.plugin;
+
+
+import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
+import cn.iocoder.yudao.module.iot.service.plugin.PluginInstanceService;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 插件实例 Job
+ *
+ * @author 芋道源码
+ */
+@Component
+public class PluginInstancesJob {
+
+ @Resource
+ private PluginInstanceService pluginInstanceService;
+
+ @Scheduled(initialDelay = 60, fixedRate = 60, timeUnit = TimeUnit.SECONDS)
+ public void updatePluginInstances() {
+ TenantUtils.executeIgnore(() -> {
+ pluginInstanceService.updatePluginInstances();
+ });
+ }
+}
\ No newline at end of file
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java
index dfc911df5..111cf5007 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/simulatesend/SimulateSendConsumer.java
@@ -1,8 +1,10 @@
package cn.iocoder.yudao.module.iot.mq.consumer.simulatesend;
/**
+ * TODO @alwayssuper:记得实现,还有类注释哈
+ *
* @author alwayssuper
- * @date 2024/12/20 8:04
+ * @since 2024/12/20 8:04
*/
public class SimulateSendConsumer {
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java
similarity index 71%
rename from yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataService.java
rename to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java
index 1dd4ad666..08375cb09 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataService.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDevicePropertyDataService.java
@@ -9,11 +9,18 @@ import java.util.List;
import java.util.Map;
/**
- * IoT 设备数据 Service 接口
+ * IoT 设备【属性】数据 Service 接口
*
* @author 芋道源码
*/
-public interface IotDeviceDataService {
+public interface IotDevicePropertyDataService {
+
+ /**
+ * 定义设备属性数据的结构
+ *
+ * @param productId 产品编号
+ */
+ void defineDevicePropertyData(Long productId);
/**
* 保存设备数据
@@ -21,7 +28,7 @@ public interface IotDeviceDataService {
* @param productKey 产品 key
* @param deviceName 设备名称
* @param message 消息
- * JSON 格式,参见 ...
+ *
参见 JSON 格式
*/
void saveDeviceData(String productKey, String deviceName, String message);
@@ -40,4 +47,5 @@ public interface IotDeviceDataService {
* @return 设备属性历史数据
*/
PageResult