Przeglądaj źródła

add:添加OTA上报记录结果并新增OTA上报结果查询

荭琪枫 2 lat temu
rodzic
commit
e772f90e08

Plik diff jest za duży
+ 0 - 0
data/components/eabb131d-8fd1-43a8-88d9-a198abfd3d42/component.js


+ 194 - 183
data/converters/6260396d67aced2696184053/converter.js

@@ -1,194 +1,205 @@
+var mid = 1;
 
-var mid=1;
-
-function getMid(){
-  mid++;
-  if(mid>10000){
-	mid=1;
-  }
-  return mid+"";
+function getMid() {
+    mid++;
+    if (mid > 10000) {
+        mid = 1;
+    }
+    return mid + "";
 }
 
 this.decode = function (msg) {
-  //对msg进行解析,并返回物模型数据
-  var content=msg.content;
-  var topic = content.topic;
-  var payload = content.payload;
-  var identifier = topic.substring(topic.lastIndexOf("/") + 1);
-  
-  //透传上报
-  if(topic.endsWith("/event/rawReport")){
-	var rst= component.transparentDecode(payload.params);
-	if(!rst){
-	  return null;
-	}
-	rst.occur=new Date().getTime();
-	rst.time=new Date().getTime();
-	return rst;
-  }
+    //对msg进行解析,并返回物模型数据
+    var content = msg.content;
+    var topic = content.topic;
+    var payload = content.payload;
+    var identifier = topic.substring(topic.lastIndexOf("/") + 1);
+
+    //透传上报
+    if (topic.endsWith("/event/rawReport")) {
+        var rst = component.transparentDecode(payload.params);
+        if (!rst) {
+            return null;
+        }
+        rst.occur = new Date().getTime();
+        rst.time = new Date().getTime();
+        return rst;
+    }
 
-  if (topic.endsWith("/property/post")) {
-	//属性上报
-	return {
-	  mid: msg.mid,
-	  productKey: msg.productKey, 
-	  deviceName: msg.deviceName,
-	  type:"property",
-	  identifier: "report", //属性上报
-	  occur: new Date().getTime(), //时间戳,设备上的事件或数据产生的本地时间
-	  time: new Date().getTime(), //时间戳,消息上报时间
-	  data: payload.params,
-	};
-  } else if (topic.indexOf("/event/") > 0) {
-	//事件上报
-	return {
-	  mid: msg.mid,
-	  productKey: msg.productKey,
-	  deviceName: msg.deviceName,
-	  type:"event",
-	  identifier: identifier,
-	  occur: new Date().getTime(),
-	  time: new Date().getTime(),
-	  data: payload.params,
-	};
-  }else if(topic.endsWith("/service/property/set_reply")){
-	//属性设置回复
-	return {
-	  mid: msg.mid,
-	  productKey: msg.productKey,
-	  deviceName: msg.deviceName,
-	  type:"property",
-	  identifier: identifier,
-	  occur: new Date().getTime(),
-	  time: new Date().getTime(),
-	  code: payload.code
-	};
-  }else if(topic.endsWith("/config/set_reply")){
-	//设备配置设置回复
-	return {
-	  mid: msg.mid,
-	  productKey: msg.productKey,
-	  deviceName: msg.deviceName,
-	  type:"config",
-	  identifier: "set_reply",
-	  occur: new Date().getTime(),
-	  time: new Date().getTime(),
-	  code: payload.code
-	};
-  }else if(topic.endsWith("/config/get")){
-	//设备配置获取
-	return {
-	  mid: msg.mid,
-	  productKey: msg.productKey,
-	  deviceName: msg.deviceName,
-	  type:"config",
-	  identifier: "get",
-	  occur: new Date().getTime(),
-	  time: new Date().getTime(),
-	  data: {},
-	};
-  } else if (topic.endsWith("_reply")) {
-	//服务回复
-	return {
-	  mid: msg.mid,
-	  productKey: msg.productKey,
-	  deviceName: msg.deviceName,
-	  type:"service",
-	  identifier: identifier,
-	  occur: new Date().getTime(),
-	  time: new Date().getTime(),
-	  code: payload.code,
-	  data: payload.data,
-	};
-  }
-  return null;
+    if (topic.endsWith("/property/post")) {
+        //属性上报
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type: "property",
+            identifier: "report", //属性上报
+            occur: new Date().getTime(), //时间戳,设备上的事件或数据产生的本地时间
+            time: new Date().getTime(), //时间戳,消息上报时间
+            data: payload.params,
+        };
+    } else if (topic.indexOf("/ota/") >= 0) {
+        //事件上报
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type: "ota",
+            identifier: "ota",
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            data: payload.params,
+        };
+    } else if (topic.indexOf("/event/") > 0) {
+        //事件上报
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type: "event",
+            identifier: identifier,
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            data: payload.params,
+        };
+    } else if (topic.endsWith("/service/property/set_reply")) {
+        //属性设置回复
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type: "property",
+            identifier: identifier,
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            code: payload.code
+        };
+    } else if (topic.endsWith("/config/set_reply")) {
+        //设备配置设置回复
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type: "config",
+            identifier: "set_reply",
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            code: payload.code
+        };
+    } else if (topic.endsWith("/config/get")) {
+        //设备配置获取
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type: "config",
+            identifier: "get",
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            data: {},
+        };
+    } else if (topic.endsWith("_reply")) {
+        //服务回复
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type: "service",
+            identifier: identifier,
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            code: payload.code,
+            data: payload.data,
+        };
+    }
+    return null;
 };
 
