Quellcode durchsuchen

【功能优化】Bpm:完善设备属性的历史值

YunaiV vor 6 Monaten
Ursprung
Commit
dfa03d24fd

+ 14 - 11
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDevicePropertyController.java

@@ -1,13 +1,13 @@
 package cn.iocoder.yudao.module.iot.controller.admin.device;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceDataPageReqVO;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceDataRespVO;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotTimeDataRespVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyPageReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
@@ -42,9 +42,10 @@ public class IotDevicePropertyController {
     @Resource
     private IotDeviceService deviceService;
 
+    // TODO @芋艿:权限
     @GetMapping("/latest")
     @Operation(summary = "获取设备属性最新属性")
-    public CommonResult<List<IotDeviceDataRespVO>> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO pageReqVO) {
+    public CommonResult<List<IotDevicePropertyRespVO>> getLatestDeviceProperties(@Valid IotDevicePropertyPageReqVO pageReqVO) {
         Map<String, IotDevicePropertyDO> properties = devicePropertyService.getLatestDeviceProperties(pageReqVO);
 
         // 拼接数据
@@ -58,18 +59,20 @@ public class IotDevicePropertyController {
                 return null;
             }
             IotDevicePropertyDO property = entry.getValue();
-            return BeanUtils.toBean(thingModel, IotDeviceDataRespVO.class)
+            return BeanUtils.toBean(thingModel, IotDevicePropertyRespVO.class)
                     .setDataType(thingModel.getProperty().getDataType())
-                    .setValue(property.getValue()).setUpdateTime(property.getUpdateTime());
+                    .setValue(property.getValue())
+                    .setUpdateTime(LocalDateTimeUtil.toEpochMilli(property.getUpdateTime()));
         }));
     }
 
-    // TODO @浩浩:这里的 /history-page 包括方法名。
-    @GetMapping("/history")
+    // TODO @芋艿:权限
+    @GetMapping("/history-page")
     @Operation(summary = "获取设备属性历史数据")
-    public CommonResult<PageResult<IotTimeDataRespVO>> getHistoryDeviceProperties(@Valid IotDeviceDataPageReqVO pageReqVO) {
-        PageResult<Map<String, Object>> list = devicePropertyService.getHistoryDeviceProperties(pageReqVO);
-        return success(BeanUtils.toBean(list, IotTimeDataRespVO.class));
+    public CommonResult<PageResult<IotDevicePropertyRespVO>> getHistoryDevicePropertyPage(
+            @Valid IotDevicePropertyPageReqVO pageReqVO) {
+        Assert.notEmpty(pageReqVO.getIdentifier(), "标识符不能为空");
+        return success(devicePropertyService.getHistoryDevicePropertyPage(pageReqVO));
     }
 
 }

+ 5 - 2
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/data/IotDeviceDataPageReqVO.java → yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/data/IotDevicePropertyPageReqVO.java

@@ -5,14 +5,17 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
-@Schema(description = "管理后台 - IoT 设备数据 Request VO")
+@Schema(description = "管理后台 - IoT 设备属性 Request VO")
 @Data
