feat:完成能耗报表相关接口,修复树形结构相关问题

plp
HuangHuiKang 3 weeks ago
parent be869fa985
commit c5be8a8dd8

@ -230,8 +230,11 @@ public class DeviceController {
return success(deviceService.getDeviceAttribute(id)); return success(deviceService.getDeviceAttribute(id));
} }
@GetMapping("/devicePointList")
@PreAuthorize("@ss.hasPermission('iot:device:query')")
public CommonResult<List<DevicePointRespVO>> devicePointList() {
return success( deviceService.devicePointList());
}
} }

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.vo;
import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
@Schema(description = "管理后台 - 设备参数集合列表 Resp VO")
@Data
@ToString(callSuper = true)
public class DevicePointRespVO {
@Schema(description = "设备Id")
private Long deviceId;
@Schema(description = "设备名称")
private String deviceName;
@Schema(description = "子集参数列表")
private List<DeviceContactModelDO> contactModelDOList;
}

@ -125,4 +125,5 @@ public interface DeviceService {
Map<Long, Map<String, Object>> createDeviceDataMap(Long deviceId); Map<Long, Map<String, Object>> createDeviceDataMap(Long deviceId);
List<DevicePointRespVO> devicePointList();
} }

@ -27,10 +27,12 @@ import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceAttributeMapper;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@ -55,6 +57,7 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
*/ */
@Service @Service
@Validated @Validated
@Slf4j
public class DeviceServiceImpl implements DeviceService { public class DeviceServiceImpl implements DeviceService {
@Resource @Resource
@ -307,19 +310,45 @@ public class DeviceServiceImpl implements DeviceService {
resultMap.put(recordId, recordInfoMap); resultMap.put(recordId, recordInfoMap);
} else { } else {
// 如果记录没有ID可以记录日志或使用其他策略如生成临时ID这里简单跳过 // 如果记录没有ID可以记录日志或使用其他策略如生成临时ID这里简单跳过
System.err.println("警告发现一条数据记录缺少ID已跳过。"); log.error("发现一条数据记录缺少ID已跳过");
} }
} }
} }
} catch (Exception e) { } catch (Exception e) {
// 异常处理 // 异常处理
System.err.println("处理设备" + deviceId + "的数据时发生异常: " + e.getMessage()); log.error("处理设备" + deviceId + "的数据时发生异常: ", e.getMessage());
// 可以选择在异常时返回空Map或包含错误信息的特殊Map根据业务需求决定 return new HashMap<>();
} }
return resultMap; return resultMap;
} }
@Override
public List<DevicePointRespVO> devicePointList() {
List<DevicePointRespVO> devicePointRespVOList = new ArrayList<>();
List<DeviceDO> deviceDOS = deviceMapper.selectList(Wrappers.<DeviceDO>lambdaQuery().orderByDesc(DeviceDO::getCreateTime));
if (deviceDOS.isEmpty()){
return devicePointRespVOList;
}
for (DeviceDO deviceDO : deviceDOS) {
DevicePointRespVO devicePointRespVO = new DevicePointRespVO();
devicePointRespVO.setDeviceId(deviceDO.getId());
devicePointRespVO.setDeviceName(deviceDO.getDeviceName());
List<DeviceContactModelDO> deviceContactModelDOS = deviceContactModelMapper.selectList(
Wrappers.<DeviceContactModelDO>lambdaQuery()
.eq(DeviceContactModelDO::getDeviceId, deviceDO.getId()));
if (!deviceContactModelDOS.isEmpty()){
devicePointRespVO.setContactModelDOList(deviceContactModelDOS);
}
devicePointRespVOList.add(devicePointRespVO);
}
return devicePointRespVOList;
}
@Override @Override
public Long createDeviceAttribute(DeviceAttributeDO deviceAttribute) { public Long createDeviceAttribute(DeviceAttributeDO deviceAttribute) {

@ -5,6 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.taosdata.jdbc.utils.BlobUtil; import com.taosdata.jdbc.utils.BlobUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.EmptyResultDataAccessException;
@ -22,6 +23,7 @@ import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
@Service @Service
@Slf4j
public class TDengineService { public class TDengineService {
@Resource @Resource
private JdbcTemplate jdbcTemplate; private JdbcTemplate jdbcTemplate;
@ -374,11 +376,9 @@ public class TDengineService {
return result; return result;
} }
}); });
} catch (EmptyResultDataAccessException e) {
return Collections.singletonList(createEmptyResult(id));
} catch (Exception e) { } catch (Exception e) {
System.err.println("查询设备" + id + "的最新数据时发生异常: " + e.getMessage()); log.error("查询设备" + id + "的最新数据时发生异常", e);
e.printStackTrace(); // e.printStackTrace();
return Collections.singletonList(createEmptyResult(id)); return Collections.singletonList(createEmptyResult(id));
} }
} }

@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.iot.dal.mysql.deviceattributetype.DeviceAttribute
import cn.iocoder.yudao.module.iot.service.device.TDengineService; import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -36,6 +37,7 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
*/ */
@Service @Service
@Validated @Validated
@Slf4j
public class DeviceModelAttributeServiceImpl implements DeviceModelAttributeService { public class DeviceModelAttributeServiceImpl implements DeviceModelAttributeService {
@Resource @Resource
@ -170,7 +172,10 @@ public class DeviceModelAttributeServiceImpl implements DeviceModelAttributeServ
} }
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("处理设备数据时发生异常", e); log.error(e.getMessage());
// e.printStackTrace();
// throw new RuntimeException("处理设备数据时发生异常", e);
return new ArrayList<>();
} }

@ -12,6 +12,7 @@ public interface ErrorCodeConstants {
ErrorCode BOM_NOT_EXISTS = new ErrorCode(5_001, "产品BOM不存在"); ErrorCode BOM_NOT_EXISTS = new ErrorCode(5_001, "产品BOM不存在");
ErrorCode BOM_EXISTS = new ErrorCode(5_002, "产品BOM已存在"); ErrorCode BOM_EXISTS = new ErrorCode(5_002, "产品BOM已存在");
ErrorCode ORGANIZATION_NOT_EXISTS = new ErrorCode(5_0011, "产线工位不存在"); ErrorCode ORGANIZATION_NOT_EXISTS = new ErrorCode(5_0011, "产线工位不存在");
ErrorCode ORGANIZATION_ID_NOT_EXISTS = new ErrorCode(5_0011, "产线工位不存在");
ErrorCode ORGANIZATION_EXITS_CHILDREN = new ErrorCode(5_0012, "存在存在子产线工位,无法删除"); ErrorCode ORGANIZATION_EXITS_CHILDREN = new ErrorCode(5_0012, "存在存在子产线工位,无法删除");
ErrorCode ORGANIZATION_PARENT_NOT_EXITS = new ErrorCode(5_0013,"父级产线工位不存在"); ErrorCode ORGANIZATION_PARENT_NOT_EXITS = new ErrorCode(5_0013,"父级产线工位不存在");
ErrorCode ORGANIZATION_PARENT_ERROR = new ErrorCode(5_0014, "不能设置自己为父产线工位"); ErrorCode ORGANIZATION_PARENT_ERROR = new ErrorCode(5_0014, "不能设置自己为父产线工位");

@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceConsumptionReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDevicePageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDevicePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceRespVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceSaveReqVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceSaveReqVO;
@ -24,6 +25,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -97,12 +99,11 @@ public class EnergyDeviceController {
BeanUtils.toBean(list, EnergyDeviceRespVO.class)); BeanUtils.toBean(list, EnergyDeviceRespVO.class));
} }
@PostMapping("/queryDataRecords") @GetMapping("/queryDataRecords")
@Operation(summary = "查询数据记录") @Operation(summary = "查询数据记录")
@PreAuthorize("@ss.hasPermission('mes:energy-device:create')") @PreAuthorize("@ss.hasPermission('mes:energy-device:create')")
public CommonResult<List<EnergyDeviceRespVO>> queryDataRecords(@RequestParam(name = "startTime", required = false ) String startTime, public CommonResult<List<EnergyDeviceRespVO>> queryDataRecords(@Valid EnergyDeviceConsumptionReqVO deviceConsumptionReqVO) {
@RequestParam(name = "endTime", required = false ) String endTime) { return success(energyDeviceService.queryDataRecords(deviceConsumptionReqVO));
return success(energyDeviceService.queryDataRecords(startTime,endTime));
} }

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 能耗管理/能耗报表 Request VO")
@Data
public class EnergyDeviceConsumptionReqVO {
@Schema(description = "表名称")
private String name;
@Schema(description = "所属区域")
private Long orgId;
@Schema(description = "开始时间")
private String startTime;
@Schema(description = "结束时间")
private String endTime;
}

