Commit 92c2717d461cc117ce0d2c595d3705606a58c287
1 parent
dea8883f
【功能新增】IoT:设备管理,增加批量导入
Showing
13 changed files
with
239 additions
and
15 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
| @@ -29,6 +29,7 @@ public interface ErrorCodeConstants { | @@ -29,6 +29,7 @@ public interface ErrorCodeConstants { | ||
| 29 | ErrorCode DEVICE_KEY_EXISTS = new ErrorCode(1_050_003_003, "设备标识已经存在"); | 29 | ErrorCode DEVICE_KEY_EXISTS = new ErrorCode(1_050_003_003, "设备标识已经存在"); |
| 30 | ErrorCode DEVICE_GATEWAY_NOT_EXISTS = new ErrorCode(1_050_003_004, "网关设备不存在"); | 30 | ErrorCode DEVICE_GATEWAY_NOT_EXISTS = new ErrorCode(1_050_003_004, "网关设备不存在"); |
| 31 | ErrorCode DEVICE_NOT_GATEWAY = new ErrorCode(1_050_003_005, "设备不是网关设备"); | 31 | ErrorCode DEVICE_NOT_GATEWAY = new ErrorCode(1_050_003_005, "设备不是网关设备"); |
| 32 | + ErrorCode DEVICE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_050_003_006, "导入设备数据不能为空!"); | ||
| 32 | 33 | ||
| 33 | // ========== 产品分类 1-050-004-000 ========== | 34 | // ========== 产品分类 1-050-004-000 ========== |
| 34 | ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_050_004_000, "产品分类不存在"); | 35 | ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_050_004_000, "产品分类不存在"); |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceController.java
| @@ -18,8 +18,10 @@ import jakarta.validation.Valid; | @@ -18,8 +18,10 @@ import jakarta.validation.Valid; | ||
| 18 | import org.springframework.security.access.prepost.PreAuthorize; | 18 | import org.springframework.security.access.prepost.PreAuthorize; |
| 19 | import org.springframework.validation.annotation.Validated; | 19 | import org.springframework.validation.annotation.Validated; |
| 20 | import org.springframework.web.bind.annotation.*; | 20 | import org.springframework.web.bind.annotation.*; |
| 21 | +import org.springframework.web.multipart.MultipartFile; | ||
| 21 | 22 | ||
| 22 | import java.io.IOException; | 23 | import java.io.IOException; |
| 24 | +import java.util.Arrays; | ||
| 23 | import java.util.Collection; | 25 | import java.util.Collection; |
| 24 | import java.util.List; | 26 | import java.util.List; |
| 25 | 27 | ||
| @@ -133,4 +135,28 @@ public class IotDeviceController { | @@ -133,4 +135,28 @@ public class IotDeviceController { | ||
| 133 | new IotDeviceRespVO().setId(device.getId()).setDeviceName(device.getDeviceName()))); | 135 | new IotDeviceRespVO().setId(device.getId()).setDeviceName(device.getDeviceName()))); |
| 134 | } | 136 | } |
| 135 | 137 | ||
| 138 | + @PostMapping("/import") | ||
| 139 | + @Operation(summary = "导入设备") | ||
| 140 | + @PreAuthorize("@ss.hasPermission('iot:device:import')") | ||
| 141 | + public CommonResult<IotDeviceImportRespVO> importDevice( | ||
| 142 | + @RequestParam("file") MultipartFile file, | ||
| 143 | + @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) | ||
| 144 | + throws Exception { | ||
| 145 | + List<IotDeviceImportExcelVO> list = ExcelUtils.read(file, IotDeviceImportExcelVO.class); | ||
| 146 | + return success(deviceService.importDevice(list, updateSupport)); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + @GetMapping("/get-import-template") | ||
| 150 | + @Operation(summary = "获得导入设备模板") | ||
| 151 | + public void importTemplate(HttpServletResponse response) throws IOException { | ||
| 152 | + // 手动创建导出 demo | ||
| 153 | + List<IotDeviceImportExcelVO> list = Arrays.asList( | ||
| 154 | + IotDeviceImportExcelVO.builder().deviceName("温度传感器001").parentDeviceName("gateway110") | ||
| 155 | + .productKey("1de24640dfe").groupNames("灰度分组,生产分组").build(), | ||
| 156 | + IotDeviceImportExcelVO.builder().deviceName("biubiu") | ||
| 157 | + .productKey("YzvHxd4r67sT4s2B").groupNames("").build()); | ||
| 158 | + // 输出 | ||
| 159 | + ExcelUtils.write(response, "设备导入模板.xls", "数据", IotDeviceImportExcelVO.class, list); | ||
| 160 | + } | ||
| 161 | + | ||
| 136 | } | 162 | } |
| 137 | \ No newline at end of file | 163 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceImportExcelVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device; | ||
| 2 | + | ||
| 3 | +import com.alibaba.excel.annotation.ExcelProperty; | ||
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | +import jakarta.validation.constraints.NotEmpty; | ||
| 6 | +import lombok.AllArgsConstructor; | ||
| 7 | +import lombok.Builder; | ||
| 8 | +import lombok.Data; | ||
| 9 | +import lombok.NoArgsConstructor; | ||
| 10 | +import lombok.experimental.Accessors; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * 设备 Excel 导入 VO | ||
| 14 | + */ | ||
| 15 | +@Data | ||
| 16 | +@Builder | ||
| 17 | +@AllArgsConstructor | ||
| 18 | +@NoArgsConstructor | ||
| 19 | +@Accessors(chain = false) // 设置 chain = false,避免设备导入有问题 | ||
| 20 | +public class IotDeviceImportExcelVO { | ||
| 21 | + | ||
| 22 | + @ExcelProperty("设备名称") | ||
| 23 | + @NotEmpty(message = "设备名称不能为空") | ||
| 24 | + private String deviceName; | ||
| 25 | + | ||
| 26 | + @ExcelProperty("父设备名称") | ||
| 27 | + @Schema(description = "父设备名称", example = "网关001") | ||
| 28 | + private String parentDeviceName; | ||
| 29 | + | ||
| 30 | + @ExcelProperty("产品标识") | ||
| 31 | + @NotEmpty(message = "产品标识不能为空") | ||
| 32 | + private String productKey; | ||
| 33 | + | ||
| 34 | + @ExcelProperty("设备分组") | ||
| 35 | + private String groupNames; | ||
| 36 | + | ||
| 37 | +} | ||
| 0 | \ No newline at end of file | 38 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceImportRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Builder; | ||
| 5 | +import lombok.Data; | ||
| 6 | + | ||
| 7 | +import java.util.List; | ||
| 8 | +import java.util.Map; | ||
| 9 | + | ||
| 10 | +@Schema(description = "管理后台 - IoT 设备导入 Response VO") | ||
| 11 | +@Data | ||
| 12 | +@Builder | ||
| 13 | +public class IotDeviceImportRespVO { | ||
| 14 | + | ||
| 15 | + @Schema(description = "创建成功的设备名称数组", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 16 | + private List<String> createDeviceNames; | ||
| 17 | + | ||
| 18 | + @Schema(description = "更新成功的设备名称数组", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 19 | + private List<String> updateDeviceNames; | ||
| 20 | + | ||
| 21 | + @Schema(description = "导入失败的设备集合,key为设备名称,value为失败原因", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 22 | + private Map<String, String> failureDeviceNames; | ||
| 23 | +} | ||
| 0 | \ No newline at end of file | 24 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceGroupMapper.java
| @@ -28,4 +28,8 @@ public interface IotDeviceGroupMapper extends BaseMapperX<IotDeviceGroupDO> { | @@ -28,4 +28,8 @@ public interface IotDeviceGroupMapper extends BaseMapperX<IotDeviceGroupDO> { | ||
| 28 | return selectList(IotDeviceGroupDO::getStatus, status); | 28 | return selectList(IotDeviceGroupDO::getStatus, status); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | + default IotDeviceGroupDO selectByName(String name) { | ||
| 32 | + return selectOne(IotDeviceGroupDO::getName, name); | ||
| 33 | + } | ||
| 34 | + | ||
| 31 | } | 35 | } |
| 32 | \ No newline at end of file | 36 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/device/IotDeviceMapper.java
| @@ -29,6 +29,10 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> { | @@ -29,6 +29,10 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> { | ||
| 29 | .orderByDesc(IotDeviceDO::getId)); | 29 | .orderByDesc(IotDeviceDO::getId)); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | + default IotDeviceDO selectByDeviceName(String deviceName) { | ||
| 33 | + return selectOne(IotDeviceDO::getDeviceName, deviceName); | ||
| 34 | + } | ||
| 35 | + | ||
| 32 | default IotDeviceDO selectByProductKeyAndDeviceName(String productKey, String deviceName) { | 36 | default IotDeviceDO selectByProductKeyAndDeviceName(String productKey, String deviceName) { |
| 33 | return selectOne(IotDeviceDO::getProductKey, productKey, | 37 | return selectOne(IotDeviceDO::getProductKey, productKey, |
| 34 | IotDeviceDO::getDeviceName, deviceName); | 38 | IotDeviceDO::getDeviceName, deviceName); |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/product/IotProductMapper.java
| @@ -23,7 +23,7 @@ public interface IotProductMapper extends BaseMapperX<IotProductDO> { | @@ -23,7 +23,7 @@ public interface IotProductMapper extends BaseMapperX<IotProductDO> { | ||
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | default IotProductDO selectByProductKey(String productKey) { | 25 | default IotProductDO selectByProductKey(String productKey) { |
| 26 | - return selectOne(new LambdaQueryWrapperX<IotProductDO>().eq(IotProductDO::getProductKey, productKey)); | 26 | + return selectOne(IotProductDO::getProductKey, productKey); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | } | 29 | } |
| 30 | \ No newline at end of file | 30 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceGroupService.java
| @@ -70,6 +70,14 @@ public interface IotDeviceGroupService { | @@ -70,6 +70,14 @@ public interface IotDeviceGroupService { | ||
| 70 | IotDeviceGroupDO getDeviceGroup(Long id); | 70 | IotDeviceGroupDO getDeviceGroup(Long id); |
| 71 | 71 | ||
| 72 | /** | 72 | /** |
| 73 | + * 获得设备分组 | ||
| 74 | + * | ||
| 75 | + * @param name 名称 | ||
| 76 | + * @return 设备分组 | ||
| 77 | + */ | ||
| 78 | + IotDeviceGroupDO getDeviceGroupByName(String name); | ||
| 79 | + | ||
| 80 | + /** | ||
| 73 | * 获得设备分组分页 | 81 | * 获得设备分组分页 |
| 74 | * | 82 | * |
| 75 | * @param pageReqVO 分页查询 | 83 | * @param pageReqVO 分页查询 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceGroupServiceImpl.java
| @@ -77,6 +77,11 @@ public class IotDeviceGroupServiceImpl implements IotDeviceGroupService { | @@ -77,6 +77,11 @@ public class IotDeviceGroupServiceImpl implements IotDeviceGroupService { | ||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | @Override | 79 | @Override |
| 80 | + public IotDeviceGroupDO getDeviceGroupByName(String name) { | ||
| 81 | + return deviceGroupMapper.selectByName(name); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + @Override | ||
| 80 | public PageResult<IotDeviceGroupDO> getDeviceGroupPage(IotDeviceGroupPageReqVO pageReqVO) { | 85 | public PageResult<IotDeviceGroupDO> getDeviceGroupPage(IotDeviceGroupPageReqVO pageReqVO) { |
| 81 | return deviceGroupMapper.selectPage(pageReqVO); | 86 | return deviceGroupMapper.selectPage(pageReqVO); |
| 82 | } | 87 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
| @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSa | @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSa | ||
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO; | 6 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO; |
| 7 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceUpdateGroupReqVO; | 7 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceUpdateGroupReqVO; |
| 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 9 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceImportRespVO; | ||
| 10 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceImportExcelVO; | ||
| 9 | import jakarta.validation.Valid; | 11 | import jakarta.validation.Valid; |
| 10 | 12 | ||
| 11 | import javax.annotation.Nullable; | 13 | import javax.annotation.Nullable; |
| @@ -71,7 +73,7 @@ public interface IotDeviceService { | @@ -71,7 +73,7 @@ public interface IotDeviceService { | ||
| 71 | IotDeviceDO getDevice(Long id); | 73 | IotDeviceDO getDevice(Long id); |
| 72 | 74 | ||
| 73 | /** | 75 | /** |
| 74 | - * 获得设备分页 | 76 | + * ��得设备分页 |
| 75 | * | 77 | * |
| 76 | * @param pageReqVO 分页查询 | 78 | * @param pageReqVO 分页查询 |
| 77 | * @return IoT 设备分页 | 79 | * @return IoT 设备分页 |
| @@ -111,4 +113,13 @@ public interface IotDeviceService { | @@ -111,4 +113,13 @@ public interface IotDeviceService { | ||
| 111 | */ | 113 | */ |
| 112 | IotDeviceDO getDeviceByProductKeyAndDeviceName(String productKey, String deviceName); | 114 | IotDeviceDO getDeviceByProductKeyAndDeviceName(String productKey, String deviceName); |
| 113 | 115 | ||
| 116 | + /** | ||
| 117 | + * 导入设备 | ||
| 118 | + * | ||
| 119 | + * @param importDevices 导入设备列表 | ||
| 120 | + * @param updateSupport 是否支持更新 | ||
| 121 | + * @return 导入结果 | ||
| 122 | + */ | ||
| 123 | + IotDeviceImportRespVO importDevice(List<IotDeviceImportExcelVO> importDevices, boolean updateSupport); | ||
| 124 | + | ||
| 114 | } | 125 | } |
| 115 | \ No newline at end of file | 126 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
| @@ -3,20 +3,22 @@ package cn.iocoder.yudao.module.iot.service.device; | @@ -3,20 +3,22 @@ package cn.iocoder.yudao.module.iot.service.device; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.hutool.core.util.IdUtil; | 4 | import cn.hutool.core.util.IdUtil; |
| 5 | import cn.hutool.core.util.RandomUtil; | 5 | import cn.hutool.core.util.RandomUtil; |
| 6 | +import cn.hutool.core.util.StrUtil; | ||
| 7 | +import cn.iocoder.yudao.framework.common.exception.ServiceException; | ||
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 8 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 9 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 10 | +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | ||
| 8 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | 11 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; |
| 9 | -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDevicePageReqVO; | ||
| 10 | -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceSaveReqVO; | ||
| 11 | -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceStatusUpdateReqVO; | ||
| 12 | -import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.IotDeviceUpdateGroupReqVO; | 12 | +import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*; |
| 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 14 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceGroupDO; | ||
| 14 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 15 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 15 | import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper; | 16 | import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper; |
| 16 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; | 17 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStatusEnum; |
| 17 | import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; | 18 | import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; |
| 18 | import cn.iocoder.yudao.module.iot.service.product.IotProductService; | 19 | import cn.iocoder.yudao.module.iot.service.product.IotProductService; |
| 19 | import jakarta.annotation.Resource; | 20 | import jakarta.annotation.Resource; |
| 21 | +import jakarta.validation.ConstraintViolationException; | ||
| 20 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
| 21 | import org.springframework.context.annotation.Lazy; | 23 | import org.springframework.context.annotation.Lazy; |
| 22 | import org.springframework.stereotype.Service; | 24 | import org.springframework.stereotype.Service; |
| @@ -25,9 +27,7 @@ import org.springframework.validation.annotation.Validated; | @@ -25,9 +27,7 @@ import org.springframework.validation.annotation.Validated; | ||
| 25 | 27 | ||
| 26 | import javax.annotation.Nullable; | 28 | import javax.annotation.Nullable; |
| 27 | import java.time.LocalDateTime; | 29 | import java.time.LocalDateTime; |
| 28 | -import java.util.Collection; | ||
| 29 | -import java.util.List; | ||
| 30 | -import java.util.Objects; | 30 | +import java.util.*; |
| 31 | 31 | ||
| 32 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 32 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 33 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | 33 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; |
| @@ -245,6 +245,15 @@ public class IotDeviceServiceImpl implements IotDeviceService { | @@ -245,6 +245,15 @@ public class IotDeviceServiceImpl implements IotDeviceService { | ||
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | /** | 247 | /** |
| 248 | + * 生成 deviceKey | ||
| 249 | + * | ||
| 250 | + * @return 生成的 deviceKey | ||
| 251 | + */ | ||
| 252 | + private String generateDeviceKey() { | ||
| 253 | + return RandomUtil.randomString(16); | ||
| 254 | + } | ||
| 255 | + | ||
| 256 | + /** | ||
| 248 | * 生成 deviceSecret | 257 | * 生成 deviceSecret |
| 249 | * | 258 | * |
| 250 | * @return 生成的 deviceSecret | 259 | * @return 生成的 deviceSecret |
| @@ -282,4 +291,74 @@ public class IotDeviceServiceImpl implements IotDeviceService { | @@ -282,4 +291,74 @@ public class IotDeviceServiceImpl implements IotDeviceService { | ||
| 282 | return RandomUtil.randomString(32); | 291 | return RandomUtil.randomString(32); |
| 283 | } | 292 | } |
| 284 | 293 | ||
| 294 | + @Override | ||
| 295 | + @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入 | ||
| 296 | + public IotDeviceImportRespVO importDevice(List<IotDeviceImportExcelVO> importDevices, boolean updateSupport) { | ||
| 297 | + // 1. 参数校验 | ||
| 298 | + if (CollUtil.isEmpty(importDevices)) { | ||
| 299 | + throw exception(DEVICE_IMPORT_LIST_IS_EMPTY); | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + // 2. 遍历,逐个创建 or 更新 | ||
| 303 | + IotDeviceImportRespVO respVO = IotDeviceImportRespVO.builder().createDeviceNames(new ArrayList<>()) | ||
| 304 | + .updateDeviceNames(new ArrayList<>()).failureDeviceNames(new LinkedHashMap<>()).build(); | ||
| 305 | + importDevices.forEach(importDevice -> { | ||
| 306 | + try { | ||
| 307 | + // 2.1.1 校验字段是否符合要求 | ||
| 308 | + try { | ||
| 309 | + ValidationUtils.validate(importDevice); | ||
| 310 | + } catch (ConstraintViolationException ex){ | ||
| 311 | + respVO.getFailureDeviceNames().put(importDevice.getDeviceName(), ex.getMessage()); | ||
| 312 | + return; | ||
| 313 | + } | ||
| 314 | + // 2.1.2 校验产品是否存在 | ||
| 315 | + IotProductDO product = productService.validateProductExists(importDevice.getProductKey()); | ||
| 316 | + // 2.1.3 校验父设备是否存在 | ||
| 317 | + Long gatewayId = null; | ||
| 318 | + if (StrUtil.isNotEmpty(importDevice.getParentDeviceName())) { | ||
| 319 | + IotDeviceDO gatewayDevice = deviceMapper.selectByDeviceName(importDevice.getParentDeviceName()); | ||
| 320 | + if (gatewayDevice == null) { | ||
| 321 | + throw exception(DEVICE_GATEWAY_NOT_EXISTS); | ||
| 322 | + } | ||
| 323 | + if (!IotProductDeviceTypeEnum.isGateway(gatewayDevice.getDeviceType())) { | ||
| 324 | + throw exception(DEVICE_NOT_GATEWAY); | ||
| 325 | + } | ||
| 326 | + gatewayId = gatewayDevice.getId(); | ||
| 327 | + } | ||
| 328 | + // 2.1.4 校验设备分组是否存在 | ||
| 329 | + Set<Long> groupIds = new HashSet<>(); | ||
| 330 | + if (StrUtil.isNotEmpty(importDevice.getGroupNames())) { | ||
| 331 | + String[] groupNames = importDevice.getGroupNames().split(","); | ||
| 332 | + for (String groupName : groupNames) { | ||
| 333 | + IotDeviceGroupDO group = deviceGroupService.getDeviceGroupByName(groupName); | ||
| 334 | + if (group == null) { | ||
| 335 | + throw exception(DEVICE_GROUP_NOT_EXISTS); | ||
| 336 | + } | ||
| 337 | + groupIds.add(group.getId()); | ||
| 338 | + } | ||
| 339 | + } | ||
| 340 | + | ||
| 341 | + // 2.2.1 判断如果不存在,在进行插入 | ||
| 342 | + IotDeviceDO existDevice = deviceMapper.selectByDeviceName(importDevice.getDeviceName()); | ||
| 343 | + if (existDevice == null) { | ||
| 344 | + createDevice(new IotDeviceSaveReqVO() | ||
| 345 | + .setDeviceName(importDevice.getDeviceName()).setDeviceKey(generateDeviceKey()) | ||
| 346 | + .setProductId(product.getId()).setGatewayId(gatewayId).setGroupIds(groupIds)); | ||
| 347 | + respVO.getCreateDeviceNames().add(importDevice.getDeviceName()); | ||
| 348 | + return; | ||
| 349 | + } | ||
| 350 | + // 2.2.2 如果存在,判断是否允许更新 | ||
| 351 | + if (updateSupport) { | ||
| 352 | + throw exception(DEVICE_KEY_EXISTS); | ||
| 353 | + } | ||
| 354 | + updateDevice(new IotDeviceSaveReqVO().setId(existDevice.getId()) | ||
| 355 | + .setGatewayId(gatewayId).setGroupIds(groupIds)); | ||
| 356 | + respVO.getUpdateDeviceNames().add(importDevice.getDeviceName()); | ||
| 357 | + } catch (ServiceException ex) { | ||
| 358 | + respVO.getFailureDeviceNames().put(importDevice.getDeviceName(), ex.getMessage()); | ||
| 359 | + } | ||
| 360 | + }); | ||
| 361 | + return respVO; | ||
| 362 | + } | ||
| 363 | + | ||
| 285 | } | 364 | } |
| 286 | \ No newline at end of file | 365 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductService.java
| @@ -46,6 +46,22 @@ public interface IotProductService { | @@ -46,6 +46,22 @@ public interface IotProductService { | ||
| 46 | IotProductDO getProduct(Long id); | 46 | IotProductDO getProduct(Long id); |
| 47 | 47 | ||
| 48 | /** | 48 | /** |
| 49 | + * 校验产品存在 | ||
| 50 | + * | ||
| 51 | + * @param id 编号 | ||
| 52 | + * @return 产品 | ||
| 53 | + */ | ||
| 54 | + IotProductDO validateProductExists(Long id); | ||
| 55 | + | ||
| 56 | + /** | ||
| 57 | + * 校验产品存在 | ||
| 58 | + * | ||
| 59 | + * @param productKey 产品 key | ||
| 60 | + * @return 产品 | ||
| 61 | + */ | ||
| 62 | + IotProductDO validateProductExists(String productKey); | ||
| 63 | + | ||
| 64 | + /** | ||
| 49 | * 获得产品分页 | 65 | * 获得产品分页 |
| 50 | * | 66 | * |
| 51 | * @param pageReqVO 分页查询 | 67 | * @param pageReqVO 分页查询 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/product/IotProductServiceImpl.java
| @@ -71,16 +71,26 @@ public class IotProductServiceImpl implements IotProductService { | @@ -71,16 +71,26 @@ public class IotProductServiceImpl implements IotProductService { | ||
| 71 | productMapper.deleteById(id); | 71 | productMapper.deleteById(id); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | - private IotProductDO validateProductExists(Long id) { | ||
| 75 | - IotProductDO iotProductDO = productMapper.selectById(id); | ||
| 76 | - if (iotProductDO == null) { | 74 | + @Override |
| 75 | + public IotProductDO validateProductExists(Long id) { | ||
| 76 | + IotProductDO product = productMapper.selectById(id); | ||
| 77 | + if (product == null) { | ||
| 78 | + throw exception(PRODUCT_NOT_EXISTS); | ||
| 79 | + } | ||
| 80 | + return product; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + @Override | ||
| 84 | + public IotProductDO validateProductExists(String productKey) { | ||
| 85 | + IotProductDO product = productMapper.selectByProductKey(productKey); | ||
| 86 | + if (product == null) { | ||
| 77 | throw exception(PRODUCT_NOT_EXISTS); | 87 | throw exception(PRODUCT_NOT_EXISTS); |
| 78 | } | 88 | } |
| 79 | - return iotProductDO; | 89 | + return product; |
| 80 | } | 90 | } |
| 81 | 91 | ||
| 82 | - private void validateProductStatus(IotProductDO iotProductDO) { | ||
| 83 | - if (Objects.equals(iotProductDO.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) { | 92 | + private void validateProductStatus(IotProductDO product) { |
| 93 | + if (Objects.equals(product.getStatus(), IotProductStatusEnum.PUBLISHED.getStatus())) { | ||
| 84 | throw exception(PRODUCT_STATUS_NOT_DELETE); | 94 | throw exception(PRODUCT_STATUS_NOT_DELETE); |
| 85 | } | 95 | } |
| 86 | } | 96 | } |