diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java index 5829f56e..9dea308d 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java @@ -23,6 +23,7 @@ import cc.iotkit.manager.dto.bo.thingmodel.ThingModelMessageBo; import cc.iotkit.manager.dto.vo.deviceconfig.DeviceConfigVo; import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupImportVo; import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupVo; +import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoImportVo; import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo; import cc.iotkit.manager.dto.vo.deviceinfo.ParentDeviceVo; import cc.iotkit.manager.dto.vo.thingmodel.ThingModelVo; @@ -150,6 +151,26 @@ public class DeviceController { return deviceServiceImpl.batchDeleteDevice(request.getData()); } + + /** + * 导入设备-批量添加设备 + */ + @ApiOperation(value = "导入设备") + @SaCheckPermission("iot:device:add") + @PostMapping("/importData") + public Response importDevice(@RequestPart("file") MultipartFile file, @RequestParam("requestId") String requestId) { + return new Response(200, deviceServiceImpl.importDevice(file), null, requestId); + } + + /** + * 获取导入设备模板 + */ + @ApiOperation("下载设备模板") + @PostMapping("/exportData") + public void exportDeviceTemplate(HttpServletResponse response) { + ExcelUtil.exportExcel(new ArrayList<>(), "设备分组", DeviceInfoImportVo.class, response); + } + @ApiOperation("设备物模型日志") @SaCheckPermission("iot:deviceLog:query") @PostMapping("/deviceLogs/list") diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoImportVo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoImportVo.java new file mode 100644 index 00000000..2d01e56b --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/deviceinfo/DeviceInfoImportVo.java @@ -0,0 +1,32 @@ +package cc.iotkit.manager.dto.vo.deviceinfo; + +import cc.iotkit.model.device.DeviceInfo; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serializable; + + +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = DeviceInfo.class,convertGenerate = false) +public class DeviceInfoImportVo implements Serializable { + private static final long serialVersionUID = -1L; + + @ExcelProperty(value = "设备名称") + private String deviceName; + + @ExcelProperty(value = "设备型号") + private String model; + + @ExcelProperty(value = "父级id") + private String parentId; + + @ExcelProperty(value = "产品key") + private String productKey; + + @ExcelProperty(value = "设备分组") + private String deviceGroup; +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceGroupImportListener.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceGroupImportListener.java index 1ec6be3f..aa438e1d 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceGroupImportListener.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceGroupImportListener.java @@ -72,7 +72,7 @@ public class DeviceGroupImportListener extends AnalysisEventListener第").append(analysisContext.getCurrentRowNum()).append("行,设备分组ID或名称不能为空"); return; } @@ -83,18 +83,16 @@ public class DeviceGroupImportListener extends AnalysisEventListener第").append(analysisContext.getCurrentRowNum()).append("行,导入失败:").append(e.getMessage()); } } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceInfoImportListener.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceInfoImportListener.java new file mode 100644 index 00000000..f41ead63 --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/listener/DeviceInfoImportListener.java @@ -0,0 +1,117 @@ +package cc.iotkit.manager.listener; + +import cc.iotkit.common.excel.core.ExcelListener; +import cc.iotkit.common.excel.core.ExcelResult; +import cc.iotkit.common.exception.BizException; +import cc.iotkit.common.satoken.utils.LoginHelper; +import cc.iotkit.common.utils.SpringUtils; +import cc.iotkit.common.utils.StringUtils; +import cc.iotkit.manager.dto.bo.device.DeviceInfoBo; +import cc.iotkit.manager.dto.bo.devicegroup.DeviceAddGroupBo; +import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoImportVo; +import cc.iotkit.manager.service.IDeviceManagerService; +import cc.iotkit.model.device.DeviceInfo; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class DeviceInfoImportListener extends AnalysisEventListener implements ExcelListener { + + private Boolean isUpdateSupport; + + private int successNum = 0; + private int failureNum = 0; + + private final String userId; + + private IDeviceManagerService deviceManagerService; + + private final StringBuilder successMsg = new StringBuilder(); + private final StringBuilder failureMsg = new StringBuilder(); + + public DeviceInfoImportListener(Boolean isUpdateSupport) { + this.isUpdateSupport = isUpdateSupport; + this.userId = String.valueOf(LoginHelper.getUserId()); + this.deviceManagerService = SpringUtils.getBean(IDeviceManagerService.class); + } + + @Override + public ExcelResult getExcelResult() { + return new ExcelResult<>() { + @Override + public String getAnalysis() { + if (failureNum > 0) { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new BizException(failureMsg.toString()); + } else { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条"); + } + return successMsg.toString(); + } + + @Override + public List getList() { + return Collections.emptyList(); + } + + @Override + public List getErrorList() { + return Collections.emptyList(); + } + }; + } + + @Override + public void invoke(DeviceInfoImportVo deviceInfoImportVo, AnalysisContext analysisContext) { + if (StringUtils.isBlank(deviceInfoImportVo.getProductKey())) { + failureMsg.append("
第").append(analysisContext.getCurrentRowNum()).append("行,产品key不能为空!"); + failureNum++; + } + if (StringUtils.isBlank(deviceInfoImportVo.getDeviceName())) { + failureMsg.append("
第").append(analysisContext.getCurrentRowNum()).append("行,设备名称不能为空!"); + failureNum++; + } + DeviceInfo deviceInfo = this.deviceManagerService.getByPkDn(deviceInfoImportVo.getProductKey(), deviceInfoImportVo.getDeviceName()); + try { + // todo 处理groups + if(ObjectUtil.isNull(deviceInfo)) { + // 新增 + DeviceInfoBo deviceInfoBo = BeanUtil.toBean(deviceInfoImportVo, DeviceInfoBo.class); + this.deviceManagerService.addDevice(deviceInfoBo); + // 新增后重新获取deviceInfo, 此操作冗余,是建立在不修改源码基础上的处理方式,可优化 + deviceInfo = this.deviceManagerService.getByPkDn(deviceInfoImportVo.getProductKey(), deviceInfoImportVo.getDeviceName()); + } else if (Boolean.TRUE.equals(isUpdateSupport)) { + // 修改 + DeviceInfoBo deviceInfoBo = BeanUtil.toBean(deviceInfo, DeviceInfoBo.class); + this.deviceManagerService.saveDevice(deviceInfoBo); + } + + // 设备分组处理 + String group = deviceInfoImportVo.getDeviceGroup(); + if (StringUtils.isNotBlank(group)) { + DeviceAddGroupBo deviceAddGroupBo = new DeviceAddGroupBo(); + deviceAddGroupBo.setGroup(group); + String deviceId = deviceInfo.getDeviceId(); + ArrayList devices = new ArrayList<>(); + devices.add(deviceId); + deviceAddGroupBo.setDevices(devices); + this.deviceManagerService.addDevice2Group(deviceAddGroupBo); + } + + successNum++; + } catch (Exception e) { + failureNum++; + failureMsg.append("
第").append(analysisContext.getCurrentRowNum()).append("行,导入失败:").append(e.getMessage()); + } + } + + @Override + public void doAfterAllAnalysed(AnalysisContext analysisContext) { + + } +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceManagerService.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceManagerService.java index 100e7799..157c2488 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceManagerService.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IDeviceManagerService.java @@ -80,4 +80,6 @@ public interface IDeviceManagerService { String importGroup(MultipartFile file); DeviceGroupVo getDeviceGroup(String id); + + String importDevice(MultipartFile file); } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceManagerServiceImpl.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceManagerServiceImpl.java index 12f2c7be..786f8bca 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceManagerServiceImpl.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/DeviceManagerServiceImpl.java @@ -23,9 +23,11 @@ import cc.iotkit.manager.dto.bo.devicegroup.DeviceGroupBo; import cc.iotkit.manager.dto.vo.deviceconfig.DeviceConfigVo; import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupImportVo; import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupVo; +import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoImportVo; import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo; import cc.iotkit.manager.dto.vo.deviceinfo.ParentDeviceVo; import cc.iotkit.manager.listener.DeviceGroupImportListener; +import cc.iotkit.manager.listener.DeviceInfoImportListener; import cc.iotkit.manager.service.DataOwnerService; import cc.iotkit.manager.service.DeferredDataConsumer; import cc.iotkit.manager.service.DeviceCtrlService; @@ -47,7 +49,6 @@ import org.springframework.stereotype.Service; import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.multipart.MultipartFile; -import java.io.IOException; import java.util.List; import java.util.stream.Collectors; @@ -444,5 +445,12 @@ public class DeviceManagerServiceImpl implements IDeviceManagerService { return MapstructUtils.convert(deviceGroup, DeviceGroupVo.class); } + @SneakyThrows + @Override + public String importDevice(MultipartFile file) { + ExcelResult result = ExcelUtil.importExcel(file.getInputStream(), DeviceInfoImportVo.class, new DeviceInfoImportListener(true)); + return result.getAnalysis(); + } + }