@ -100,7 +100,7 @@ public class EnergyDeviceRespVO {
@ExcelProperty("子列表点位参数值") @ExcelProperty("子列表点位参数值")
private Map<String,String> sublistPointList; private Map<String,String> sublistPointList;
@Schema(description = "列表") @Schema(description = "点位差值列表")
Map<Long,List<OperationRulesVO>> operationRulesVOMap; private Map<String, String> operationRulesVOMap;
} }

@ -4,10 +4,7 @@ import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.LineAnalysisTreeDTO; import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.*;
import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationListReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO; import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO;
import cn.iocoder.yudao.module.mes.service.organization.OrganizationService; import cn.iocoder.yudao.module.mes.service.organization.OrganizationService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -98,10 +95,22 @@ public class OrganizationController {
@GetMapping("/deviceParameterAnalysis") @GetMapping("/deviceParameterAnalysis")
@Operation(summary = "设备运行参数分析") @Operation(summary = "设备运行参数分析")
@PreAuthorize("@ss.hasPermission('iot:device:query')") @PreAuthorize("@ss.hasPermission('iot:device:query')")
public CommonResult<List<LineAnalysisTreeDTO.LineNode>> deviceParameterAnalysis(@RequestParam(value = "keyword", required = false) String keyword) { public CommonResult<List<LineAnalysisTreeDTO.LineNode>> deviceParameterAnalysis(@RequestParam(value = "keyword", required = false) String keyword,
List<LineAnalysisTreeDTO.LineNode> list = organizationService.deviceParameterAnalysis(keyword); @RequestParam(value = "showDevices") Integer showDevices
) {
List<LineAnalysisTreeDTO.LineNode> list = organizationService.deviceParameterAnalysis(keyword,showDevices);
return success(list); return success(list);
} }
//
// @GetMapping("/getParametersById")
// @Operation(summary = "根据产线Id获取点位参数")
// @Parameter(name = "id", description = "编号", required = true, example = "1024")
// //@PreAuthorize("@ss.hasPermission('mes:organization:query')")
// public CommonResult<List<DeviceParametersDTO>> getParametersById(@RequestParam("id") Long id) {
// List<DeviceParametersDTO> organization = organizationService.getDeviceParametersByOrganizationId(id);
// return success(organization);
// }
} }

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.mes.controller.admin.organization.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DeviceParametersDTO {
/**
* ID
*/
private Long deviceId;
/**
*
*/
private String deviceName;
/**
*
*/
private String deviceCode;
/**
*
*/
private String deviceType;
/**
*
*/
private String deviceStatus;
/**
*
*/
private List<ParameterInfoDTO> parameters;
}

@ -27,8 +27,12 @@ public class LineAnalysisTreeDTO {
public static class LineNode { public static class LineNode {
private Long id; // 产线ID private Long id; // 产线ID
private String name; // 产线名称 private String name; // 产线名称
private String orgClass; // 组织等级
private Long parentId; private Long parentId;
private List<EquipmentNode> equipments = new ArrayList<>(); // private List<EquipmentNode> equipments = new ArrayList<>();
private List<EquipmentNode> equipments;
private List<LineNode> children;
} }
// 设备节点 // 设备节点
@ -39,7 +43,7 @@ public class LineAnalysisTreeDTO {
public static class EquipmentNode { public static class EquipmentNode {
private Long id; // 设备ID private Long id; // 设备ID
private String name; // 设备名称 private String name; // 设备名称
private List<ParameterNode> parameters = new ArrayList<>(); private List<ParameterNode> parameters;
} }
// 参数节点 // 参数节点

@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.mes.controller.admin.organization.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ParameterInfoDTO {
/**
* ID
*/
private Long parameterId;
/**
*
*/
private String parameterName;
/**
*
*/
private String parameterCode;
/**
*
*/
private String parameterType;
/**
*
*/
private String dataType;
/**
*
*/
private String unit;
/**
*
*/
private Double ratio;
}

@ -27,9 +27,11 @@ public class TaskManagementSaveReqVO {
private Integer taskType; private Integer taskType;
@Schema(description = "设备列表") @Schema(description = "设备列表")
@NotEmpty(message = "名称不能为空")
private String deviceList; private String deviceList;
@Schema(description = "项目表单") @Schema(description = "项目表单")
@NotNull
private Long projectForm; private Long projectForm;
@Schema(description = "起止开始日期") @Schema(description = "起止开始日期")

@ -16,5 +16,5 @@ public class TicketManagementBatchUpdateReqVO {
@Schema(description = "作业状态", example = "2") @Schema(description = "作业状态", example = "2")
@NotNull(message = "作业状态不能为空") @NotNull(message = "作业状态不能为空")
private Integer jobStatus ; // 默认值为2 private Integer jobStatus ;
} }

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.service.energydevice;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceConsumptionReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDevicePageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDevicePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceRespVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceSaveReqVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceSaveReqVO;
@ -109,7 +110,7 @@ public interface EnergyDeviceService {
return convertMap(getList(ids), EnergyDeviceDO::getId); return convertMap(getList(ids), EnergyDeviceDO::getId);
} }
List<EnergyDeviceRespVO> queryDataRecords(String startTime,String endTime); List<EnergyDeviceRespVO> queryDataRecords(EnergyDeviceConsumptionReqVO deviceConsumptionReqVO);
} }