-this.encode = function (service,device) {
-  var deviceMid=getMid();
-  var method="thing.service.";
-  var topic="/sys/"+service.productKey+"/"+service.deviceName+"/c/service/";
-  var params={};
+this.encode = function (service, device) {
+    var deviceMid = getMid();
+    var method = "thing.service.";
+    var topic = "/sys/" + service.productKey + "/" + service.deviceName + "/c/service/";
+    var params = {};
+
+    //透传下发
+    if (device.transparent) {
+        var rst = component.transparentEncode(service, device);
+        topic = "/sys/" + rst.productKey + "/" + rst.deviceName + "/c/service/rawSend";
+        params.model = rst.content.model;
+        params.deviceName = rst.content.deviceName;
+        params.data = rst.content.data;
+
+        return {
+            productKey: rst.productKey,
+            deviceName: rst.deviceName,
+            mid: rst.mid,
+            content: {
+                topic: topic,
+                payload: JSON.stringify({
+                    id: rst.mid,
+                    method: method + "rawSend",
+                    params: params
+                })
+            }
+        }
+
+    }
+
+    var type = service.type;
+    var identifier = service.identifier;
+
+    if (type == "property") {
+        method += "property." + identifier;
+        topic += "property/" + identifier;
+    } else if (type == "service") {
+        method += identifier;
+        topic += identifier;
+    } else if (type == "config") {
+        //设备配置下发
+        method += identifier;
+        topic = "/sys/" + service.productKey + "/" + service.deviceName + "/c/config/" + identifier;
+    } else if (type = "lifetime") {
+        //子设备注销下发
+        method += identifier;
+        topic = "/sys/" + service.productKey + "/" + service.deviceName + "/c/deregister";
+    }
+    if (type == "property" && identifier == "get") {
+        var listParams = []
+        for (var p in service.params) {
+            listParams.push(service.params[p]);
+        }
+        return {
+            productKey: service.productKey,
+            deviceName: service.deviceName,
+            mid: deviceMid,
+            content: {
+                topic: topic,
+                payload: JSON.stringify({
+                    id: deviceMid,
+                    method: method,
+                    params: listParams
+                })
+            }
+        }
+    } else {
+        for (var p in service.params) {
+            params[p] = service.params[p];
+        }
+        return {
+            productKey: service.productKey,
+            deviceName: service.deviceName,
+            mid: deviceMid,
+            content: {
+                topic: topic,
+                payload: JSON.stringify({
+                    id: deviceMid,
+                    method: method,
+                    params: params
+                })
+            }
+        }
 
-  //透传下发
-  if(device.transparent){
-	var rst=component.transparentEncode(service,device);
-	topic="/sys/"+rst.productKey+"/"+rst.deviceName+"/c/service/rawSend";
-	params.model=rst.content.model;
-	params.deviceName=rst.content.deviceName;
-	params.data=rst.content.data;
-	
-	return {
-	  productKey:rst.productKey,
-	  deviceName:rst.deviceName,
-	  mid:rst.mid,
-	  content:{
-		topic:topic,
-		payload:JSON.stringify({
-		  id:rst.mid,
-		  method:method+"rawSend",
-		  params:params
-		})
-	  }
-	}
-	
-  }
-  
-  var type=service.type;
-  var identifier=service.identifier;
+    }
 
-  if(type=="property"){
-	method+="property."+identifier;
-	topic+="property/"+identifier;
-  }else if(type=="service"){
-	method+=identifier;
-	topic+=identifier;
-  }else if(type=="config"){
-	//设备配置下发
-	method+=identifier;
-	topic="/sys/"+service.productKey+"/"+service.deviceName+"/c/config/"+identifier;
-  }else if(type="lifetime"){
-	//子设备注销下发
-	method+=identifier;
-	topic="/sys/"+service.productKey+"/"+service.deviceName+"/c/deregister";
-  }
-  if(type=="property" && identifier=="get"  ){
-	var listParams = []
-	for(var p in service.params){
-	listParams.push(service.params[p]);
-  }
-	return {
-	productKey:service.productKey,
-	deviceName:service.deviceName,
-	mid:deviceMid,
-	content:{
-	  topic:topic,
-	  payload:JSON.stringify({
-		id:deviceMid,
-		method:method,
-		params: listParams
-	  })
-	}
-  }
-  }else{
-   for(var p in service.params){
-	params[p]=service.params[p];
-  }
-	return {
-	productKey:service.productKey,
-	deviceName:service.deviceName,
-	mid:deviceMid,
-	content:{
-	  topic:topic,
-	  payload:JSON.stringify({
-		id:deviceMid,
-		method:method,
-		params:params
-	  })
-	}
-  }
 
-  }
- 
-  
 };

+ 7 - 0
iot-common/iot-common-core/src/main/java/cc/iotkit/common/utils/JsonUtils.java

@@ -15,6 +15,7 @@ import lombok.SneakyThrows;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * JSON 工具类
@@ -118,5 +119,11 @@ public class JsonUtils {
             throw new RuntimeException(e);
         }
     }
