diff --git a/detection/src/main/java/com/njcn/gather/device/controller/PqDevController.java b/detection/src/main/java/com/njcn/gather/device/controller/PqDevController.java index c9586248..b4997198 100644 --- a/detection/src/main/java/com/njcn/gather/device/controller/PqDevController.java +++ b/detection/src/main/java/com/njcn/gather/device/controller/PqDevController.java @@ -12,7 +12,6 @@ import com.njcn.common.utils.LogUtil; import com.njcn.gather.device.pojo.param.PqDevParam; import com.njcn.gather.device.pojo.vo.PqDevVO; import com.njcn.gather.device.service.IPqDevService; -import com.njcn.gather.monitor.pojo.po.PqMonitor; import com.njcn.gather.type.service.IDevTypeService; import com.njcn.web.controller.BaseController; import com.njcn.web.utils.FileUtil; @@ -137,7 +136,7 @@ public class PqDevController extends BaseController { @ApiImplicitParam(name = "file", value = "被检设备数据文件", required = true), @ApiImplicitParam(name = "patternId", value = "模式id", required = true) }) - public HttpResult importDev(@RequestParam("file") MultipartFile file, @RequestParam("patternId") String patternId, @RequestParam("planId") String planId, HttpServletResponse response) { + public HttpResult importDev(@RequestParam("file") MultipartFile file, @RequestParam("patternId") String patternId, @RequestParam("planId") String planId, @RequestParam(value = "cover", defaultValue = "0") Integer cover, HttpServletResponse response) { String methodDescribe = getMethodDescribe("importDev"); LogUtil.njcnDebug(log, "{},上传文件为:{}", methodDescribe, file.getOriginalFilename()); boolean fileType = FileUtil.judgeFileIsExcel(file.getOriginalFilename()); @@ -147,12 +146,7 @@ public class PqDevController extends BaseController { if ("null".equals(planId)) { planId = null; } - Boolean result = pqDevService.importDev(file, patternId, planId, response); - if (result) { - return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe); - } else { - return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe); - } + return pqDevService.importDev(file, patternId, planId, response, cover); } @OperateInfo(info = LogEnum.BUSINESS_COMMON) diff --git a/detection/src/main/java/com/njcn/gather/device/service/IPqDevService.java b/detection/src/main/java/com/njcn/gather/device/service/IPqDevService.java index 18747961..8da6b10a 100644 --- a/detection/src/main/java/com/njcn/gather/device/service/IPqDevService.java +++ b/detection/src/main/java/com/njcn/gather/device/service/IPqDevService.java @@ -3,6 +3,7 @@ package com.njcn.gather.device.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.njcn.common.pojo.poi.PullDown; +import com.njcn.common.pojo.response.HttpResult; import com.njcn.gather.device.pojo.enums.TimeCheckResultEnum; import com.njcn.gather.device.pojo.param.PqDevParam; import com.njcn.gather.device.pojo.po.PqDev; @@ -124,7 +125,7 @@ public interface IPqDevService extends IService { * @param devId * @param userId */ - void updateResult(String devId,String userId); + void updateResult(String devId, String userId); void updatePqDevReportState(String devId, int i); @@ -160,7 +161,7 @@ public interface IPqDevService extends IService { * @param planId 计划Id * @param response 响应 */ - boolean importDev(MultipartFile file, String patternId, String planId, HttpServletResponse response); + HttpResult importDev(MultipartFile file, String patternId, String planId, HttpServletResponse response, Integer cover); /** * 导入灿能二楼设备数据 @@ -254,7 +255,7 @@ public interface IPqDevService extends IService { * @param planId 计划Id * @param response 响应 */ - boolean importContrastDev(MultipartFile file, String patternId, String planId, HttpServletResponse response); + HttpResult importContrastDev(MultipartFile file, String patternId, String planId, HttpServletResponse response, Integer cover); /** * 导入比对式设备数据 @@ -262,7 +263,7 @@ public interface IPqDevService extends IService { * @param contrastDevExcelList * @param patternId */ - boolean importContrastDev(List contrastDevExcelList, String patternId, String planId); + HttpResult importContrastDev(List contrastDevExcelList, String patternId, String planId, Integer cover); /** * 获取比对式设备导出、导出文件模板的下拉列表 diff --git a/detection/src/main/java/com/njcn/gather/device/service/impl/PqDevServiceImpl.java b/detection/src/main/java/com/njcn/gather/device/service/impl/PqDevServiceImpl.java index e10bb116..a393a17a 100644 --- a/detection/src/main/java/com/njcn/gather/device/service/impl/PqDevServiceImpl.java +++ b/detection/src/main/java/com/njcn/gather/device/service/impl/PqDevServiceImpl.java @@ -11,6 +11,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; @@ -19,8 +20,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.njcn.common.pojo.constant.PatternRegex; import com.njcn.common.pojo.enums.common.DataStateEnum; +import com.njcn.common.pojo.enums.response.CommonResponseEnum; import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.poi.PullDown; +import com.njcn.common.pojo.response.HttpResult; import com.njcn.common.utils.EncryptionUtil; import com.njcn.db.mybatisplus.constant.DbConstant; import com.njcn.gather.device.mapper.PqDevMapper; @@ -35,7 +38,6 @@ import com.njcn.gather.monitor.pojo.po.PqMonitor; import com.njcn.gather.monitor.pojo.vo.PqMonitorExcel; import com.njcn.gather.monitor.service.IPqMonitorService; import com.njcn.gather.pojo.enums.DetectionResponseEnum; -import com.njcn.gather.report.pojo.enums.ReportResponseEnum; import com.njcn.gather.storage.service.DetectionDataDealService; import com.njcn.gather.system.cfg.pojo.enums.SceneEnum; import com.njcn.gather.system.cfg.pojo.po.SysTestConfig; @@ -50,6 +52,7 @@ import com.njcn.gather.user.user.pojo.po.SysUser; import com.njcn.gather.user.user.service.ISysUserService; import com.njcn.web.factory.PageFactory; import com.njcn.web.utils.ExcelUtil; +import com.njcn.web.utils.HttpResultUtil; import com.njcn.web.utils.PoiUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -653,25 +656,31 @@ public class PqDevServiceImpl extends ServiceImpl implements } @Override - public boolean importDev(MultipartFile file, String patternId, String planId, HttpServletResponse response) { + public HttpResult importDev(MultipartFile file, String patternId, String planId, HttpServletResponse response, Integer cover) { DictData dictData = dictDataService.getDictDataById(patternId); if (PatternEnum.CONTRAST.getValue().equals(dictData.getCode())) { - return this.importContrastDev(file, patternId, planId, response); + return this.importContrastDev(file, patternId, planId, response, cover); } else { String currrentScene = sysTestConfigService.getCurrrentScene(); SceneEnum sceneEnum = SceneEnum.getSceneEnum(currrentScene); switch (sceneEnum) { case PROVINCE_PLATFORM: - return this.importProvinceDev(file, patternId, planId, response); + boolean result = this.importProvinceDev(file, patternId, planId, response); + if (result) { + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, "导入成功"); + } case LEAVE_FACTORY_TEST: - return this.importCNDev(file, patternId, planId, response); + result = this.importCNDev(file, patternId, planId, response); + if (result) { + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, "导入成功"); + } case SELF_TEST: break; default: break; } } - return false; + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, "导入失败"); } @Override @@ -798,21 +807,15 @@ public class PqDevServiceImpl extends ServiceImpl implements * @param isExcludeSelf 是否排除自己 */ private void checkRepeat(PqDevParam param, boolean isExcludeSelf) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper - .eq("state", DataStateEnum.ENABLE.getCode()) - .eq(StrUtil.isNotBlank(param.getDevType()), "Dev_Type", param.getDevType()) - .eq(StrUtil.isNotBlank(param.getPattern()), "pattern", param.getPattern()) - .eq(StrUtil.isNotBlank(param.getCityName()), "City_Name", param.getCityName()) - .eq(StrUtil.isNotBlank(param.getGdName()), "Gd_Name", param.getGdName()) - .eq(StrUtil.isNotBlank(param.getSubName()), "Sub_Name", param.getSubName()) - .and(q -> q.eq(StrUtil.isNotBlank(param.getName()), "name", param.getName()).or() - .eq(StrUtil.isNotBlank(param.getCreateId()), "Create_Id", param.getCreateId())); //设备序列号重复 -// .eq("manufacturer", param.getManufacturer()) -// .eq("Dev_Type", param.getDevType()).or() + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(PqDev::getState, DataStateEnum.ENABLE.getCode()) + .eq(StrUtil.isNotBlank(param.getIp()), PqDev::getIp, param.getIp()) + .eq(ObjectUtil.isNotNull(param.getPort()), PqDev::getPort, param.getPort()) + .eq(StrUtil.isNotBlank(param.getPattern()), PqDev::getPattern, param.getPattern()) + .eq(StrUtil.isNotBlank(param.getCreateId()), PqDev::getCreateId, param.getCreateId()); if (isExcludeSelf) { if (param instanceof PqDevParam.UpdateParam) { - queryWrapper.ne("id", ((PqDevParam.UpdateParam) param).getId()); + queryWrapper.ne(PqDev::getId, ((PqDevParam.UpdateParam) param).getId()); } } int count = this.count(queryWrapper); @@ -1191,7 +1194,7 @@ public class PqDevServiceImpl extends ServiceImpl implements } @Override - public boolean importContrastDev(MultipartFile file, String patternId, String planId, HttpServletResponse response) { + public HttpResult importContrastDev(MultipartFile file, String patternId, String planId, HttpServletResponse response, Integer cover) { ImportParams params = new ImportParams(); params.setStartSheetIndex(0); params.setSheetNum(1); @@ -1211,20 +1214,22 @@ public class PqDevServiceImpl extends ServiceImpl implements } catch (Exception e) { throw new BusinessException(DetectionResponseEnum.IMPORT_DATA_FAIL); } - return this.importContrastDev(contrastDevExcelList, patternId, planId); + return this.importContrastDev(contrastDevExcelList, patternId, planId, cover); } @Override @Transactional - public boolean importContrastDev(List contrastDevExcelList, String patternId, String planId) { + public HttpResult importContrastDev(List contrastDevExcelList, String patternId, String planId, Integer cover) { if (CollUtil.isNotEmpty(contrastDevExcelList)) { // 根据设备名称分组 Map> listMap = contrastDevExcelList.stream() .collect(Collectors.groupingBy(ContrastDevExcel::getName, LinkedHashMap::new, Collectors.toList())); - List oldDevList = new ArrayList<>(listMap.size()); - List finalMonitorList = new ArrayList<>(); + List newDevList = new ArrayList<>(listMap.size()); + List updateDevList = new ArrayList<>(); + List finalUpdateDevList = new ArrayList<>(); for (Map.Entry> entry : listMap.entrySet()) { String name = entry.getKey(); + List devExcelList = entry.getValue(); // 监测点数据 List pqMonitorExcelList = devExcelList.stream() @@ -1234,16 +1239,16 @@ public class PqDevServiceImpl extends ServiceImpl implements .collect(Collectors.toList()); // 取第一条为设备基本信息 ContrastDevExcel devExcel = devExcelList.get(0); - PqDev pqDev = BeanUtil.copyProperties(devExcel, PqDev.class); - if (pqDev.getEncryptionFlag() == 1) { - if (StrUtil.isNotBlank(pqDev.getSeries()) && StrUtil.isNotBlank(pqDev.getDevKey())) { - pqDev.setSeries(EncryptionUtil.encodeString(1, pqDev.getSeries())); - pqDev.setDevKey(EncryptionUtil.encodeString(1, pqDev.getDevKey())); + PqDev importPqDev = BeanUtil.copyProperties(devExcel, PqDev.class); + if (importPqDev.getEncryptionFlag() == 1) { + if (StrUtil.isNotBlank(importPqDev.getSeries()) && StrUtil.isNotBlank(importPqDev.getDevKey())) { + importPqDev.setSeries(EncryptionUtil.encodeString(1, importPqDev.getSeries())); + importPqDev.setDevKey(EncryptionUtil.encodeString(1, importPqDev.getDevKey())); } else { throw new BusinessException(DetectionResponseEnum.SERIES_AND_DEVKEY_NOT_BLANK); } } - DevType devType = devTypeService.getByName(pqDev.getDevType()); + DevType devType = devTypeService.getByName(importPqDev.getDevType()); if (ObjectUtil.isNull(devType)) { throw new BusinessException(DetectionResponseEnum.DEV_TYPE_NOT_EXIST); } @@ -1264,18 +1269,16 @@ public class PqDevServiceImpl extends ServiceImpl implements throw new BusinessException(DetectionResponseEnum.MONITOR_NUM_OUT_OF_RANGE); } - pqDev.setDevType(devType.getId()); - pqDev.setImportFlag(1); - pqDev.setId(UUID.randomUUID().toString().replaceAll("-", "")); - pqDev.setCreateId(pqDev.getName()); //导入时设备序列号默认与设备名称相同 - List monitorList = new ArrayList<>(); + importPqDev.setDevType(devType.getId()); + importPqDev.setImportFlag(1); + importPqDev.setId(UUID.randomUUID().toString().replaceAll("-", "")); + + if (StrUtil.isEmpty(importPqDev.getCreateId())) { + // 与设备名称相同 + importPqDev.setCreateId(importPqDev.getName()); + } // 根据num排序 pqMonitorExcelList.sort(Comparator.comparingInt(PqMonitorExcel::getNum)); - for (PqMonitorExcel pqMonitorExcel : pqMonitorExcelList) { - PqMonitor monitor = BeanUtil.copyProperties(pqMonitorExcel, PqMonitor.class); - monitor.setDevId(pqDev.getId()); - monitorList.add(monitor); - } StringBuilder inspectChannelBuilder = new StringBuilder(); for (int i = 1; i <= devChns; i++) { inspectChannelBuilder.append(i); @@ -1283,71 +1286,121 @@ public class PqDevServiceImpl extends ServiceImpl implements inspectChannelBuilder.append(","); } } - pqDev.setInspectChannel(inspectChannelBuilder.toString()); - oldDevList.add(pqDev); - finalMonitorList.addAll(monitorList); - } - //逆向可视化 - this.reverseVisualizeProvinceDev(oldDevList, patternId); - - List newDevList = new ArrayList<>(); - oldDevList.forEach(pqDev -> { - PqDevParam param = BeanUtil.copyProperties(pqDev, PqDevParam.class); - this.checkRepeat(param, false); - long count = newDevList.stream().filter(dev -> - dev.getDevType().equals(pqDev.getDevType()) - && dev.getCityName().equals(pqDev.getCityName()) - && dev.getGdName().equals(pqDev.getGdName()) - && dev.getSubName().equals(pqDev.getSubName()) - && (dev.getName().equals(pqDev.getName()) || dev.getCreateId().equals(pqDev.getCreateId()))) - .count(); - if (count == 0) { - pqDev.setPlanId(planId); - newDevList.add(pqDev); - } - }); - QueryWrapper wrapper1 = new QueryWrapper() - .eq("pq_dev.State", DataStateEnum.ENABLE.getCode()) - .in("pq_dev.Harm_Sys_Id", newDevList.stream().map(PqDev::getHarmSysId).collect(Collectors.toList())); - List oldDevList1 = this.list(wrapper1); - if (CollUtil.isNotEmpty(oldDevList1)) { - oldDevList1.stream().forEach(oldDev -> { - PqDev newDev = newDevList.stream().filter(dev -> dev.getHarmSysId().equals(oldDev.getHarmSysId())).findFirst().orElse(null); - if (ObjectUtil.isNotNull(newDev)) { - newDevList.remove(newDev); - finalMonitorList.stream() - .filter(monitor -> monitor.getDevId().equals(newDev.getId())) - .forEach(monitor -> monitor.setDevId(oldDev.getId())); - BeanUtil.copyProperties(newDev, oldDev, "id"); + importPqDev.setInspectChannel(inspectChannelBuilder.toString()); + List monitorList = new ArrayList<>(); + // 1、先判断是否有谐波系统ID + boolean hasHarmSys = false; + if (StrUtil.isNotBlank(importPqDev.getHarmSysId())) { + // 1.1、如果有则判断是否已存在 + List hasList = this.lambdaQuery() + .eq(PqDev::getState, DataStateEnum.ENABLE.getCode()) + .eq(PqDev::getPattern, patternId) + .eq(PqDev::getHarmSysId, importPqDev.getHarmSysId()) + .isNull(PqDev::getPlanId) + .orderByDesc(PqDev::getCreateTime).list(); + // 1.2、 存在则放入强制更新list + if (CollUtil.isNotEmpty(hasList)) { + importPqDev.setId(hasList.get(0).getId()); + for (PqMonitorExcel pqMonitorExcel : pqMonitorExcelList) { + PqMonitor pqMonitor = BeanUtil.copyProperties(pqMonitorExcel, PqMonitor.class); + pqMonitor.setDevId(importPqDev.getId()); + monitorList.add(pqMonitor); + } + importPqDev.setMonitorList(monitorList); + finalUpdateDevList.add(importPqDev); + hasHarmSys = true; } - }); - this.updateBatchById(oldDevList1); - } - this.saveBatch(newDevList); - List pqDevSubList = new ArrayList<>(); - for (PqDev dev : newDevList) { - PqDevSub pqDevSub = new PqDevSub(); - pqDevSub.setDevId(dev.getId()); - pqDevSub.setCheckState(CheckStateEnum.UNCHECKED.getValue()); - pqDevSub.setCheckResult(CheckResultEnum.UNCHECKED.getValue()); - pqDevSub.setReportState(DevReportStateEnum.UNCHECKED.getValue()); - pqDevSub.setTimeCheckResult(TimeCheckResultEnum.UNKNOWN.getValue()); - pqDevSub.setFactorCheckResult(FactorCheckResultEnum.UNKNOWN.getValue()); - pqDevSubList.add(pqDevSub); - } - pqDevSubService.saveBatch(pqDevSubList); - List devIdList = oldDevList1.stream().map(PqDev::getId).collect(Collectors.toList()); - if (CollUtil.isNotEmpty(devIdList)) { - QueryWrapper wrapper = new QueryWrapper() - .in("pq_monitor.Dev_Id", devIdList); - pqMonitorService.remove(wrapper); + } + if (!hasHarmSys) { + // 2、查询 ip + 端口 + 序列号 + patternId + Plan_Id为空 是否存在 + List hasList = this.lambdaQuery() + .eq(PqDev::getState, DataStateEnum.ENABLE.getCode()) + .eq(PqDev::getIp, devExcel.getIp()) + .eq(PqDev::getPort, devExcel.getPort()) + .eq(PqDev::getPattern, patternId) + .eq(PqDev::getCreateId, devExcel.getCreateId()) + .isNull(PqDev::getPlanId) + .orderByDesc(PqDev::getCreateTime).list(); + // 2.1、存在则放入更新list + if (CollUtil.isNotEmpty(hasList)) { + importPqDev.setId(hasList.get(0).getId()); + for (PqMonitorExcel pqMonitorExcel : pqMonitorExcelList) { + PqMonitor monitor = BeanUtil.copyProperties(pqMonitorExcel, PqMonitor.class); + monitor.setDevId(importPqDev.getId()); + monitorList.add(monitor); + } + importPqDev.setMonitorList(monitorList); + updateDevList.add(importPqDev); + } else { + //2.2、不存在则放入新增list + for (PqMonitorExcel pqMonitorExcel : pqMonitorExcelList) { + PqMonitor monitor = BeanUtil.copyProperties(pqMonitorExcel, PqMonitor.class); + monitor.setDevId(importPqDev.getId()); + monitorList.add(monitor); + } + importPqDev.setMonitorList(monitorList); + newDevList.add(importPqDev); + } + } } - pqMonitorService.reverseVisualizeMonitor(finalMonitorList); - pqMonitorService.saveBatch(finalMonitorList); - return true; + // 3、是否有重复的设备 + if (CollUtil.isNotEmpty(updateDevList)) { + // 3.1、有则让用户确认是否覆盖 + if (cover == 0) { + List existDevList = new ArrayList<>(); + updateDevList.forEach(pqDev -> { + existDevList.add(pqDev.getName() + "(" + pqDev.getIp() + ":" + pqDev.getPort() + ")"); + }); + return HttpResultUtil.assembleResult(DetectionResponseEnum.DEV_IP_PORT_EXIST.getCode(), existDevList, "请确认是否覆盖"); + + } else { + // 3.2、确认覆盖则放入强制更新list + finalUpdateDevList.addAll(updateDevList); + } + } + + + // 4、新增list + if (CollUtil.isNotEmpty(newDevList)) { + //逆向可视化 + this.reverseVisualizeProvinceDev(newDevList, patternId); + this.saveBatch(newDevList); + List pqDevSubList = new ArrayList<>(); + List newMonitorList = new ArrayList<>(); + for (PqDev dev : newDevList) { + PqDevSub pqDevSub = new PqDevSub(); + pqDevSub.setDevId(dev.getId()); + pqDevSub.setCheckState(CheckStateEnum.UNCHECKED.getValue()); + pqDevSub.setCheckResult(CheckResultEnum.UNCHECKED.getValue()); + pqDevSub.setReportState(DevReportStateEnum.UNCHECKED.getValue()); + pqDevSub.setTimeCheckResult(TimeCheckResultEnum.UNKNOWN.getValue()); + pqDevSub.setFactorCheckResult(FactorCheckResultEnum.UNKNOWN.getValue()); + pqDevSubList.add(pqDevSub); + newMonitorList.addAll(dev.getMonitorList()); + } + pqMonitorService.reverseVisualizeMonitor(newMonitorList); + pqMonitorService.saveBatch(newMonitorList); + pqDevSubService.saveBatch(pqDevSubList); + } + // 5、更新list + if (CollUtil.isNotEmpty(finalUpdateDevList)) { + //逆向可视化 + this.reverseVisualizeProvinceDev(finalUpdateDevList, patternId); + this.updateBatchById(finalUpdateDevList); + List updateMonitorList = new ArrayList<>(); + for (PqDev dev : finalUpdateDevList) { + updateMonitorList.addAll(dev.getMonitorList()); + } + pqMonitorService.reverseVisualizeMonitor(updateMonitorList); + for (PqMonitor monitor : updateMonitorList) { + pqMonitorService.update(monitor, new LambdaUpdateWrapper().eq(PqMonitor::getDevId, monitor.getDevId())); + } + } + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, "导入成功"); } - return false; + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, "导入失败"); + } @Override diff --git a/detection/src/main/java/com/njcn/gather/pojo/enums/DetectionResponseEnum.java b/detection/src/main/java/com/njcn/gather/pojo/enums/DetectionResponseEnum.java index 7779b612..8ef34854 100644 --- a/detection/src/main/java/com/njcn/gather/pojo/enums/DetectionResponseEnum.java +++ b/detection/src/main/java/com/njcn/gather/pojo/enums/DetectionResponseEnum.java @@ -73,8 +73,9 @@ public enum DetectionResponseEnum { MONITOR_NUM_REPEAT("A02094", "该被检设备下存在相同线路号的监测点"), PLAN_HAS_CHILDREN("A02095", "该计划下存在子计划,请先删除子计划"), PLAN_REPEATED_IN_SAME_LEVEL("A02096", "该父计划下存在同名的子计划"), - PLEASE_UNASSIGN_STANDARD_DEV("A02097","存在已分配给子计划的标准设备,请先解除分配" ), - PLEASE_UNASSIGN_DEVICE("A02098", "存在已分配给计划的被检设备,请先解除分配"); + PLEASE_UNASSIGN_STANDARD_DEV("A02097", "存在已分配给子计划的标准设备,请先解除分配"), + PLEASE_UNASSIGN_DEVICE("A02098", "存在已分配给计划的被检设备,请先解除分配"), + DEV_IP_PORT_EXIST("A02099", "存在重复被检设备"); private final String code;