@ -4,19 +4,21 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO; import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper;
import cn.iocoder.yudao.module.iot.service.device.TDengineService; import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDevicePageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.*;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceSaveReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.OperationRulesVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceCheckRecordDO; import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceCheckRecordDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceDO; import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceDO;
import cn.iocoder.yudao.module.mes.dal.mysql.energydevice.EnergyDeviceCheckRecordMapper; import cn.iocoder.yudao.module.mes.dal.mysql.energydevice.EnergyDeviceCheckRecordMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.energydevice.EnergyDeviceMapper; import cn.iocoder.yudao.module.mes.dal.mysql.energydevice.EnergyDeviceMapper;
import cn.iocoder.yudao.module.mes.dal.redis.no.MesNoRedisDAO; import cn.iocoder.yudao.module.mes.dal.redis.no.MesNoRedisDAO;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -24,6 +26,8 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
@ -39,6 +43,7 @@ import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
*/ */
@Service @Service
@Validated @Validated
@Slf4j
public class EnergyDeviceServiceImpl implements EnergyDeviceService { public class EnergyDeviceServiceImpl implements EnergyDeviceService {
@Resource @Resource
@ -49,6 +54,8 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService {
private MesNoRedisDAO noRedisDAO; private MesNoRedisDAO noRedisDAO;
@Resource @Resource
private TDengineService tDengineService; private TDengineService tDengineService;
@Resource
private DeviceContactModelMapper deviceContactModelMapper;
@Override @Override
public Long createEnergyDevice(EnergyDeviceSaveReqVO createReqVO) { public Long createEnergyDevice(EnergyDeviceSaveReqVO createReqVO) {
@ -242,50 +249,647 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService {
} }
@Override @Override
public List<EnergyDeviceRespVO> queryDataRecords(String startTime,String endTime) { public List<EnergyDeviceRespVO> queryDataRecords(EnergyDeviceConsumptionReqVO deviceConsumptionReqVO) {
List<EnergyDeviceRespVO> energyDeviceRespVOArrayList = new ArrayList<>(); List<EnergyDeviceRespVO> result = new ArrayList<>();
List<EnergyDeviceDO> energyDeviceDO = energyDeviceMapper.selectList(); List<EnergyDeviceDO> energyDeviceDO = energyDeviceMapper.selectList(
if (energyDeviceDO.isEmpty()){ Wrappers.<EnergyDeviceDO>lambdaQuery()
.like(StringUtils.isNotBlank(deviceConsumptionReqVO.getName()), EnergyDeviceDO::getName, deviceConsumptionReqVO.getName())
.eq(deviceConsumptionReqVO.getOrgId() != null, EnergyDeviceDO::getOrgId, deviceConsumptionReqVO.getOrgId()));
if (energyDeviceDO == null || energyDeviceDO.isEmpty()) {
throw exception(ENERGY_LIST_NOT_EXISTS); throw exception(ENERGY_LIST_NOT_EXISTS);
} }
for (EnergyDeviceDO deviceDO : energyDeviceDO) { for (EnergyDeviceDO deviceDO : energyDeviceDO) {
EnergyDeviceRespVO energyDeviceRespVO = new EnergyDeviceRespVO(); if (StringUtils.isBlank(deviceDO.getRules())) {
if (StringUtils.isBlank(deviceDO.getRules())){
continue; continue;
} }
// 解析规则
//查询每个点位的Id
List<OperationRulesVO> operationRulesVOList = JSON.parseArray(deviceDO.getRules(), OperationRulesVO.class); List<OperationRulesVO> operationRulesVOList = JSON.parseArray(deviceDO.getRules(), OperationRulesVO.class);
Map<Long,List<OperationRulesVO>> operationRulesVOMap =new HashMap<>(); if (operationRulesVOList == null || operationRulesVOList.isEmpty()) {
continue;
for (OperationRulesVO operationRulesVO : operationRulesVOList) { }
List<OperationRulesVO> operationRulesVOS = new ArrayList<>();
//获取Td列表 try {
List<Map<String, Object>> maps = tDengineService.getstDeviceDataOrderByTimeDesc(operationRulesVO.getDeviceId(), startTime, endTime); // 计算设备结果
for (Map<String, Object> map : maps) { EnergyDeviceRespVO deviceRespVO = buildEnergyDeviceRespVO(deviceDO, operationRulesVOList, deviceConsumptionReqVO.getStartTime(), deviceConsumptionReqVO.getEndTime());
String queryData = map.get("queryData").toString(); if (deviceRespVO != null) {
result.add(deviceRespVO);
//获取json数据列表 }
List<DeviceContactModelDO> deviceContactModelDOS = JSON.parseArray(queryData, DeviceContactModelDO.class); } catch (Exception e) {
for (DeviceContactModelDO deviceContactModelDO : deviceContactModelDOS) { log.error("计算设备结果失败, deviceId: {}", deviceDO.getId(), e);
if (operationRulesVO.equals(deviceContactModelDO.getId())){ }
OperationRulesVO operationRulesVO1 = new OperationRulesVO(); }
operationRulesVO1.setPointId(deviceContactModelDO.getId());
operationRulesVO1.setPointValue((String) deviceContactModelDO.getAddressValue()); return result;
operationRulesVOS.add(operationRulesVO1); }
/**
* EnergyDeviceRespVO
*/
private EnergyDeviceRespVO buildEnergyDeviceRespVO(EnergyDeviceDO deviceDO,
List<OperationRulesVO> rules,
String startTime, String endTime) {
if (deviceDO == null || rules == null || rules.isEmpty()) {
return null;
}
EnergyDeviceRespVO respVO = new EnergyDeviceRespVO();
// 设置设备基本信息
respVO.setId(deviceDO.getId());
respVO.setName(deviceDO.getName());
respVO.setCode(deviceDO.getCode());
respVO.setInfo(deviceDO.getInfo());
respVO.setCheckCron(deviceDO.getCheckCron());
respVO.setLastCheckTime(deviceDO.getLastCheckTime());
respVO.setLastCheckValue(deviceDO.getLastCheckValue());
respVO.setUnitName(deviceDO.getUnitName());
respVO.setIsEnable(deviceDO.getIsEnable());
respVO.setCreateTime(deviceDO.getCreateTime());
respVO.setUpdateTime(deviceDO.getUpdateTime());
respVO.setDeviceTypeId(deviceDO.getDeviceTypeId());
respVO.setDeviceTypeName(deviceDO.getDeviceTypeName());
respVO.setOrgId(deviceDO.getOrgId());
respVO.setOrgName(deviceDO.getOrgName());
respVO.setRules(deviceDO.getRules());
respVO.setOperationRulesVOList(rules);
// 计算数据结果
Map<String, Object> calculationResult = calculateDeviceData(deviceDO, rules, startTime, endTime);
if (calculationResult == null) {
return respVO;
}
// 设置能耗总用量差值
Double totalDifference = (Double) calculationResult.get("totalDifference");
if (totalDifference != null) {
respVO.setEnergyConsumption(formatDouble(totalDifference));
} else {
respVO.setEnergyConsumption("0.0");
}
// 设置每个点位参数的差值key为点位参数名称
Map<String, String> operationRulesVOMap = buildPointDifferenceMap(calculationResult, deviceDO, rules);
respVO.setOperationRulesVOMap(operationRulesVOMap);
return respVO;
}
/**
*
*/
private Map<String, Object> getPointData(Map<String, Object> dataMap, Long pointId) {
if (dataMap == null || pointId == null) {
return null;
}
try {
Object queryDataObj = dataMap.get("queryData");
if (queryDataObj == null) {
return null;
}
String queryData = queryDataObj.toString();
if (StringUtils.isBlank(queryData)) {
return null;
}
// 处理编码问题
queryData = fixEncoding(queryData);
// 解析JSON数组
JSONArray jsonArray = JSON.parseArray(queryData);
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObj = jsonArray.getJSONObject(i);
// 安全获取id
Long dataPointId = null;
try {
dataPointId = jsonObj.getLong("id");
} catch (Exception e) {
continue;
}
if (dataPointId == null) {
continue;
}
// 匹配点位ID
if (pointId.equals(dataPointId)) {
Map<String, Object> pointData = new HashMap<>();
// 提取所有需要的字段
pointData.put("id", dataPointId);
// 安全获取字段
pointData.put("address", getJsonString(jsonObj, "address"));
// 处理值
Object value = jsonObj.get("addressValue");
Double doubleValue = null;
if (value != null) {
try {
if (value instanceof Number) {
doubleValue = ((Number) value).doubleValue();
} else {
doubleValue = Double.parseDouble(value.toString());
}
} catch (NumberFormatException e) {
log.warn("点位值无法转换为数字: pointId={}, value={}", pointId, value);
doubleValue = null;
} }
} }
pointData.put("value", doubleValue);
pointData.put("addressValue", value);
pointData.put("attributeCode", getJsonString(jsonObj, "attributeCode"));
pointData.put("attributeName", getJsonString(jsonObj, "attributeName"));
pointData.put("attributeType", getJsonString(jsonObj, "attributeType"));
pointData.put("dataType", getJsonString(jsonObj, "dataType"));
pointData.put("dataUnit", getJsonString(jsonObj, "dataUnit"));
// 安全获取ratio
try {
Float ratio = jsonObj.getFloat("ratio");
pointData.put("ratio", ratio);
} catch (Exception e) {
pointData.put("ratio", null);
}
return pointData;
}
}
} catch (Exception e) {
log.error("解析点位数据失败, pointId: {}", pointId, e);
}
return null;
}
/**
* JSON
*/
private String getJsonString(JSONObject jsonObj, String key) {
try {
return jsonObj.getString(key);
} catch (Exception e) {
return "";
}
}
/**
* double
*/
private String formatDouble(Double value) {
if (value == null) {
return "0.0";
}
DecimalFormat df = new DecimalFormat("#.##");
return df.format(value);
}
/**
*
*/
private Map<String, Object> calculateDeviceData(EnergyDeviceDO deviceDO,
List<OperationRulesVO> rules,
String startTime, String endTime) {
if (deviceDO == null || rules == null || rules.isEmpty()) {
return null;
}
Map<String, Object> result = new HashMap<>();
try {
// 分别计算最新和最晚时间的数据
Map<String, Object> latestData = getTimePointData(rules, startTime, endTime, true);
Map<String, Object> earliestData = getTimePointData(rules, startTime, endTime, false);
if (latestData == null || earliestData == null) {
return result;
}
// 使用相同的规则计算两个时间点的总值
Double latestTotal = calculateTotalByRules(latestData, rules);
Double earliestTotal = calculateTotalByRules(earliestData, rules);
// 计算每个点位的差值
List<Map<String, Object>> pointDifferences = calculatePointDifferences(latestData, earliestData, rules);
result.put("latestData", latestData);
result.put("earliestData", earliestData);
result.put("latestTotal", latestTotal != null ? latestTotal : 0.0);
result.put("earliestTotal", earliestTotal != null ? earliestTotal : 0.0);
result.put("totalDifference", (latestTotal != null && earliestTotal != null) ?
latestTotal - earliestTotal : 0.0);
result.put("pointDifferences", pointDifferences != null ? pointDifferences : Collections.emptyList());
} catch (Exception e) {
log.error("计算设备数据失败, deviceId: {}", deviceDO.getId(), e);
}
return result;
}
/**
*
*/
private Double getPointValueFromDataByDevice(Map<String, Object> timePointData, Long deviceId, Long pointId) {
if (timePointData == null || deviceId == null || pointId == null) {
return null;
}
String deviceKey = "device_" + deviceId;
Map<String, Object> deviceData = (Map<String, Object>) timePointData.get(deviceKey);
if (deviceData == null) {
return null;
}
return getPointValueFromData(deviceData, pointId);
}
/**
*
*/
private Double getPointValueFromData(Map<String, Object> dataMap, Long pointId) {
if (dataMap == null || pointId == null) {
return null;
}
Map<String, Object> pointData = getPointData(dataMap, pointId);
if (pointData != null) {
Object value = pointData.get("value");
if (value instanceof Double) {
return (Double) value;
} else if (value instanceof Number) {
return ((Number) value).doubleValue();
}
}
return null;
}
/**
*
*/
private Map<String, Object> getTimePointData(List<OperationRulesVO> rules,
String startTime, String endTime,
boolean isLatest) {
if (rules == null || rules.isEmpty()) {
return null;
}
Map<String, Object> timePointData = new HashMap<>();
String timestamp = null;
for (OperationRulesVO rule : rules) {
if (rule == null || rule.getDeviceId() == null) {
continue;
}
List<Map<String, Object>> maps = null;
try {
maps = tDengineService.getstDeviceDataOrderByTimeDesc(
rule.getDeviceId(), startTime, endTime);
} catch (Exception e) {
log.error("查询设备数据失败, deviceId: {}", rule.getDeviceId(), e);
continue;
}
if (maps == null || maps.isEmpty()) {
continue;
}
Map<String, Object> dataMap = null;
try {
if (isLatest) {
dataMap = maps.get(0);
} else {
dataMap = maps.get(maps.size() - 1);
}
} catch (Exception e) {
log.error("获取时间点数据失败, deviceId: {}, isLatest: {}", rule.getDeviceId(), isLatest, e);
continue;
}
if (dataMap == null) {
continue;
}
if (timestamp == null && dataMap.containsKey("timestamp")) {
Object tsObj = dataMap.get("timestamp");
if (tsObj != null) {
timestamp = tsObj.toString();
} }
operationRulesVOMap.put(operationRulesVO.getPointId(),operationRulesVOS); }
String deviceKey = "device_" + rule.getDeviceId();
if (!timePointData.containsKey(deviceKey)) {
timePointData.put(deviceKey, dataMap);
} }
energyDeviceRespVO.setOperationRulesVOMap(operationRulesVOMap);
energyDeviceRespVOArrayList.add(energyDeviceRespVO);
} }
if (timestamp != null) {
timePointData.put("timestamp", timestamp);
} else {
timePointData.put("timestamp", "");
}
return timePointData.isEmpty() ? null : timePointData;
}
/**
*
*/
private Double calculateTotalByRules(Map<String, Object> timePointData, List<OperationRulesVO> rules) {
if (timePointData == null || timePointData.isEmpty() || rules == null || rules.isEmpty()) {
return 0.0;
}
Double total = null;
String lastOperator = null;
for (int i = 0; i < rules.size(); i++) {
OperationRulesVO rule = rules.get(i);
if (rule == null || rule.getDeviceId() == null || rule.getPointId() == null) {
continue;
}
String deviceKey = "device_" + rule.getDeviceId();
Map<String, Object> deviceData = (Map<String, Object>) timePointData.get(deviceKey);
if (deviceData == null) {
continue;
}
Double pointValue = getPointValueFromData(deviceData, rule.getPointId());
if (pointValue == null) {
continue;
}
if (total == null) {
total = pointValue;
} else {
String operator = null;
if (rule.getOperator() != null) {
operator = rule.getOperator().trim();
}
if (StringUtils.isEmpty(operator)) {
operator = lastOperator;
}
if (StringUtils.isNotEmpty(operator)) {
try {
total = applyOperator(total, pointValue, operator);
} catch (Exception e) {
log.error("应用运算符失败: current={}, value={}, operator={}", total, pointValue, operator, e);
total += pointValue;
}
} else {
total += pointValue;
}
}
lastOperator = rule.getOperator();
}
return total != null ? total : 0.0;
}
/**
*
*/
private List<Map<String, Object>> calculatePointDifferences(Map<String, Object> latestData,
Map<String, Object> earliestData,
List<OperationRulesVO> rules) {
List<Map<String, Object>> differences = new ArrayList<>();
if (rules == null || rules.isEmpty()) {
return differences;
}
for (OperationRulesVO rule : rules) {
if (rule == null || rule.getDeviceId() == null || rule.getPointId() == null) {
continue;
}
Map<String, Object> pointDiff = new HashMap<>();
pointDiff.put("pointId", rule.getPointId());
pointDiff.put("operator", rule.getOperator() != null ? rule.getOperator() : "");
pointDiff.put("deviceId", rule.getDeviceId());
Double latestValue = getPointValueFromDataByDevice(latestData, rule.getDeviceId(), rule.getPointId());
Double earliestValue = getPointValueFromDataByDevice(earliestData, rule.getDeviceId(), rule.getPointId());
pointDiff.put("latestValue", latestValue != null ? latestValue : 0.0);
pointDiff.put("earliestValue", earliestValue != null ? earliestValue : 0.0);
if (latestValue != null && earliestValue != null) {
Double difference = latestValue - earliestValue;
pointDiff.put("difference", difference);
} else if (latestValue != null) {
pointDiff.put("difference", latestValue);
} else if (earliestValue != null) {
pointDiff.put("difference", -earliestValue);
} else {
pointDiff.put("difference", 0.0);
}
differences.add(pointDiff);
}
return differences;
}
/**
*
*/
private Double applyOperator(Double current, Double value, String operator) {
if (current == null || value == null || operator == null) {
return current;
}
String op = operator.trim();
switch (op) {
case "+":
return current + value;
case "-":
return current - value;
case "*":
return current * value;
case "/":
if (Math.abs(value) > 0.000001) { // 避免除零
return current / value;
} else {
log.warn("除数不能为0: current={}, value={}", current, value);
return current;
}
default:
log.warn("不支持的操作符: {}, 使用加法", operator);
return current + value;
}
}
/**
*
*/
private String fixEncoding(String str) {
if (StringUtils.isBlank(str)) {
return str;
}
try {
// 尝试UTF-8解码
byte[] bytes = str.getBytes(StandardCharsets.ISO_8859_1);
return new String(bytes, StandardCharsets.UTF_8);
} catch (Exception e) {
return str;
}
}
/**
* Map
*/
private Map<String, String> buildPointDifferenceMap(Map<String, Object> calculationResult,
EnergyDeviceDO deviceDO,
List<OperationRulesVO> originalRules) {
Map<String, String> result = new HashMap<>();
if (calculationResult == null || originalRules == null || originalRules.isEmpty()) {
return result;
}
List<Map<String, Object>> pointDifferences = (List<Map<String, Object>>) calculationResult.get("pointDifferences");
if (pointDifferences == null || pointDifferences.isEmpty()) {
return result;
}
// 获取最新数据用于获取点位名称
Map<String, Object> latestData = (Map<String, Object>) calculationResult.get("latestData");
// 收集所有点位ID
List<Long> allPointIds = new ArrayList<>();
for (Map<String, Object> pointDiff : pointDifferences) {
Long pointId = (Long) pointDiff.get("pointId");
if (pointId != null) {
allPointIds.add(pointId);
}
}
// 批量从本地数据库获取点位名称
Map<Long, String> pointNameMap = batchGetPointNamesFromLocalDB(allPointIds);
for (Map<String, Object> pointDiff : pointDifferences) {
Long pointId = (Long) pointDiff.get("pointId");
if (pointId == null) {
continue;
}
// 获取点位名称
String pointName = null;
// 1. 尝试从TD数据库获取
pointName = getPointNameFromTDData(latestData, pointId, pointDiff);
// 2. 如果TD数据库没有从本地数据库获取
if (StringUtils.isBlank(pointName)) {
pointName = pointNameMap.get(pointId);
}
// 获取差值
Double difference = (Double) pointDiff.get("difference");
String differenceStr = formatDouble(difference != null ? difference : 0.0);
// 以点位名称为key差值为value
if (StringUtils.isNotBlank(pointName)) {
result.put(pointName, differenceStr);
} else {
// 如果还没有点位名称使用点位ID作为key
result.put("点位" + pointId, differenceStr);
}
}
return result;
}
/**
* TD
*/
private String getPointNameFromTDData(Map<String, Object> timePointData, Long pointId, Map<String, Object> pointDiff) {
if (timePointData == null || pointId == null || pointDiff == null) {
return null;
}
Long deviceId = (Long) pointDiff.get("deviceId");
if (deviceId == null) {
return null;
}
String deviceKey = "device_" + deviceId;
Map<String, Object> deviceData = (Map<String, Object>) timePointData.get(deviceKey);
if (deviceData == null) {
return null;
}
Map<String, Object> pointData = getPointData(deviceData, pointId);
if (pointData == null) {
return null;
}
String attributeName = (String) pointData.get("attributeName");
if (StringUtils.isNotBlank(attributeName)) {
return attributeName;
}
String attributeCode = (String) pointData.get("attributeCode");
if (StringUtils.isNotBlank(attributeCode)) {
return attributeCode;
}
return null;
}
/**
*
*/
private Map<Long, String> batchGetPointNamesFromLocalDB(List<Long> pointIds) {
Map<Long, String> result = new HashMap<>();
if (pointIds == null || pointIds.isEmpty()) {
return result;
}
try {
// 批量查询点位信息
List<DeviceContactModelDO> deviceContacts = deviceContactModelMapper.selectBatchIds(pointIds);
if (deviceContacts != null && !deviceContacts.isEmpty()) {
for (DeviceContactModelDO deviceContact : deviceContacts) {
if (deviceContact == null || deviceContact.getId() == null) {
continue;
}
String pointName = null;
if (StringUtils.isNotBlank(deviceContact.getAttributeName())) {
pointName = deviceContact.getAttributeName();
} else if (StringUtils.isNotBlank(deviceContact.getAttributeCode())) {
pointName = deviceContact.getAttributeCode();
}
if (StringUtils.isNotBlank(pointName)) {
result.put(deviceContact.getId(), pointName);
}
}
}
} catch (Exception e) {
log.error("批量查询点位信息失败, pointIds: {}", pointIds, e);
}
return energyDeviceRespVOArrayList; return result;
} }
} }

@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.mes.service.organization;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.LineAnalysisTreeDTO; import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.*;
import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationListReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO; import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO;
import javax.validation.Valid; import javax.validation.Valid;
@ -80,5 +77,7 @@ public interface OrganizationService {
return convertMap(getOrganizationVOList(ids), OrganizationDO::getId); return convertMap(getOrganizationVOList(ids), OrganizationDO::getId);
} }
List<LineAnalysisTreeDTO.LineNode> deviceParameterAnalysis(String keyword); List<LineAnalysisTreeDTO.LineNode> deviceParameterAnalysis(String keyword,Integer showDevices);
// List<DeviceParametersDTO> getDeviceParametersByOrganizationId(Long id);
} }

@ -257,374 +257,405 @@ public class OrganizationServiceImpl implements OrganizationService {
} }
@Override @Override
public List<LineAnalysisTreeDTO.LineNode> deviceParameterAnalysis(String keyword) { public List<LineAnalysisTreeDTO.LineNode> deviceParameterAnalysis(String keyword, Integer showDevices) {
// 参数验证
if (showDevices == null || (showDevices != 1 && showDevices != 2)) {
showDevices = 1; // 默认展示设备和参数
}
boolean needShowDevices = showDevices == 1; // 1-展示2-不展示
//1. 获取产线集合 // 1. 获取产线集合
OrganizationListReqVO organizationListReqVO = new OrganizationListReqVO(); OrganizationListReqVO organizationListReqVO = new OrganizationListReqVO();
List<OrganizationDO> organizationDOS = getOrganizationList(organizationListReqVO); List<OrganizationDO> organizationDOS = getOrganizationList(organizationListReqVO);
List<OrganizationRespVO> organizationRespVOS = buildVOList(organizationDOS); List<OrganizationRespVO> organizationRespVOS = buildVOList(organizationDOS);
if (organizationRespVOS.isEmpty()) { if (organizationRespVOS.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
// 2. 获取所有有machineId的产线 // 2. 获取所有有machineId的组织
List<Long> machineIds = organizationRespVOS.stream() List<Long> deviceIds = organizationRespVOS.stream()
.map(OrganizationRespVO::getMachineId) .map(OrganizationRespVO::getMachineId)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
// 3. 根据machineId查询设备 // 3. 查询设备信息
List<DeviceDO> allDevices = Collections.emptyList(); Map<Long, DeviceDO> deviceMap;
if (!machineIds.isEmpty()) { if (!deviceIds.isEmpty()) {
LambdaQueryWrapper<DeviceDO> deviceWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<DeviceDO> deviceWrapper = new LambdaQueryWrapper<>();
deviceWrapper.in(DeviceDO::getId, machineIds) deviceWrapper.in(DeviceDO::getId, deviceIds)
.eq(DeviceDO::getIsEnable, true); .eq(DeviceDO::getIsEnable, true);
allDevices = deviceMapper.selectList(deviceWrapper); List<DeviceDO> devices = deviceMapper.selectList(deviceWrapper);
deviceMap = devices.stream()
.collect(Collectors.toMap(DeviceDO::getId, Function.identity()));
} else {
deviceMap = new HashMap<>();
} }
// 4. 获取所有参数 // 4. 查询设备参数
List<DeviceContactModelDO> allParameters = getAllParameters(allDevices); Map<Long, List<DeviceContactModelDO>> paramsByDeviceId;
if (!deviceIds.isEmpty()) {
LambdaQueryWrapper<DeviceContactModelDO> paramWrapper = new LambdaQueryWrapper<>();
// 5. 构建映射关系 paramWrapper.in(DeviceContactModelDO::getDeviceId, deviceIds)
Map<Long, DeviceDO> deviceById = allDevices.stream() .orderByAsc(DeviceContactModelDO::getSort);
.collect(Collectors.toMap(DeviceDO::getId, Function.identity())); List<DeviceContactModelDO> allParameters = deviceContactModelMapper.selectList(paramWrapper);
paramsByDeviceId = allParameters.stream()
.filter(param -> param.getDeviceId() != null)
.collect(Collectors.groupingBy(DeviceContactModelDO::getDeviceId));
} else {
paramsByDeviceId = new HashMap<>();
}
// 6. 构建设备按产线分组的映射 // 5. 构建产线ID到orgClass的映射
Map<Long, List<DeviceDO>> devicesByLineId = new HashMap<>(); Map<Long, String> lineOrgClassMap = new HashMap<>();
for (OrganizationRespVO line : organizationRespVOS) { for (int i = 0; i < organizationDOS.size(); i++) {
if (line.getMachineId() != null) { OrganizationDO orgDO = organizationDOS.get(i);
DeviceDO device = deviceById.get(line.getMachineId()); OrganizationRespVO orgVO = organizationRespVOS.get(i);
if (device != null) { if (orgDO.getOrgClass() != null && orgVO != null) {
devicesByLineId.computeIfAbsent(line.getId(), k -> new ArrayList<>()) lineOrgClassMap.put(orgVO.getId(), orgDO.getOrgClass());
.add(device);
}
} }
} }
Map<Long, List<DeviceContactModelDO>> paramsByDeviceId = allParameters.stream() // 6. 构建组织ID到子节点的映射
.filter(param -> param.getDeviceId() != null) Map<Long, List<OrganizationRespVO>> childrenByParentId = organizationRespVOS.stream()
.collect(Collectors.groupingBy(DeviceContactModelDO::getDeviceId)); .filter(org -> org.getParentId() != null && org.getParentId() != 0L)
.collect(Collectors.groupingBy(OrganizationRespVO::getParentId));
// 获取产线与父节点的映射关系
Map<Long, Long> lineParentIdMap = organizationRespVOS.stream()
.collect(Collectors.toMap(
OrganizationRespVO::getId,
line -> line.getParentId() != null ? line.getParentId() : 0L, // 如果父节点为空使用默认值0
(existing, replacement) -> existing
));
// 构建产线ID到产线对象的映射
Map<Long, OrganizationRespVO> lineMap = organizationRespVOS.stream()
.collect(Collectors.toMap(OrganizationRespVO::getId, Function.identity()));
// 获取所有匹配的产线(包括下级匹配的)
List<OrganizationRespVO> matchedLines = getMatchedLinesWithAncestors(
organizationRespVOS, keyword, allDevices, paramsByDeviceId, lineParentIdMap, lineMap
);
// 7. 构建树结构
return buildTreeStructureWithKeyword(matchedLines, devicesByLineId, paramsByDeviceId,keyword,lineParentIdMap);
}
private List<OrganizationRespVO> getMatchedLinesWithAncestors(
List<OrganizationRespVO> allLines,
String keyword,
List<DeviceDO> allDevices,
Map<Long, List<DeviceContactModelDO>> paramsByDeviceId,
Map<Long, Long> lineParentIdMap,
Map<Long, OrganizationRespVO> lineMap) {
// 7. 如果有搜索关键词,筛选匹配的节点
Set<Long> matchedNodeIds = new HashSet<>();
boolean hasKeyword = StringUtils.isNotBlank(keyword); boolean hasKeyword = StringUtils.isNotBlank(keyword);
String lowerKeyword = hasKeyword ? keyword.toLowerCase() : "";
// 存储最终要包含的产线ID if (hasKeyword) {
Set<Long> lineIdsToInclude = new HashSet<>(); String lowerKeyword = keyword.toLowerCase();
// 1. 首先找出直接匹配的产线 // 查找组织名称匹配的节点
for (OrganizationRespVO line : allLines) { for (OrganizationRespVO node : organizationRespVOS) {
boolean lineMatch = !hasKeyword || boolean nodeMatched = false;
(line.getName() != null && line.getName().toLowerCase().contains(lowerKeyword));
if (lineMatch) { // 1. 检查组织名称是否匹配
// 添加到结果集 if (node.getName() != null && node.getName().toLowerCase().contains(lowerKeyword)) {
lineIdsToInclude.add(line.getId()); nodeMatched = true;
// 向上查找所有父级节点 }
addAllAncestors(line.getId(), lineParentIdMap, lineMap, lineIdsToInclude);
}
}
// 2. 查找设备匹配的产线 // 2. 如果没有组织名称匹配,检查该节点是否有设备匹配
if (hasKeyword) { if (!nodeMatched && needShowDevices && node.getMachineId() != null) {
for (DeviceDO device : allDevices) { DeviceDO device = deviceMap.get(node.getMachineId());
boolean deviceMatch = device.getDeviceName() != null && if (device != null) {
device.getDeviceName().toLowerCase().contains(lowerKeyword); // 检查设备名称是否匹配
if (device.getDeviceName() != null &&
if (deviceMatch) { device.getDeviceName().toLowerCase().contains(lowerKeyword)) {
// 找到这个设备所属的产线 nodeMatched = true;
for (OrganizationRespVO line : allLines) {
if (line.getMachineId() != null && line.getMachineId().equals(device.getId())) {
lineIdsToInclude.add(line.getId());
addAllAncestors(line.getId(), lineParentIdMap, lineMap, lineIdsToInclude);
} }
}
}
}
}
// 3. 查找参数匹配的产线 // 检查设备参数是否匹配
if (hasKeyword) { if (!nodeMatched) {
for (Map.Entry<Long, List<DeviceContactModelDO>> entry : paramsByDeviceId.entrySet()) { List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
Long deviceId = entry.getKey(); boolean hasMatchingParam = deviceParams.stream()
List<DeviceContactModelDO> params = entry.getValue(); .anyMatch(param -> param.getAttributeName() != null &&
param.getAttributeName().toLowerCase().contains(lowerKeyword));
boolean hasMatchingParam = params.stream() if (hasMatchingParam) {
.anyMatch(param -> param.getAttributeName() != null && nodeMatched = true;
param.getAttributeName().toLowerCase().contains(lowerKeyword)); }
if (hasMatchingParam) {
// 找到这个设备所属的产线
for (OrganizationRespVO line : allLines) {
if (line.getMachineId() != null && line.getMachineId().equals(deviceId)) {
lineIdsToInclude.add(line.getId());
addAllAncestors(line.getId(), lineParentIdMap, lineMap, lineIdsToInclude);
} }
} }
} }
if (nodeMatched) {
// 将当前节点加入匹配列表
matchedNodeIds.add(node.getId());
// 迭代添加所有子节点
addAllDescendants(node.getId(), childrenByParentId, matchedNodeIds);
}
} }
}
// 如果没有关键词,返回所有产线 // 如果没有匹配任何节点,返回空列表
if (!hasKeyword) { if (matchedNodeIds.isEmpty()) {
return allLines; return Collections.emptyList();
}
} else {
// 无关键词时,包含所有节点
matchedNodeIds.addAll(organizationRespVOS.stream()
.map(OrganizationRespVO::getId)
.collect(Collectors.toSet()));
} }
// 只返回需要包含的产线 // 8. 找到最顶层的匹配节点(没有匹配的父节点)
return allLines.stream() Set<Long> topLevelNodeIds = new HashSet<>(matchedNodeIds);
.filter(line -> lineIdsToInclude.contains(line.getId()))
.collect(Collectors.toList());
}
private void addAllAncestors(Long lineId,
Map<Long, Long> lineParentIdMap,
Map<Long, OrganizationRespVO> lineMap,
Set<Long> lineIdsToInclude) {
Long currentParentId = lineParentIdMap.get(lineId);
// 递归向上查找所有父级节点
while (currentParentId != null && currentParentId != 0L) {
lineIdsToInclude.add(currentParentId);
// 继续向上查找 // 从匹配节点中移除那些父节点也在匹配列表中的节点
currentParentId = lineParentIdMap.get(currentParentId); for (OrganizationRespVO node : organizationRespVOS) {
if (matchedNodeIds.contains(node.getId()) && node.getParentId() != null &&
node.getParentId() != 0L && matchedNodeIds.contains(node.getParentId())) {
topLevelNodeIds.remove(node.getId());
}
} }
}
private List<LineAnalysisTreeDTO.LineNode> buildTreeStructureWithKeyword(List<OrganizationRespVO> lines, // 9. 获取顶层节点
Map<Long, List<DeviceDO>> devicesByLineId, Map<Long, OrganizationRespVO> nodeMap = organizationRespVOS.stream()
Map<Long, List<DeviceContactModelDO>> paramsByDeviceId, .collect(Collectors.toMap(OrganizationRespVO::getId, Function.identity()));
String keyword,
Map<Long, Long> lineParentIdMap) {
// 统一处理关键词 List<OrganizationRespVO> topLevelNodes = topLevelNodeIds.stream()
boolean hasKeyword = StringUtils.isNotBlank(keyword); .map(nodeMap::get)
String lowerKeyword = hasKeyword ? keyword.toLowerCase() : ""; .filter(Objects::nonNull)
.collect(Collectors.toList());
// 如果lines已经过滤过这里不再需要复杂的匹配判断 // 10. 构建树结构
if (!hasKeyword) { return buildOrganizationTreeWithChildren(topLevelNodes, matchedNodeIds, childrenByParentId,
// 没有关键词时,返回完整的树结构 deviceMap, paramsByDeviceId, lineOrgClassMap, keyword, organizationRespVOS, needShowDevices, hasKeyword);
return lines.stream().map(line -> { }
Long parentId = lineParentIdMap.getOrDefault(line.getId(), 0L);
// 获取该产线的设备 /**
List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); *
*/
private void addAllDescendants(Long nodeId,
Map<Long, List<OrganizationRespVO>> childrenByParentId,
Set<Long> matchedNodeIds) {
if (childrenByParentId == null || childrenByParentId.isEmpty()) {
return;
}
// 构建设备节点(显示所有设备和参数) // 使用队列进行广度优先遍历
List<LineAnalysisTreeDTO.EquipmentNode> equipmentNodes = lineDevices.stream() Queue<Long> queue = new LinkedList<>();
.map(device -> { queue.offer(nodeId);
List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream() while (!queue.isEmpty()) {
.map(this::buildParameterNode) Long currentId = queue.poll();
.collect(Collectors.toList());
return LineAnalysisTreeDTO.EquipmentNode.builder() List<OrganizationRespVO> children = childrenByParentId.get(currentId);
.id(device.getId()) if (children != null && !children.isEmpty()) {
.name(device.getDeviceName()) for (OrganizationRespVO child : children) {
.parameters(parameterNodes) matchedNodeIds.add(child.getId());
.build(); queue.offer(child.getId());
}) }
.collect(Collectors.toList());
return LineAnalysisTreeDTO.LineNode.builder()
.id(line.getId())
.name(line.getName())
.parentId(parentId)
.equipments(equipmentNodes)
.build();
}).collect(Collectors.toList());
}
// 有关键词时lines已经包含了匹配的产线及其父级产线
// 但我们仍然需要根据关键词过滤设备和参数
// 记录匹配情况
Map<Long, Boolean> lineMatchedMap = new HashMap<>();
Map<Long, Boolean> deviceMatchedMap = new HashMap<>();
// 第一遍:分析匹配情况
for (OrganizationRespVO line : lines) {
// 产线是否匹配
boolean lineMatch = line.getName() != null &&
line.getName().toLowerCase().contains(lowerKeyword);
lineMatchedMap.put(line.getId(), lineMatch);
// 检查该产线的设备
List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>());
for (DeviceDO device : lineDevices) {
// 设备是否匹配
boolean deviceMatch = device.getDeviceName() != null &&
device.getDeviceName().toLowerCase().contains(lowerKeyword);
deviceMatchedMap.put(device.getId(), deviceMatch);
} }
} }
}
// 第二遍:构建树结构 /**
return lines.stream().map(line -> { *
boolean lineMatch = lineMatchedMap.getOrDefault(line.getId(), false); */
Long parentId = lineParentIdMap.getOrDefault(line.getId(), 0L); private List<LineAnalysisTreeDTO.LineNode> buildOrganizationTreeWithChildren(
List<OrganizationRespVO> topLevelNodes,
Set<Long> matchedNodeIds,
Map<Long, List<OrganizationRespVO>> childrenByParentId,
Map<Long, DeviceDO> deviceMap,
Map<Long, List<DeviceContactModelDO>> paramsByDeviceId,
Map<Long, String> lineOrgClassMap,
String keyword,
List<OrganizationRespVO> allOrganizationRespVOS,
boolean needShowDevices,
boolean hasKeyword) {
// 获取该产线的设备 // 创建节点映射
List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); Map<Long, LineAnalysisTreeDTO.LineNode> nodeMap = new HashMap<>();
// 构建设备节点 // 创建所有组织节点的映射
List<LineAnalysisTreeDTO.EquipmentNode> equipmentNodes = lineDevices.stream() Map<Long, OrganizationRespVO> allNodesMap = allOrganizationRespVOS.stream()
.map(device -> { .collect(Collectors.toMap(OrganizationRespVO::getId, Function.identity()));
boolean deviceMatch = deviceMatchedMap.getOrDefault(device.getId(), false);
List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
// 如果产线匹配,显示该产线下的所有设备 // 获取所有匹配节点的完整列表(包括所有子孙节点)
if (lineMatch) { Set<Long> allMatchedAndDescendantIds = new HashSet<>();
List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream() for (Long matchedId : matchedNodeIds) {
.map(this::buildParameterNode) allMatchedAndDescendantIds.add(matchedId);
.collect(Collectors.toList()); addAllDescendants(matchedId, childrenByParentId, allMatchedAndDescendantIds);
}
return LineAnalysisTreeDTO.EquipmentNode.builder() // 构建所有匹配节点的树节点
.id(device.getId()) for (OrganizationRespVO node : allOrganizationRespVOS) {
.name(device.getDeviceName()) if (!allMatchedAndDescendantIds.contains(node.getId())) {
.parameters(parameterNodes) continue;
.build(); }
}
// 如果设备匹配,显示该设备的所有参数 // 构建设备节点
if (deviceMatch) { List<LineAnalysisTreeDTO.EquipmentNode> equipmentNodes = new ArrayList<>();
List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream()
.map(this::buildParameterNode) if (needShowDevices) {
.collect(Collectors.toList()); // 有搜索关键词时获取所有设备,无关键词时只获取当前节点的设备
List<Long> deviceIds = hasKeyword ?
return LineAnalysisTreeDTO.EquipmentNode.builder() getAllDeviceIdsForNode(node.getId(), childrenByParentId, allNodesMap, allMatchedAndDescendantIds) :
.id(device.getId()) getCurrentDeviceId(node, allNodesMap);
.name(device.getDeviceName())
.parameters(parameterNodes) for (Long deviceId : deviceIds) {
.build(); DeviceDO device = deviceMap.get(deviceId);
} if (device != null) {
// 获取设备参数
List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
// 检查设备和参数是否匹配关键词
boolean shouldIncludeDevice = false;
List<DeviceContactModelDO> filteredParams = new ArrayList<>();
if (hasKeyword) {
String lowerKeyword = keyword.toLowerCase();
// 检查当前节点是否匹配关键词(组织名称匹配)
boolean isNodeNameMatched = node.getName() != null &&
node.getName().toLowerCase().contains(lowerKeyword);
if (!isNodeNameMatched) {
// 有关键词但不是组织名称匹配的情况
boolean deviceNameMatches = device.getDeviceName() != null &&
device.getDeviceName().toLowerCase().contains(lowerKeyword);
// 检查参数是否匹配
filteredParams = deviceParams.stream()
.filter(param -> param.getAttributeName() != null &&
param.getAttributeName().toLowerCase().contains(lowerKeyword))
.collect(Collectors.toList());
// 检查是否有匹配的参数 boolean hasMatchingParam = !filteredParams.isEmpty();
boolean hasMatchingParam = deviceParams.stream()
.anyMatch(param -> isParameterMatch(param, lowerKeyword));
if (!hasMatchingParam) { // 如果设备名称或参数匹配,则包含设备
return null; if (deviceNameMatches || hasMatchingParam) {
shouldIncludeDevice = true;
// 如果设备名称匹配但参数不匹配,包含所有参数
if (deviceNameMatches && filteredParams.isEmpty()) {
filteredParams = new ArrayList<>(deviceParams);
}
} }
} else {
// 是组织名称匹配的情况:包含所有设备和参数
shouldIncludeDevice = true;
filteredParams = new ArrayList<>(deviceParams);
}
} else {
// 无关键词的情况:包含所有设备和参数
shouldIncludeDevice = true;
filteredParams = new ArrayList<>(deviceParams);
}
// 只显示匹配的参数 if (shouldIncludeDevice) {
List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream() List<LineAnalysisTreeDTO.ParameterNode> paramInfos = filteredParams.stream()
.filter(param -> isParameterMatch(param, lowerKeyword)) .map(this::convertToSimpleInfo)
.map(this::buildParameterNode) .collect(Collectors.toList());
.collect(Collectors.toList());
return LineAnalysisTreeDTO.EquipmentNode.builder() // 检查设备是否已添加(避免重复)
boolean alreadyAdded = equipmentNodes.stream()
.anyMatch(e -> e.getId().equals(device.getId()));
if (!alreadyAdded) {
equipmentNodes.add(LineAnalysisTreeDTO.EquipmentNode.builder()
.id(device.getId()) .id(device.getId())
.name(device.getDeviceName()) .name(device.getDeviceName())
.parameters(parameterNodes) .parameters(paramInfos)
.build(); .build());
}) }
.filter(Objects::nonNull) }
.collect(Collectors.toList()); }
}
return LineAnalysisTreeDTO.LineNode.builder() }
.id(line.getId())
.name(line.getName())
.parentId(parentId)
.equipments(equipmentNodes)
.build();
})
.collect(Collectors.toList());
}
// /** LineAnalysisTreeDTO.LineNode lineNode = LineAnalysisTreeDTO.LineNode.builder()
// * 检查产线下是否有匹配的设备或参数 .id(node.getId())
// */ .name(node.getName())
// private boolean checkIfLineHasMatchingDeviceOrParam(OrganizationRespVO line, .orgClass(lineOrgClassMap.getOrDefault(node.getId(), null))
// Map<Long, List<DeviceDO>> devicesByLineId, .parentId(node.getParentId())
// Map<Long, List<DeviceContactModelDO>> paramsByDeviceId, .equipments(equipmentNodes)
// String lowerKeyword, .children(new ArrayList<>())
// Map<Long, Boolean> deviceMatchedMap) { .build();
//
// List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); nodeMap.put(node.getId(), lineNode);
// }
// for (DeviceDO device : lineDevices) {
// // 检查设备是否匹配 // 构建父子关系
// boolean deviceMatch = deviceMatchedMap.getOrDefault(device.getId(), false); List<LineAnalysisTreeDTO.LineNode> result = new ArrayList<>();
// if (deviceMatch) {
// return true; for (LineAnalysisTreeDTO.LineNode lineNode : nodeMap.values()) {
// } if (lineNode.getParentId() == null || lineNode.getParentId() == 0L) {
// // 根节点
// // 检查设备下的参数是否匹配 result.add(lineNode);
// List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); } else {
// boolean hasMatchingParam = deviceParams.stream() // 查找父节点
// .anyMatch(param -> isParameterMatch(param, lowerKeyword)); LineAnalysisTreeDTO.LineNode parentNode = nodeMap.get(lineNode.getParentId());
// if (hasMatchingParam) { if (parentNode != null) {
// return true; parentNode.getChildren().add(lineNode);
// } } else {
// } // 父节点不在当前构建的节点中,但当前节点是匹配的
// // 这种情况下,当前节点应该作为根节点展示
// return false; result.add(lineNode);
// } }
// }
// /** }
// * 检查设备下是否有匹配的参数
// */
// private boolean checkIfDeviceHasMatchingParam(DeviceDO device,
// Map<Long, List<DeviceContactModelDO>> paramsByDeviceId,
// String lowerKeyword) {
//
// List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
// return deviceParams.stream()
// .anyMatch(param -> isParameterMatch(param, lowerKeyword));
// }
// 过滤:只保留顶层节点
List<LineAnalysisTreeDTO.LineNode> filteredResult = new ArrayList<>();
Set<Long> topLevelNodeIds = topLevelNodes.stream()
.map(OrganizationRespVO::getId)
.collect(Collectors.toSet());
for (LineAnalysisTreeDTO.LineNode node : result) {
if (topLevelNodeIds.contains(node.getId())) {
filteredResult.add(node);
} else if (node.getParentId() == null || node.getParentId() == 0L) {
// 或者是没有父节点的根节点
filteredResult.add(node);
}
}
return filteredResult;
}
/** /**
* * ID
*/ */
private boolean isParameterMatch(DeviceContactModelDO param, String lowerKeyword) { private List<Long> getCurrentDeviceId(OrganizationRespVO node, Map<Long, OrganizationRespVO> allNodesMap) {
if (StringUtils.isBlank(lowerKeyword)) { List<Long> deviceIds = new ArrayList<>();
return true;
// 获取当前节点
OrganizationRespVO currentNode = allNodesMap.get(node.getId());
if (currentNode != null && currentNode.getMachineId() != null) {
deviceIds.add(currentNode.getMachineId());
} }
return (param.getAttributeName() != null && param.getAttributeName().toLowerCase().contains(lowerKeyword)); return deviceIds;
} }
/**
* ID
*/
private List<Long> getAllDeviceIdsForNode(Long nodeId,
Map<Long, List<OrganizationRespVO>> childrenByParentId,
Map<Long, OrganizationRespVO> allNodesMap,
Set<Long> matchedNodeIds) {
Set<Long> deviceIds = new HashSet<>();
// 先检查当前节点是否有设备
OrganizationRespVO currentNode = allNodesMap.get(nodeId);
if (currentNode != null && currentNode.getMachineId() != null) {
deviceIds.add(currentNode.getMachineId());
}
// 使用队列迭代获取所有子孙节点
Queue<Long> queue = new LinkedList<>();
queue.offer(nodeId);
while (!queue.isEmpty()) {
Long currentId = queue.poll();
// 获取当前节点的子节点
List<OrganizationRespVO> children = childrenByParentId.get(currentId);
if (children != null) {
for (OrganizationRespVO child : children) {
if (matchedNodeIds.contains(child.getId())) {
// 如果子节点有设备,添加到设备列表
if (child.getMachineId() != null) {
deviceIds.add(child.getMachineId());
}
// 继续处理子节点的子节点
queue.offer(child.getId());
}
}
}
}
return new ArrayList<>(deviceIds);
}
/** /**
* *
*/ */
private LineAnalysisTreeDTO.ParameterNode buildParameterNode(DeviceContactModelDO param) { private LineAnalysisTreeDTO.ParameterNode convertToSimpleInfo(DeviceContactModelDO param) {
return LineAnalysisTreeDTO.ParameterNode.builder() return LineAnalysisTreeDTO.ParameterNode.builder()
.id(param.getId()) .id(param.getId())
.name(param.getAttributeName()) .name(param.getAttributeName())
@ -636,29 +667,4 @@ public class OrganizationServiceImpl implements OrganizationService {
.build(); .build();
} }
private List<DeviceContactModelDO> getAllParameters(List<DeviceDO> devices) {
if (devices.isEmpty()) {
return Collections.emptyList();
}
List<Long> deviceIds = devices.stream()
.map(DeviceDO::getId)
.collect(Collectors.toList());
LambdaQueryWrapper<DeviceContactModelDO> wrapper = new LambdaQueryWrapper<>();
wrapper.in(DeviceContactModelDO::getDeviceId, deviceIds)
.orderByAsc(DeviceContactModelDO::getSort); // 按排序字段排序
List<DeviceContactModelDO> result = deviceContactModelMapper.selectList(wrapper);
// 调试日志
System.out.println("查询条件: 设备IDs=" + deviceIds);
System.out.println("查询结果数量: " + result.size());
return result;
}
} }

@ -109,7 +109,9 @@ public class TaskManagementServiceImpl implements TaskManagementService {
PageResult<TaskManagementDO> taskManagementDOPageResult = taskManagementMapper.selectPage(pageReqVO); PageResult<TaskManagementDO> taskManagementDOPageResult = taskManagementMapper.selectPage(pageReqVO);
for (TaskManagementDO taskManagementDO : taskManagementDOPageResult.getList()) { for (TaskManagementDO taskManagementDO : taskManagementDOPageResult.getList()) {
PlanMaintenanceDO planMaintenanceDO = planMaintenanceMapper.selectById(taskManagementDO.getProjectForm()); PlanMaintenanceDO planMaintenanceDO = planMaintenanceMapper.selectById(taskManagementDO.getProjectForm());
taskManagementDO.setProjectFormName(planMaintenanceDO.getPlanName()); if (planMaintenanceDO !=null) {
taskManagementDO.setProjectFormName(planMaintenanceDO.getPlanName());
}
} }

Loading…
Cancel
Save