-public class IotDeviceDataPageReqVO extends PageParam {
+public class IotDevicePropertyPageReqVO extends PageParam {
 
     @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "177")
     @NotNull(message = "设备编号不能为空")
     private Long deviceId;
 
+    @Schema(description = "设备 Key", hidden = true)
+    private String deviceKey; // 非前端传递,后端自己查询设置
+
     @Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
     private String identifier;
 

+ 2 - 7
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/data/IotDeviceDataRespVO.java → yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/data/IotDevicePropertyRespVO.java

@@ -3,11 +3,9 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
-import java.time.LocalDateTime;
-
 @Schema(description = "管理后台 - IoT 设备属性 Response VO")
 @Data
-public class IotDeviceDataRespVO {
+public class IotDevicePropertyRespVO {
 
     @Schema(description = "属性标识符", requiredMode = Schema.RequiredMode.REQUIRED)
     private String identifier;
@@ -16,13 +14,10 @@ public class IotDeviceDataRespVO {
     private Object value;
 
     @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    private LocalDateTime updateTime;
+    private Long updateTime;
 
     // ========== 基于 ThingModel 查询 ==========
 
-//    @Schema(description = "物模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21816")
-//    private Long thingModelId;
-
     @Schema(description = "属性名称", requiredMode = Schema.RequiredMode.REQUIRED)
     private String name;
 

+ 0 - 23
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/data/IotTimeDataRespVO.java

@@ -1,23 +0,0 @@
-package cn.iocoder.yudao.module.iot.controller.admin.device.vo.data;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class IotTimeDataRespVO {
-
-    /**
-     * 时间
-     */
-    private long time;
-
-    /**
-     * 数据值
-     */
-    private Object data;
-
-}

+ 0 - 71
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/tdengine/SelectVisualDO.java

@@ -1,71 +0,0 @@
-package cn.iocoder.yudao.module.iot.dal.dataobject.tdengine;
-
-import lombok.Data;
-
-import java.util.Map;
-
-// TODO @haohao:类似 SelectDO 的想法,只是它是返回。ps:貌似可以在 tdengine 里面,创建一个 query 包,放这种比较特殊的查询和结果对象。dataobject 更多还是实际存储的结构化的 do
-@Data
-@Deprecated
-public class SelectVisualDO {
-
-    /**
-     * 数据库名称
-     */
-    private String dataBaseName;
-
-    /**
-     * 表名
-     */
-    private String tableName;
-
-
-    private String deviceKey;
-
-    /**
-     * 属性
-     */
-    private String fieldName;
-
-    /**
-     * 查询类型,0历史数据,1实时数据,2聚合数据
-     */
-    private int type;
-
-    /**
-     * 查询的数据量
-     */
-    private int num;
-
-    /**
-     * 聚合函数
-     */
-    private String aggregate;
-
-    /**
-     * 统计间隔数字+s/m/h/d
-     * 比如1s,1m,1h,1d代表1秒,1分钟,1小时,1天
-     */
-    private String interval;
-
-    /**
-     * 开始时间
-     */
-    private Long startTime;
-
-    /**
-     * 结束时间
-     */
-    private Long endTime;
-
-    /**
-     * 请求参数
-     */
-    private Map<String, Object> params;
-
-    private String sql;
-
-    private String deviceId;
-
-    private Long lastTime;
-}

+ 1 - 9
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDeviceLogMapper.java

@@ -44,14 +44,6 @@ public interface IotDeviceLogMapper {
      * @return 设备日志列表
      */
     IPage<IotDeviceLogDO> selectPage(IPage<IotDeviceLogDO> page,
-                                    @Param("reqVO") IotDeviceLogPageReqVO reqVO);
-
-    /**
-     * 获得设备日志总数
-     *
-     * @param reqVO 查询条件
-     * @return 日志总数
-     */
-    Long selectCount(@Param("reqVO") IotDeviceLogPageReqVO reqVO);
+                                     @Param("reqVO") IotDeviceLogPageReqVO reqVO);
 
 }

+ 5 - 20
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/tdengine/IotDevicePropertyMapper.java

@@ -3,12 +3,13 @@ package cn.iocoder.yudao.module.iot.dal.tdengine;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyPageReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
-import cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO;
 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 com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -83,23 +84,7 @@ public interface IotDevicePropertyMapper {
                 @Param("properties") Map<String, Object> properties,
                 @Param("reportTime") Long reportTime);
 
-    // TODO @芋艿:待实现
-    /**
-     * 获取历史数据列表
-     *
-     * @param selectVisualDO 查询条件
-     * @return 历史数据列表
-     */
-    @TenantIgnore
-    List<Map<String, Object>> selectHistoryDataList(SelectVisualDO selectVisualDO);
-
-    /**
-     * 获取历史数据条数
-     *
-     * @param selectVisualDO 查询条件
-     * @return 数据条数
-     */
-    @TenantIgnore
-    Long selectHistoryCount(SelectVisualDO selectVisualDO);
+    IPage<IotDevicePropertyRespVO> selectPageByHistory(IPage<?> page,
+                                                       @Param("reqVO") IotDevicePropertyPageReqVO reqVO);
 
 }

+ 5 - 4
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDevicePropertyService.java

@@ -1,7 +1,8 @@
 package cn.iocoder.yudao.module.iot.service.device.data;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceDataPageReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyPageReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
 import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
 import jakarta.validation.Valid;
@@ -35,14 +36,14 @@ public interface IotDevicePropertyService {
      * @param deviceId 设备编号
      * @return 设备属性最新数据
      */
-    Map<String, IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO deviceId);
+    Map<String, IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDevicePropertyPageReqVO deviceId);
 
     /**
      * 获得设备属性历史数据
      *
-     * @param deviceDataReqVO 设备属性历史数据 Request VO
+     * @param pageReqVO 分页请求
      * @return 设备属性历史数据
      */
-    PageResult<Map<String, Object>> getHistoryDeviceProperties(@Valid IotDeviceDataPageReqVO deviceDataReqVO);
+    PageResult<IotDevicePropertyRespVO> getHistoryDevicePropertyPage(@Valid IotDevicePropertyPageReqVO pageReqVO);
 
 }

+ 15 - 30
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDevicePropertyServiceImpl.java

@@ -6,7 +6,8 @@ import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
-import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDeviceDataPageReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyPageReqVO;
+import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO;
 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
@@ -21,6 +22,8 @@ import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
 import cn.iocoder.yudao.module.iot.service.product.IotProductService;
 import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import jakarta.annotation.Resource;
 import jakarta.validation.Valid;
 import lombok.extern.slf4j.Slf4j;
@@ -150,8 +153,9 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService {
                 entry -> IotDevicePropertyDO.builder().value(entry.getValue()).updateTime(message.getReportTime()).build()));
     }
 
+    // TODO @芋艿:需要在优化下,根据 name 之类的过滤
     @Override