+    public static <T> T objectToJavaBean(Object obj, Class<T> clazz) {
+        if (Objects.isNull(obj)) {
+            return null;
+        }
+        return OBJECT_MAPPER.convertValue(obj,clazz);
+    }
 
 }

+ 14 - 2
iot-common/iot-common-dao/iot-common-model/src/main/java/cc/iotkit/model/ota/DeviceOtaInfo.java

@@ -13,11 +13,23 @@ import lombok.*;
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class DeviceOtaInfo implements Id<String> {
-    private String id;
+public class DeviceOtaInfo implements Id<Long> {
+
+    private Long id;
+
     private Integer step;
+
+    private String taskId;
+
     private String desc;
+
     private String version;
+
     private String module;
+
     private String deviceId;
+
+    private String productKey;
+
+    private String deviceName;
 }

+ 1 - 1
iot-common/iot-common-dao/iot-data-service/src/main/java/cc/iotkit/data/manager/IDeviceOtaInfoData.java

@@ -8,5 +8,5 @@ import cc.iotkit.model.ota.DeviceOtaInfo;
  * @Date: 2023/6/15 22:14
  * @Description:
  */
-public interface IDeviceOtaInfoData extends ICommonData<DeviceOtaInfo, String> {
+public interface IDeviceOtaInfoData extends ICommonData<DeviceOtaInfo, Long> {
 }

+ 19 - 2
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbDeviceOtaInfo.java

@@ -1,5 +1,6 @@
 package cc.iotkit.data.model;
 
+import cc.iotkit.model.ota.DeviceOtaInfo;
 import io.github.linpeilie.annotations.AutoMapper;
 import io.swagger.annotations.ApiModel;
 import lombok.Data;
@@ -19,10 +20,26 @@ import javax.persistence.Table;
 @Entity
 @Table(name = "device_ota_info")
 @ApiModel(value = "设备信息")
-@AutoMapper(target = TbDeviceOtaInfo.class)
+@AutoMapper(target = DeviceOtaInfo.class)
 public class TbDeviceOtaInfo {
     @Id
     @GeneratedValue(generator = "SnowflakeIdGenerator")
     @GenericGenerator(name = "SnowflakeIdGenerator", strategy = "cc.iotkit.data.config.id.SnowflakeIdGenerator")
-    private String id;
+    private Long id;
+
+    private Integer step;
+
+    private String taskId;
+
+    private String desc;
+
+    private String version;
+
+    private String module;
+
+    private String deviceId;
+
+    private String productKey;
+
+    private String deviceName;
 }

+ 2 - 2
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/service/DeviceOtaInfoDataImpl.java

@@ -19,9 +19,9 @@ import org.springframework.stereotype.Service;
 @Primary
 @Service
 @RequiredArgsConstructor
-public class DeviceOtaInfoDataImpl implements IDeviceOtaInfoData, IJPACommData<DeviceOtaInfo, String> {
+public class DeviceOtaInfoDataImpl implements IDeviceOtaInfoData, IJPACommData<DeviceOtaInfo, Long> {
 
-    private DeviceOtaInfoRepository deviceOtaInfoRepository;
+    private final DeviceOtaInfoRepository deviceOtaInfoRepository;
 
     private final JPAQueryFactory jpaQueryFactory;
 

+ 22 - 6
iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DeviceBehaviourService.java

@@ -14,6 +14,7 @@ import cc.iotkit.common.enums.ErrCode;
 import cc.iotkit.common.exception.BizException;
 import cc.iotkit.common.utils.DeviceUtil;
 import cc.iotkit.common.utils.JsonUtils;
+import cc.iotkit.common.utils.MapstructUtils;
 import cc.iotkit.common.utils.UniqueIdUtil;
 import cc.iotkit.comp.model.DeviceState;
 import cc.iotkit.comp.model.RegisterInfo;
@@ -33,9 +34,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.UUID;
+import java.util.*;
 
 @Slf4j
 @Service
@@ -274,8 +273,25 @@ public class DeviceBehaviourService {
     }
 
     public void deviceOta(ThingModelMessage message) {
-        DeviceOtaInfo otaInfo = (DeviceOtaInfo)message.getData();
-        otaInfo.setDeviceId(message.getDeviceId());
-        deviceOtaInfoData.save(otaInfo);
+        DeviceOtaInfo deviceOtaInfoTemp = JsonUtils.objectToJavaBean(message.getData(), DeviceOtaInfo.class);
+        if (Objects.isNull(deviceOtaInfoTemp)) {
+            log.debug("device ota upload data is null deviceId:{}", message.getDeviceId());
+            return;
+        }
+        deviceOtaInfoTemp.setTaskId(message.getMid());
+        deviceOtaInfoTemp.setDeviceId(message.getDeviceId());
+        deviceOtaInfoTemp.setDeviceName(message.getDeviceName());
+        deviceOtaInfoTemp.setProductKey(message.getProductKey());
+        DeviceOtaInfo deviceOtaInfo = deviceOtaInfoData.findOneByCondition(DeviceOtaInfo.builder()
+                .taskId(message.getMid())
+                        .productKey(message.getProductKey())
+                        .deviceName(message.getDeviceName())
+                .deviceId(message.getDeviceId()).build());
+        if (Objects.nonNull(deviceOtaInfo)) {
+            deviceOtaInfo.setStep(deviceOtaInfoTemp.getStep());
+        }else{
+            deviceOtaInfo = deviceOtaInfoTemp;
+        }
+        deviceOtaInfoData.save(deviceOtaInfo);
     }
 }

+ 14 - 4
iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/OtaController.java

@@ -3,6 +3,9 @@ package cc.iotkit.manager.controller;
 import cc.iotkit.common.api.PageRequest;
 import cc.iotkit.common.api.Paging;
 import cc.iotkit.common.api.Request;
+import cc.iotkit.manager.dto.bo.ota.DeviceOtaInfoBo;
+import cc.iotkit.manager.dto.bo.ota.DeviceUpgradeBo;
+import cc.iotkit.manager.dto.vo.ota.DeviceOtaInfoVO;
 import cc.iotkit.manager.service.OtaService;
 import cc.iotkit.model.alert.AlertConfig;
 import cc.iotkit.model.ota.DeviceOta;
@@ -66,10 +69,17 @@ public class OtaController {
         return otaService.getOtaPackagePageList(request);
     }
 
-    @ApiOperation("设备获取升级")
+    @ApiOperation("设备升级")
     @PostMapping("/device/upgrade")
-    public void deviceUpgrade(@RequestBody Request<DeviceOta> deviceOtaRequest) {
-        DeviceOta deviceOta = deviceOtaRequest.getData();
-        otaService.findByVersionGreaterThan(deviceOta.getCurrentVersion(), deviceOta.getDeviceId());
+    public void deviceUpgrade(@RequestBody Request<DeviceUpgradeBo> request) {
+        otaService.startUpgrade(request.getData().getOtaId(), request.getData().getDeviceId());
     }
+
+    @ApiOperation("设备升级结果查询")
+    @PostMapping("/result")
+    public Paging<DeviceOtaInfoVO> otaResult(@RequestBody PageRequest<DeviceOtaInfoBo> request) {
+        return otaService.otaResult(request);
+    }
+
+
 }

+ 29 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/ota/DeviceOtaInfoBo.java

@@ -0,0 +1,29 @@
+package cc.iotkit.manager.dto.bo.ota;
+
+import cc.iotkit.common.api.BaseDto;
+import io.github.linpeilie.annotations.AutoMapper;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: 石恒
+ * @Date: 2023/6/17 20:45
+ * @Description:
+ */
+@Data
+@ApiModel(value = "DeviceOtaInfoBo")
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DeviceOtaInfoBo.class, reverseConvertGenerate = false)
+public class DeviceOtaInfoBo extends BaseDto {
+
+    private String taskId;
+
+    private String version;
+
+    private String deviceId;
+
+    private String productKey;
+
+    private String deviceName;
+}

+ 22 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/ota/DeviceUpgradeBo.java

@@ -0,0 +1,22 @@
+package cc.iotkit.manager.dto.bo.ota;
+
+import cc.iotkit.common.api.BaseDto;
+import io.github.linpeilie.annotations.AutoMapper;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: 石恒
+ * @Date: 2023/6/16 21:13
+ * @Description:
+ */
+@ApiModel(value = "DeviceUpgradeBo")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DeviceUpgradeBo.class, reverseConvertGenerate = false)
+public class DeviceUpgradeBo extends BaseDto {
+    private static final long serialVersionUID = -1L;
+    private String deviceId;
+    private String otaId;
+}

+ 38 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/ota/DeviceOtaInfoVO.java

@@ -0,0 +1,38 @@
+package cc.iotkit.manager.dto.vo.ota;
+
+import cc.iotkit.model.device.DeviceInfo;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import io.github.linpeilie.annotations.AutoMapper;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author: 石恒
+ * @Date: 2023/6/17 20:49
+ * @Description:
+ */
+@Data
+@ExcelIgnoreUnannotated
+@ApiModel(value = "DeviceOtaInfoVO")
+@AutoMapper(target = DeviceOtaInfoVO.class)
+public class DeviceOtaInfoVO implements Serializable {
+    private Long id;
+
+    private Integer step;
+
+    private String taskId;
+
+    private String desc;
+
+    private String version;
+
+    private String module;
+
+    private String deviceId;
+
+    private String productKey;
+
+    private String deviceName;
+}

+ 1 - 1
iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/DeviceService.java

@@ -76,7 +76,7 @@ public class DeviceService {
     public String otaUpgrade(String deviceId, boolean checkOwner, Object data) {
         DeviceInfo device = getAndCheckDevice(deviceId, checkOwner);
         return send(deviceId, device.getProductKey(), device.getDeviceName(),
-                data, ThingModelMessage.TYPE_OTA, "OTA");
+                data, ThingModelMessage.TYPE_OTA, "ota");
     }
 
     /**

+ 14 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/OtaService.java

@@ -2,16 +2,25 @@ package cc.iotkit.manager.service;
 
 import cc.iotkit.common.api.PageRequest;
 import cc.iotkit.common.api.Paging;
+import cc.iotkit.common.api.Request;
 import cc.iotkit.comps.ApiTool;
+import cc.iotkit.data.manager.IDeviceOtaInfoData;
 import cc.iotkit.data.manager.IOtaDeviceData;
 import cc.iotkit.data.manager.IOtaPackageData;
+import cc.iotkit.data.service.DeviceOtaInfoDataImpl;
+import cc.iotkit.manager.dto.bo.ota.DeviceOtaInfoBo;
+import cc.iotkit.manager.dto.vo.channel.ChannelTemplateVo;
+import cc.iotkit.manager.dto.vo.ota.DeviceOtaInfoVO;
 import cc.iotkit.model.alert.AlertConfig;
+import cc.iotkit.model.notify.ChannelTemplate;
+import cc.iotkit.model.ota.DeviceOtaInfo;
 import cc.iotkit.model.ota.OtaPackage;
 import com.google.gson.JsonObject;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RequestBody;
 
 import java.io.InputStream;
 import java.util.UUID;
@@ -29,6 +38,7 @@ public class OtaService {
     private final IOtaPackageData iOtaPackageData;
     private final IOtaDeviceData iOtaDeviceData;
     private final DeviceService deviceService;
+    private final IDeviceOtaInfoData deviceOtaInfoData;
 
 
     @Value("${oss.region}")
@@ -87,4 +97,8 @@ public class OtaService {
         return ota;
     }
 
+    public Paging<DeviceOtaInfoVO> otaResult(PageRequest<DeviceOtaInfoBo> request) {
+        return deviceOtaInfoData.findAll(request.to(DeviceOtaInfo.class)).to(DeviceOtaInfoVO.class);
+    }
+
 }

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików