Commit 8c84ac9d8a88dd73d03746274f4f6e2de7004668
1 parent
88088c79
【新增功能】 mqtt 数据接收
Showing
13 changed files
with
224 additions
and
23 deletions
yudao-module-iot/yudao-module-iot-biz/pom.xml
| ... | ... | @@ -25,6 +25,11 @@ |
| 25 | 25 | <version>${revision}</version> |
| 26 | 26 | </dependency> |
| 27 | 27 | |
| 28 | + <dependency> | |
| 29 | + <groupId>cn.iocoder.boot</groupId> | |
| 30 | + <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> | |
| 31 | + </dependency> | |
| 32 | + | |
| 28 | 33 | <!-- Web 相关 --> |
| 29 | 34 | <dependency> |
| 30 | 35 | <groupId>cn.iocoder.boot</groupId> | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/ThingModelMessage.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Builder; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.NoArgsConstructor; | |
| 7 | + | |
| 8 | +import java.util.HashMap; | |
| 9 | +import java.util.Map; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * 物模型消息 | |
| 13 | + */ | |
| 14 | +@Data | |
| 15 | +@NoArgsConstructor | |
| 16 | +@AllArgsConstructor | |
| 17 | +@Builder | |
| 18 | +public class ThingModelMessage { | |
| 19 | + | |
| 20 | + /** | |
| 21 | + * 消息ID | |
| 22 | + */ | |
| 23 | + private String id; | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * 扩展功能的参数 | |
| 27 | + */ | |
| 28 | + private Object sys; | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * 请求方法 例如:thing.event.property.post | |
| 32 | + */ | |
| 33 | + private String method; | |
| 34 | + | |
| 35 | + /** | |
| 36 | + * 请求参数 | |
| 37 | + */ | |
| 38 | + private Object params; | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * 属性上报时间戳 | |
| 42 | + */ | |
| 43 | + private Long time; | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * 设备信息 | |
| 47 | + */ | |
| 48 | + private String productKey; | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * 设备名称 | |
| 52 | + */ | |
| 53 | + private String deviceName; | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * 设备 key | |
| 57 | + */ | |
| 58 | + private String deviceKey; | |
| 59 | + | |
| 60 | + /** | |
| 61 | + * 转换为 Map 类型 | |
| 62 | + */ | |
| 63 | + public Map<String, Object> dataToMap() { | |
| 64 | + Map<String, Object> mapData = new HashMap<>(); | |
| 65 | + if (params instanceof Map) { | |
| 66 | + ((Map<?, ?>) params).forEach((key, value) -> mapData.put(key.toString(), value)); | |
| 67 | + } | |
| 68 | + return mapData; | |
| 69 | + } | |
| 70 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/emq/service/EmqxServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.emq.service; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 4 | +import cn.iocoder.yudao.module.iot.service.device.IotDeviceDataService; | |
| 5 | +import jakarta.annotation.Resource; | |
| 3 | 6 | import lombok.extern.slf4j.Slf4j; |
| 4 | 7 | import org.eclipse.paho.client.mqttv3.MqttClient; |
| 5 | 8 | import org.eclipse.paho.client.mqttv3.MqttMessage; |
| ... | ... | @@ -16,13 +19,20 @@ import org.springframework.stereotype.Service; |
| 16 | 19 | @Service |
| 17 | 20 | public class EmqxServiceImpl implements EmqxService { |
| 18 | 21 | |
| 22 | + @Resource | |
| 23 | + private IotDeviceDataService iotDeviceDataService; | |
| 24 | + | |
| 19 | 25 | // TODO 多线程处理消息 |
| 20 | 26 | @Override |
| 21 | 27 | public void subscribeCallback(String topic, MqttMessage mqttMessage) { |
| 22 | 28 | log.info("收到消息,主题: {}, 内容: {}", topic, new String(mqttMessage.getPayload())); |
| 23 | 29 | // 根据不同的主题,处理不同的业务逻辑 |
| 24 | 30 | if (topic.contains("/property/post")) { |
| 25 | - // 设备上报数据 | |
| 31 | + // 设备上报数据 topic /sys/f13f57c63e9/dianbiao1/thing/event/property/post | |
| 32 | + String productKey = topic.split("/")[2]; | |
| 33 | + String deviceName = topic.split("/")[3]; | |
| 34 | + String message = new String(mqttMessage.getPayload()); | |
| 35 | + iotDeviceDataService.saveDeviceData(productKey, deviceName, message); | |
| 26 | 36 | } |
| 27 | 37 | } |
| 28 | 38 | |
| ... | ... | @@ -30,7 +40,7 @@ public class EmqxServiceImpl implements EmqxService { |
| 30 | 40 | public void subscribe(MqttClient client) { |
| 31 | 41 | try { |
| 32 | 42 | // 订阅默认主题,可以根据需要修改 |
| 33 | -// client.subscribe("$share/yudao/+/+/#", 1); | |
| 43 | + client.subscribe("/sys/+/+/#", 1); | |
| 34 | 44 | log.info("订阅默认主题成功"); |
| 35 | 45 | } catch (Exception e) { |
| 36 | 46 | log.error("订阅默认主题失败", e); | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.service.device; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO; | |
| 5 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO; | |
| 6 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | |
| 8 | +import jakarta.validation.Valid; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * IoT 设备数据 Service 接口 | |
| 12 | + * | |
| 13 | + * @author 芋道源码 | |
| 14 | + */ | |
| 15 | +public interface IotDeviceDataService { | |
| 16 | + | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * 保存设备数据 | |
| 20 | + * | |
| 21 | + * @param productKey 产品 key | |
| 22 | + * @param deviceName 设备名称 | |
| 23 | + * @param message 消息 | |
| 24 | + */ | |
| 25 | + void saveDeviceData(String productKey, String deviceName, String message); | |
| 26 | +} | |
| 0 | 27 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceDataServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.service.device; | |
| 2 | + | |
| 3 | +import cn.hutool.json.JSONObject; | |
| 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | |
| 5 | +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; | |
| 6 | +import cn.iocoder.yudao.module.iot.service.tdengine.IotThingModelMessageService; | |
| 7 | +import jakarta.annotation.Resource; | |
| 8 | +import lombok.extern.slf4j.Slf4j; | |
| 9 | +import org.springframework.stereotype.Service; | |
| 10 | + | |
| 11 | +@Slf4j | |
| 12 | +@Service | |
| 13 | +public class IotDeviceDataServiceImpl implements IotDeviceDataService { | |
| 14 | + | |
| 15 | + @Resource | |
| 16 | + private IotDeviceService deviceService; | |
| 17 | + @Resource | |
| 18 | + private IotThingModelMessageService thingModelMessageService; | |
| 19 | + | |
| 20 | + @Override | |
| 21 | + public void saveDeviceData(String productKey, String deviceName, String message) { | |
| 22 | + // 1. 根据产品 key 和设备名称,获得设备信息 | |
| 23 | + IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceName(productKey, deviceName); | |
| 24 | + // 2. 解析消息,保存数据 | |
| 25 | + JSONObject jsonObject = new JSONObject(message); | |
| 26 | + log.info("[saveDeviceData][productKey({}) deviceName({}) data({})]", productKey, deviceName, jsonObject); | |
| 27 | + ThingModelMessage thingModelMessage = ThingModelMessage.builder() | |
| 28 | + .id(jsonObject.getStr("id")) | |
| 29 | + .sys(jsonObject.get("sys")) | |
| 30 | + .method(jsonObject.getStr("method")) | |
| 31 | + .params(jsonObject.get("params")) | |
| 32 | + .time(jsonObject.getLong("time") == null ? System.currentTimeMillis() : jsonObject.getLong("time")) | |
| 33 | + .productKey(productKey) | |
| 34 | + .deviceName(deviceName) | |
| 35 | + .deviceKey(device.getDeviceKey()) | |
| 36 | + .build(); | |
| 37 | + thingModelMessageService.saveThingModelMessage(thingModelMessage); | |
| 38 | + } | |
| 39 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
| ... | ... | @@ -64,4 +64,13 @@ public interface IotDeviceService { |
| 64 | 64 | * @return 设备数量 |
| 65 | 65 | */ |
| 66 | 66 | Long getDeviceCountByProductId(Long productId); |
| 67 | + | |
| 68 | + /** | |
| 69 | + * 根据产品 key 和设备名称,获得设备信息 | |
| 70 | + * | |
| 71 | + * @param productKey 产品 key | |
| 72 | + * @param deviceName 设备名称 | |
| 73 | + * @return 设备信息 | |
| 74 | + */ | |
| 75 | + IotDeviceDO getDeviceByProductKeyAndDeviceName(String productKey, String deviceName); | |
| 67 | 76 | } |
| 68 | 77 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
| ... | ... | @@ -4,6 +4,7 @@ import cn.hutool.core.util.IdUtil; |
| 4 | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | |
| 7 | 8 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDevicePageReqVO; |
| 8 | 9 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceSaveReqVO; |
| 9 | 10 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.IotDeviceStatusUpdateReqVO; |
| ... | ... | @@ -32,7 +33,7 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; |
| 32 | 33 | @Service |
| 33 | 34 | @Validated |
| 34 | 35 | @Slf4j |
| 35 | -public class DeviceServiceImpl implements IotDeviceService { | |
| 36 | +public class IotDeviceServiceImpl implements IotDeviceService { | |
| 36 | 37 | |
| 37 | 38 | @Resource |
| 38 | 39 | private IotDeviceMapper deviceMapper; |
| ... | ... | @@ -224,4 +225,10 @@ public class DeviceServiceImpl implements IotDeviceService { |
| 224 | 225 | return deviceMapper.selectCountByProductId(productId); |
| 225 | 226 | } |
| 226 | 227 | |
| 228 | + @Override | |
| 229 | + @TenantIgnore | |
| 230 | + public IotDeviceDO getDeviceByProductKeyAndDeviceName(String productKey, String deviceName) { | |
| 231 | + return deviceMapper.selectByProductKeyAndDeviceName(productKey, deviceName); | |
| 232 | + } | |
| 233 | + | |
| 227 | 234 | } |
| 228 | 235 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotDbStructureDataServiceImpl.java
| ... | ... | @@ -25,7 +25,7 @@ import java.util.stream.Collectors; |
| 25 | 25 | public class IotDbStructureDataServiceImpl implements IotDbStructureDataService { |
| 26 | 26 | |
| 27 | 27 | @Resource |
| 28 | - private TdEngineService tdEngineService; | |
| 28 | + private IotTdEngineService iotTdEngineService; | |
| 29 | 29 | |
| 30 | 30 | @Resource |
| 31 | 31 | private TdRestApi tdRestApi; |
| ... | ... | @@ -87,7 +87,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService |
| 87 | 87 | |
| 88 | 88 | // 5. 创建超级表 |
| 89 | 89 | String dataBaseName = url.substring(url.lastIndexOf("/") + 1); |
| 90 | - tdEngineService.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName); | |
| 90 | + iotTdEngineService.createSuperTable(schemaFields, tagsFields, dataBaseName, superTableName); | |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | @Override |
| ... | ... | @@ -107,7 +107,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService |
| 107 | 107 | private List<TdFieldDO> getTableFields(String tableName) { |
| 108 | 108 | List<TdFieldDO> fields = new ArrayList<>(); |
| 109 | 109 | // 获取超级表的描述信息 |
| 110 | - List<Map<String, Object>> maps = tdEngineService.describeSuperTable(url.substring(url.lastIndexOf("/") + 1), tableName); | |
| 110 | + List<Map<String, Object>> maps = iotTdEngineService.describeSuperTable(url.substring(url.lastIndexOf("/") + 1), tableName); | |
| 111 | 111 | if (maps != null) { |
| 112 | 112 | // 过滤掉 note 字段为 TAG 的记录 |
| 113 | 113 | maps = maps.stream().filter(map -> !"TAG".equals(map.get("note"))).toList(); |
| ... | ... | @@ -133,16 +133,16 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService |
| 133 | 133 | String dataBaseName = url.substring(url.lastIndexOf("/") + 1); |
| 134 | 134 | // 添加新增字段 |
| 135 | 135 | if (CollUtil.isNotEmpty(addFields)) { |
| 136 | - tdEngineService.addColumnForSuperTable(dataBaseName,tableName, addFields); | |
| 136 | + iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, addFields); | |
| 137 | 137 | } |
| 138 | 138 | // 删除旧字段 |
| 139 | 139 | if (CollUtil.isNotEmpty(dropFields)) { |
| 140 | - tdEngineService.dropColumnForSuperTable(dataBaseName,tableName, dropFields); | |
| 140 | + iotTdEngineService.dropColumnForSuperTable(dataBaseName, tableName, dropFields); | |
| 141 | 141 | } |
| 142 | 142 | // 修改字段(先删除再添加) |
| 143 | 143 | if (CollUtil.isNotEmpty(modifyFields)) { |
| 144 | - tdEngineService.dropColumnForSuperTable(dataBaseName,tableName, modifyFields); | |
| 145 | - tdEngineService.addColumnForSuperTable(dataBaseName,tableName, modifyFields); | |
| 144 | + iotTdEngineService.dropColumnForSuperTable(dataBaseName, tableName, modifyFields); | |
| 145 | + iotTdEngineService.addColumnForSuperTable(dataBaseName, tableName, modifyFields); | |
| 146 | 146 | } |
| 147 | 147 | } |
| 148 | 148 | |
| ... | ... | @@ -181,7 +181,7 @@ public class IotDbStructureDataServiceImpl implements IotDbStructureDataService |
| 181 | 181 | |
| 182 | 182 | String superTableName = getProductPropertySTableName(product.getDeviceType(), product.getProductKey()); |
| 183 | 183 | String dataBaseName = url.substring(url.lastIndexOf("/") + 1); |
| 184 | - Integer tableExists = tdEngineService.checkSuperTableExists(dataBaseName, superTableName); | |
| 184 | + Integer tableExists = iotTdEngineService.checkSuperTableExists(dataBaseName, superTableName); | |
| 185 | 185 | |
| 186 | 186 | if (tableExists != null && tableExists > 0) { |
| 187 | 187 | updateSuperTable(thingModel, product.getDeviceType()); | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineService.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotTdEngineService.java
| ... | ... | @@ -12,7 +12,7 @@ import java.util.Map; |
| 12 | 12 | /** |
| 13 | 13 | * TdEngineService |
| 14 | 14 | */ |
| 15 | -public interface TdEngineService { | |
| 15 | +public interface IotTdEngineService { | |
| 16 | 16 | |
| 17 | 17 | /** |
| 18 | 18 | * 创建数据库 |
| ... | ... | @@ -45,20 +45,20 @@ public interface TdEngineService { |
| 45 | 45 | /** |
| 46 | 46 | * 为超级表添加列 |
| 47 | 47 | * |
| 48 | - * @param dataBaseName 数据库名称 | |
| 48 | + * @param dataBaseName 数据库名称 | |
| 49 | 49 | * @param superTableName 超级表名称 |
| 50 | 50 | * @param fieldsVo 字段信息 |
| 51 | 51 | */ |
| 52 | - void addColumnForSuperTable(String dataBaseName,String superTableName, List<TdFieldDO> fieldsVo); | |
| 52 | + void addColumnForSuperTable(String dataBaseName, String superTableName, List<TdFieldDO> fieldsVo); | |
| 53 | 53 | |
| 54 | 54 | /** |
| 55 | 55 | * 为超级表删除列 |
| 56 | 56 | * |
| 57 | - * @param dataBaseName 数据库名称 | |
| 57 | + * @param dataBaseName 数据库名称 | |
| 58 | 58 | * @param superTableName 超级表名称 |
| 59 | 59 | * @param fieldsVo 字段信息 |
| 60 | 60 | */ |
| 61 | - void dropColumnForSuperTable(String dataBaseName,String superTableName, List<TdFieldDO> fieldsVo); | |
| 61 | + void dropColumnForSuperTable(String dataBaseName, String superTableName, List<TdFieldDO> fieldsVo); | |
| 62 | 62 | |
| 63 | 63 | /** |
| 64 | 64 | * 为超级表添加tag | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/TdEngineServiceImpl.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotTdEngineServiceImpl.java
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.service.tdengine; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * 物模型消息 Service | |
| 7 | + */ | |
| 8 | +public interface IotThingModelMessageService { | |
| 9 | + | |
| 10 | + /** | |
| 11 | + * 保存物模型消息 | |
| 12 | + * | |
| 13 | + * @param thingModelMessage 物模型消息 | |
| 14 | + */ | |
| 15 | + void saveThingModelMessage(ThingModelMessage thingModelMessage); | |
| 16 | +} | |
| 0 | 17 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/tdengine/IotThingModelMessageServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.service.tdengine; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.ThingModelMessage; | |
| 4 | +import org.springframework.stereotype.Service; | |
| 5 | + | |
| 6 | +@Service | |
| 7 | +public class IotThingModelMessageServiceImpl implements IotThingModelMessageService { | |
| 8 | + | |
| 9 | + @Override | |
| 10 | + public void saveThingModelMessage(ThingModelMessage thingModelMessage) { | |
| 11 | + // TODO 芋艿,后续实现 | |
| 12 | + } | |
| 13 | +} | |
| 0 | 14 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/tdengine/TdEngineMapper.xml
| ... | ... | @@ -2,9 +2,10 @@ |
| 2 | 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| 3 | 3 | |
| 4 | 4 | <mapper namespace="cn.iocoder.yudao.module.iot.dal.tdengine.TdEngineMapper"> |
| 5 | + <!-- TODO 对 $ 符号有安全要求的话,后期改为接口方式 --> | |
| 5 | 6 | |
| 6 | 7 | <update id="createDatabase" parameterType="String"> |
| 7 | - create database if not exists #{dataBaseName} | |
| 8 | + CREATE DATABASE IF NOT EXISTS ${dataBaseName} | |
| 8 | 9 | </update> |
| 9 | 10 | |
| 10 | 11 | <update id="createSuperTable"> |
| ... | ... | @@ -271,7 +272,8 @@ |
| 271 | 272 | <select id="getCountByTimestamp" parameterType="cn.iocoder.yudao.module.iot.domain.SelectDto" |
| 272 | 273 | resultType="java.util.Map"> |
| 273 | 274 | SELECT count(0) AS count |
| 274 | - FROM #{dataBaseName}.#{tableName} WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime} | |
| 275 | + FROM #{dataBaseName}.#{tableName} | |
| 276 | + WHERE ${fieldName} BETWEEN #{startTime} AND #{endTime} | |
| 275 | 277 | </select> |
| 276 | 278 | |
| 277 | 279 | <select id="showSuperTables" resultType="java.util.Map"> |
| ... | ... | @@ -287,26 +289,30 @@ |
| 287 | 289 | <select id="getLastDataByTags" parameterType="cn.iocoder.yudao.module.iot.domain.TagsSelectDao" |
| 288 | 290 | resultType="Map"> |
| 289 | 291 | select last(*) |
| 290 | - from #{dataBaseName}.#{stableName} group by ${tagsName} | |
| 292 | + from #{dataBaseName}.#{stableName} | |
| 293 | + group by ${tagsName} | |
| 291 | 294 | </select> |
| 292 | 295 | |
| 293 | 296 | <select id="getHistoryData" resultType="java.util.Map" |
| 294 | 297 | parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto"> |
| 295 | 298 | SELECT #{fieldName}, ts |
| 296 | - FROM #{dataBaseName}.#{tableName} WHERE ts BETWEEN #{startTime} AND #{endTime} | |
| 299 | + FROM #{dataBaseName}.#{tableName} | |
| 300 | + WHERE ts BETWEEN #{startTime} AND #{endTime} | |
| 297 | 301 | LIMIT #{num} |
| 298 | 302 | </select> |
| 299 | 303 | |
| 300 | 304 | <select id="getRealtimeData" resultType="java.util.Map" |
| 301 | 305 | parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto"> |
| 302 | 306 | SELECT #{fieldName}, ts |
| 303 | - FROM #{dataBaseName}.#{tableName} LIMIT #{num} | |
| 307 | + FROM #{dataBaseName}.#{tableName} | |
| 308 | + LIMIT #{num} | |
| 304 | 309 | </select> |
| 305 | 310 | |
| 306 | 311 | <select id="getAggregateData" resultType="java.util.Map" |
| 307 | 312 | parameterType="cn.iocoder.yudao.module.iot.domain.visual.SelectVisualDto"> |
| 308 | 313 | SELECT #{aggregate}(${fieldName}) |
| 309 | - FROM #{dataBaseName}.#{tableName} WHERE ts BETWEEN #{startTime} AND #{endTime} interval (${interval}) | |
| 314 | + FROM #{dataBaseName}.#{tableName} | |
| 315 | + WHERE ts BETWEEN #{startTime} AND #{endTime} interval (${interval}) | |
| 310 | 316 | LIMIT #{num} |
| 311 | 317 | </select> |
| 312 | 318 | ... | ... |