-    public Map<String, IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDeviceDataPageReqVO pageReqVO) {
+    public Map<String, IotDevicePropertyDO> getLatestDeviceProperties(@Valid IotDevicePropertyPageReqVO pageReqVO) {
         // 获取设备信息
         IotDeviceDO device = deviceService.validateDeviceExists(pageReqVO.getDeviceId());
 
@@ -160,34 +164,15 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService {
     }
 
     @Override
-    public PageResult<Map<String, Object>> getHistoryDeviceProperties(IotDeviceDataPageReqVO deviceDataReqVO) {
-//        PageResult<Map<String, Object>> pageResult = new PageResult<>();
-//        // 1. 获取设备信息
-//        IotDeviceDO device = deviceService.getDevice(deviceDataReqVO.getDeviceId());
-//        // 2. 获取设备属性历史数据
-//        SelectVisualDO selectVisualDO = new SelectVisualDO();
-//        selectVisualDO.setDataBaseName(getDatabaseName());
-//        selectVisualDO.setTableName(getDeviceTableName(device.getProductKey(), device.getDeviceName()));
-//        selectVisualDO.setDeviceKey(device.getDeviceKey());
-//        selectVisualDO.setFieldName(deviceDataReqVO.getIdentifier());
-//        selectVisualDO.setStartTime(DateUtil.date(deviceDataReqVO.getTimes()[0].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
-//        selectVisualDO.setEndTime(DateUtil.date(deviceDataReqVO.getTimes()[1].atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime());
-//        Map<String, Object> params = new HashMap<>();
-//        params.put("rows", deviceDataReqVO.getPageSize());
-//        params.put("page", (deviceDataReqVO.getPageNo() - 1) * deviceDataReqVO.getPageSize());
-//        selectVisualDO.setParams(params);
-//        pageResult.setList(devicePropertyDataMapper.selectHistoryDataList(selectVisualDO));
-//        pageResult.setTotal(devicePropertyDataMapper.selectHistoryCount(selectVisualDO));
-//        return pageResult;
-        return null; // TODO 芋艿:晚点实现
-    }
+    public PageResult<IotDevicePropertyRespVO> getHistoryDevicePropertyPage(IotDevicePropertyPageReqVO pageReqVO) {
+        // 获取设备信息
+        IotDeviceDO device = deviceService.validateDeviceExists(pageReqVO.getDeviceId());
+        pageReqVO.setDeviceKey(device.getDeviceKey());
 
-//    private String getDatabaseName() {
-//        return StrUtil.subAfter(url, "/", true);
-//    }
-//
-//    private static String getDeviceTableName(String productKey, String deviceName) {
-//        return String.format(IotConstants.DEVICE_TABLE_NAME_FORMAT, productKey, deviceName);
-//    }
+        // TODO @芋艿:增加一个表不存在的 try catch
+        IPage<IotDevicePropertyRespVO> page = devicePropertyMapper.selectPageByHistory(
+                new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO);
+        return new PageResult<>(page.getRecords(), page.getTotal());
+    }
 
 }

+ 5 - 19
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyMapper.xml

@@ -45,7 +45,6 @@
         DROP COLUMN ${field.field}
     </update>
 
-    <!-- TODO 芋艿,report_time 需要增加下 -->
     <insert id="insert">
         INSERT INTO device_property_${device.deviceKey}
         USING product_property_${device.productKey}
@@ -63,29 +62,16 @@
         )
     </insert>
 
-    <!-- 描述超级表结构 -->
     <select id="describeSuperTable" resultType="java.util.Map">
         DESCRIBE product_property_${productKey}
     </select>
 
-    <!-- 获取历史数据 -->
-    <select id="selectHistoryDataList" resultType="java.util.Map"
-            parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
-        SELECT ${fieldName} AS data, ts AS time
-        FROM device_property_${deviceKey}
-        WHERE ts BETWEEN #{startTime} AND #{endTime}
-          AND ${fieldName} IS NOT NULL
+    <!-- TODO 芋艿:缺少时间范围 AND ts BETWEEN #{reqVO.startTime} AND #{reqVO.endTime} -->
+    <select id="selectPageByHistory" resultType="cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO">
+        SELECT ${reqVO.identifier} AS `value`, report_time AS update_time
+        FROM device_property_${reqVO.deviceKey}
+        WHERE ${reqVO.identifier} IS NOT NULL
         ORDER BY ts DESC
-        LIMIT #{params.rows} OFFSET #{params.page}
-    </select>
-
-    <!-- 统计历史数据总数 -->
-    <select id="selectHistoryCount" resultType="java.lang.Long"
-            parameterType="cn.iocoder.yudao.module.iot.dal.dataobject.tdengine.SelectVisualDO">
-        SELECT COUNT(*)
-        FROM device_property_${deviceKey}
-        WHERE ts BETWEEN #{startTime} AND #{endTime}
-          AND ${fieldName} IS NOT NULL
     </select>
 
 </mapper>