feat(topology): 添加拓扑图目标指标功能并重构数据处理逻辑

- 在AppLineTopologyDiagram相关类中添加target字段用于绑定指标
- 重构DeviceMessageClient的getLineInfo方法参数结构
- 实现CsLineTopologyFeignClient的queryTopologyDiagram接口及降级处理
- 更新MqttMessageHandler中拓扑图数据处理逻辑,支持自定义指标查询
- 添加PqdData数据拆分服务IPqdDataSplitService及其实现
- 优化PortableOfflLogServiceImpl中的数据入库逻辑
- 修复CsTerminalReplyServiceImpl中时间范围查询条件
- 移除未使用的导入和代码,优化服务依赖注入
This commit is contained in:
xy
2026-05-25 14:38:35 +08:00
parent 1d8d714d66
commit ea2962840c
17 changed files with 1079 additions and 453 deletions

View File

@@ -4,9 +4,12 @@ import com.njcn.common.pojo.constant.ServerInfo;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.csdevice.api.fallback.CsLineTopologyClientFallbackFactory;
import com.njcn.csdevice.pojo.po.AppLineTopologyDiagramPO;
import com.njcn.csdevice.pojo.vo.AppTopologyDiagramVO;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@@ -19,4 +22,8 @@ public interface CsLineTopologyFeignClient {
@PostMapping("/addList")
HttpResult<String> addList(@RequestBody List<AppLineTopologyDiagramPO> list);
@PostMapping("/queryTopologyDiagram")
@ApiOperation("查询装置拓扑图")
HttpResult<AppTopologyDiagramVO> queryTopologyDiagram(@RequestParam(value="devId") String devId);
}

View File

@@ -1,17 +1,11 @@
package com.njcn.csdevice.api;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.constant.ServerInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.csdevice.api.fallback.DeviceMessageClientFallbackFactory;
import com.njcn.csdevice.param.DeviceMessageParam;
import com.njcn.csdevice.pojo.po.CsLinePO;
import com.njcn.csdevice.param.LineInfoParam;
import com.njcn.user.pojo.po.User;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
@@ -36,6 +30,6 @@ public interface DeviceMessageFeignClient {
@PostMapping("/getLineInfo")
@ApiOperation("获取监测点信息")
HttpResult<String> getLineInfo(@RequestParam("id") String id, @RequestParam(value = "list", required = false) List<CsLinePO> list);
HttpResult<String> getLineInfo(@RequestBody LineInfoParam param);
}

View File

@@ -5,6 +5,7 @@ import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.csdevice.api.CsLineTopologyFeignClient;
import com.njcn.csdevice.pojo.po.AppLineTopologyDiagramPO;
import com.njcn.csdevice.pojo.vo.AppTopologyDiagramVO;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -33,6 +34,12 @@ public class CsLineTopologyClientFallbackFactory implements FallbackFactory<CsLi
throw new BusinessException(finalExceptionEnum);
}
@Override
public HttpResult<AppTopologyDiagramVO> queryTopologyDiagram(String devId) {
log.error("{}异常,降级处理,异常为:{}","查询装置拓扑图异常",cause.toString());
throw new BusinessException(finalExceptionEnum);
}
};
}
}

View File

@@ -5,7 +5,7 @@ import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.csdevice.api.DeviceMessageFeignClient;
import com.njcn.csdevice.param.DeviceMessageParam;
import com.njcn.csdevice.pojo.po.CsLinePO;
import com.njcn.csdevice.param.LineInfoParam;
import com.njcn.user.pojo.po.User;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
@@ -42,7 +42,7 @@ public class DeviceMessageClientFallbackFactory implements FallbackFactory<Devic
}
@Override
public HttpResult<String> getLineInfo(String id, List<CsLinePO> list) {
public HttpResult<String> getLineInfo(LineInfoParam param) {
log.error("{}异常,降级处理,异常为:{}","获取监测点信息数据异常",cause.toString());
throw new BusinessException(finalExceptionEnum);
}

View File

@@ -0,0 +1,21 @@
package com.njcn.csdevice.param;
import com.njcn.csdevice.pojo.po.CsLinePO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* @author xy
*/
@Data
public class LineInfoParam {
@ApiModelProperty("nDid")
private String nDid;
@ApiModelProperty("监测点集合")
List<CsLinePO> list;
}

View File

@@ -44,5 +44,6 @@ public class AppLineTopologyDiagramParm extends BaseEntity {
private Double lat;
private String target;
}

View File

@@ -45,5 +45,7 @@ public class AppLineTopologyDiagramPO extends BaseEntity {
@TableField(value = "lat")
private Double lat;
@TableField(value = "target")
private String target;
}

View File

@@ -1,8 +1,6 @@
package com.njcn.csdevice.pojo.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.bo.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
@@ -43,5 +41,6 @@ public class AppLineTopologyDiagramVO {
private String linePostion;
@ApiModelProperty(value="绑定的指标")
private String target;
}

View File

@@ -7,7 +7,7 @@ import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.csdevice.param.DeviceMessageParam;
import com.njcn.csdevice.pojo.po.CsLinePO;
import com.njcn.csdevice.param.LineInfoParam;
import com.njcn.csdevice.service.DeviceMessageService;
import com.njcn.user.pojo.po.User;
import com.njcn.web.controller.BaseController;
@@ -64,13 +64,10 @@ public class DeviceMessageController extends BaseController {
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/getLineInfo")
@ApiOperation("获取监测点信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "参数", paramType = "query"),
@ApiImplicitParam(name = "list", value = "监测点id集合", paramType = "query",required = false)
})
public HttpResult<String> getLineInfo(@RequestParam(value = "id") String id, @RequestParam(value = "list",required = false) List<CsLinePO> list){
@ApiImplicitParam(name = "param", value = "参数", required = true)
public HttpResult<String> getLineInfo(@RequestBody LineInfoParam param){
String methodDescribe = getMethodDescribe("getLineInfo");
deviceMessageService.getLineInfo(id,list);
deviceMessageService.getLineInfo(param.getNDid(),param.getList());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, "success", methodDescribe);
}

View File

@@ -0,0 +1,25 @@
package com.njcn.csdevice.service;
import com.njcn.influx.pojo.po.cs.PqdData;
import java.util.List;
import java.util.Map;
/**
* PqdData数据拆分服务
*
* @author system
* @since 2026-05-22
*/
public interface IPqdDataSplitService {
/**
* 将PqdData数据拆分到不同的表中
*
* @param pqdDataList 原始PqdData数据列表
* @return 包含两部分数据:
* - "splitData": 已拆分到各表的数据 Map<表名, 数据列表>
* - "remainingPqdData": 未匹配的PqdData数据仍需插入InfluxDB
*/
Map<String, Object> splitPqdData(List<PqdData> pqdDataList);
}

View File

@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.csdevice.mapper.AppLineTopologyDiagramMapper;
import com.njcn.csdevice.mapper.CsLedgerMapper;
import com.njcn.csdevice.pojo.param.AppTopologyDiagramQueryParm;
import com.njcn.csdevice.pojo.param.LinePostionParam;
import com.njcn.csdevice.pojo.po.AppLineTopologyDiagramPO;
@@ -13,7 +12,6 @@ import com.njcn.csdevice.pojo.po.CsLedger;
import com.njcn.csdevice.pojo.po.CsLinePO;
import com.njcn.csdevice.pojo.vo.AppLineTopologyDiagramVO;
import com.njcn.csdevice.pojo.vo.AppTopologyDiagramVO;
import com.njcn.csdevice.pojo.vo.CsLineTopologyTemplateVO;
import com.njcn.csdevice.service.AppLineTopologyDiagramService;
import com.njcn.csdevice.service.AppTopologyDiagramService;
import com.njcn.csdevice.service.CsLinePOService;
@@ -73,7 +71,7 @@ public class AppLineTopologyDiagramServiceImpl extends ServiceImpl<AppLineTopolo
}
public List<AppLineTopologyDiagramVO> queryByLineIds(List<String> lineIds) {
List<AppLineTopologyDiagramVO> result = new ArrayList<>();
if (lineIds != null && lineIds.size() > 0) {
if (lineIds != null && !lineIds.isEmpty()) {
result = this.getBaseMapper().queryByLineIds( lineIds);
}
return result;
@@ -83,14 +81,13 @@ public class AppLineTopologyDiagramServiceImpl extends ServiceImpl<AppLineTopolo
@Override
@Transactional(rollbackFor = Exception.class)
public void auditList(LinePostionParam linePostionParam) {
linePostionParam.getPointList().forEach(temp->{
csLinePOService.lambdaUpdate().eq(CsLinePO::getLineId,temp.getLineId()).set(CsLinePO::getName,temp.getName()).set(CsLinePO::getPosition,temp.getLinePostion()).update();
this.lambdaUpdate().eq(AppLineTopologyDiagramPO::getId,temp.getId()).
eq(AppLineTopologyDiagramPO::getLineId,temp.getLineId()).set(AppLineTopologyDiagramPO::getLat,temp.getLat()).
set(AppLineTopologyDiagramPO::getLng,temp.getLng()).set(AppLineTopologyDiagramPO::getId,linePostionParam.getId()).update();
set(AppLineTopologyDiagramPO::getLng,temp.getLng()).set(AppLineTopologyDiagramPO::getId,linePostionParam.getId())
.set(AppLineTopologyDiagramPO::getTarget,temp.getTarget())
.update();
iCsLedgerService.lambdaUpdate().eq(CsLedger::getId,temp.getLineId()).set(CsLedger::getName,temp.getName()).update();
});
}

View File

@@ -1,6 +1,7 @@
package com.njcn.csdevice.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -177,27 +178,10 @@ public class CsTerminalReplyServiceImpl extends ServiceImpl<CsTerminalReplyMappe
QueryWrapper<CsTerminalReply> queryWrapper = new QueryWrapper<>();
if (StrUtil.isNotBlank(param.getSearchValue())) {
queryWrapper.like("cs_terminal_reply.line_id", param.getSearchValue());
// //获取监测点id
// List<CsLinePO> list = csLinePOService.getLineByName(param.getSearchValue());
// if (CollectionUtil.isEmpty(list)) {
// return page;
// } else {
// queryWrapper.and(pr -> {
// // 获取所有 lineId
// List<String> lineIds = list.stream()
// .map(CsLinePO::getLineId)
// .collect(Collectors.toList());
// // 使用 OR 条件连接多个 lineId
// for (int i = 0; i < lineIds.size(); i++) {
// if (i == 0) {
// pr.like("cs_terminal_reply.line_id", lineIds.get(i));
// } else {
// pr.or().like("cs_terminal_reply.line_id", lineIds.get(i));
// }
// }
// });
// }
}
queryWrapper.between("cs_terminal_reply.Create_Time"
, DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime()))
, DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime())));
//排序
queryWrapper.orderBy(true, false, "cs_terminal_reply.create_time");
queryWrapper.in("cs_terminal_reply.code", Arrays.asList("allFile", "allEvent", "oneFile"));

View File

@@ -5,6 +5,7 @@ import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.tocrhz.mqtt.publisher.MqttPublisher;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
@@ -12,17 +13,13 @@ import com.njcn.csdevice.api.EquipmentFeignClient;
import com.njcn.csdevice.constant.DataParam;
import com.njcn.csdevice.enums.AlgorithmResponseEnum;
import com.njcn.csdevice.mapper.PortableOfflLogMapper;
import com.njcn.csdevice.param.UploadDataParam;
import com.njcn.csdevice.pojo.dto.CsEquipmentDeliveryDTO;
import com.njcn.csdevice.pojo.po.CsLinePO;
import com.njcn.csdevice.pojo.po.PortableOffMainLog;
import com.njcn.csdevice.pojo.po.PortableOfflLog;
import com.njcn.csdevice.pojo.po.WlRecord;
import com.njcn.csdevice.service.CsLinePOService;
import com.njcn.csdevice.service.IPortableOfflLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.csdevice.param.UploadDataParam;
import com.njcn.csdevice.service.IWlRecordService;
import com.njcn.csdevice.service.PortableOffMainLogService;
import com.njcn.csdevice.service.*;
import com.njcn.csdevice.util.InfluxDbParamUtil;
import com.njcn.csharmonic.api.EventFeignClient;
import com.njcn.csharmonic.api.OfflineDataUploadFeignClient;
@@ -36,8 +33,8 @@ import com.njcn.csharmonic.offline.mincfg.AnalyseComtradeCfg;
import com.njcn.csharmonic.offline.mincfg.vo.CmnModeCfg;
import com.njcn.csharmonic.offline.vo.Response;
import com.njcn.csharmonic.pojo.po.CsEventPO;
import com.njcn.influx.imapper.EvtDataMapper;
import com.njcn.influx.imapper.PqdDataMapper;
import com.njcn.influx.imapper.*;
import com.njcn.influx.pojo.po.*;
import com.njcn.influx.pojo.po.cs.EntData;
import com.njcn.influx.pojo.po.cs.PqdData;
import com.njcn.oss.utils.FileStorageUtil;
@@ -50,11 +47,11 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
@@ -81,25 +78,31 @@ public class PortableOfflLogServiceImpl extends ServiceImpl<PortableOfflLogMappe
private final DecimalFormat df = new DecimalFormat("#0.000");
private final FileStorageUtil fileStorageUtil;
private final DicDataFeignClient dicDataFeignClient;
private final OfflineDataUploadFeignClient offlineDataUploadFeignClient;
private final EleEvtFeignClient eleEvtFeignClient;
private final EventFeignClient eventFeignClient;
private final EquipmentFeignClient equipmentFeignClient;
private final InfluxDbParamUtil influxDbParamUtil;
private final PqdDataMapper pqdDataMapper;
private final EvtDataMapper evtDataMapper;
private final DataVMapper dataVMapper;
private final DataIMapper dataIMapper;
private final DataHarmRateVMapper dataHarmRateV;
private final DataHarmRateIMapper dataHarmRateI;
private final DataInHarmVMapper dataInHarmV;
private final DataHarmPowerPMapper dataHarmPowerP;
private final DataHarmPowerQMapper dataHarmPowerQ;
private final DataHarmPowerSMapper dataHarmPowerS;
private final DataFlickerMapper dataFlicker;
private final DataFlucMapper dataFluc;
private final DataPltMapper dataPlt;
private final DataHarmPhasicVMapper dataHarmPhasicV;
private final DataHarmPhasicIMapper dataHarmPhasicI;
private final IPqdDataSplitService pqdDataSplitService;
private final MqttPublisher publisher;
private final PortableOffMainLogService portableOffMainLogService;
private final IWlRecordService wlRecordService;
@@ -353,6 +356,8 @@ public class PortableOfflLogServiceImpl extends ServiceImpl<PortableOfflLogMappe
List<List<PqdData>> partition = ListUtils.partition(pqdData, 1500);
for (List<PqdData> sliceList : partition) {
List<PqdData> sublistAsOriginalListType = new ArrayList<>(sliceList);
// Map<String, Object> map = pqdDataSplitService.splitPqdData(sublistAsOriginalListType);
// insertData(map);
pqdDataMapper.insertBatch(sublistAsOriginalListType);
}
//min结果集解析入库后就不需要在解析了
@@ -604,4 +609,61 @@ public class PortableOfflLogServiceImpl extends ServiceImpl<PortableOfflLogMappe
}
return Objects.isNull(result)?null:result;
}
public void insertData(Map<String, Object> map) {
//13张表
Map<String, List<?>> splitData = (Map<String, List<?>>) map.get("splitData");
splitData.forEach((key, value) -> {
switch (key) {
case "data_v":
dataVMapper.insertBatch((List<DataV>) value);
break;
case "data_i":
dataIMapper.insertBatch((List<DataI>) value);
break;
case "data_flicker":
dataFlicker.insertBatch((List<DataFlicker>) value);
break;
case "data_fluc":
dataFluc.insertBatch((List<DataFluc>) value);
break;
case "data_harmphasic_i":
dataHarmPhasicI.insertBatch((List<DataHarmPhasicI>) value);
break;
case "data_harmphasic_v":
dataHarmPhasicV.insertBatch((List<DataHarmPhasicV>) value);
break;
case "data_harmpower_p":
dataHarmPowerP.insertBatch((List<DataHarmPowerP>) value);
break;
case "data_harmpower_q":
dataHarmPowerQ.insertBatch((List<DataHarmPowerQ>) value);
break;
case "data_harmpower_s":
dataHarmPowerS.insertBatch((List<DataHarmPowerS>) value);
break;
case "data_harmrate_v":
dataHarmRateV.insertBatch((List<DataHarmRateV>) value);
break;
case "data_harmrate_i":
dataHarmRateI.insertBatch((List<DataHarmRateI>) value);
break;
case "data_inharm_v":
dataInHarmV.insertBatch((List<DataInHarmV>) value);
break;
case "data_plt":
dataPlt.insertBatch((List<DataPlt>) value);
break;
default:
log.warn("不支持的目标表: {}", key);
break;
}
});
//其余数据
List<PqdData> remainingPqdData = (List<PqdData>) map.get("remainingPqdData");
if (!CollectionUtils.isEmpty(remainingPqdData)) {
pqdDataMapper.insertBatch(remainingPqdData);
}
}
}

View File

@@ -0,0 +1,425 @@
package com.njcn.csdevice.service.impl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.njcn.csdevice.service.IPqdDataSplitService;
import com.njcn.influx.pojo.po.*;
import com.njcn.influx.pojo.po.cs.PqdData;
import com.njcn.redis.pojo.enums.AppRedisKey;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.api.EpdFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.system.pojo.po.EleEpdPqd;
import com.njcn.system.pojo.vo.EleEpdPqdListVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* PqdData数据拆分服务实现
*
* @author system
* @since 2026-05-22
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class PqdDataSplitServiceImpl implements IPqdDataSplitService {
private final RedisUtil redisUtil;
private final EpdFeignClient epdFeignClient;
private final DicDataFeignClient dicDataFeignClient;
@Override
public Map<String, Object> splitPqdData(List<PqdData> pqdDataList) {
Map<String, Object> result = new HashMap<>();
if (CollectionUtils.isEmpty(pqdDataList)) {
result.put("splitData", Collections.emptyMap());
result.put("remainingPqdData", Collections.emptyList());
return result;
}
log.info("开始拆分PqdData数据共{}条记录", pqdDataList.size());
Map<String, List<?>> splitDataMap = new HashMap<>();
List<PqdData> remainingPqdData = new ArrayList<>();
//获取表映射关系
Map<String,String> map1 = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.ELE_EPD_PQD)), Map.class);
//获取字段映射关系
DictData pqd = dicDataFeignClient.getDicDataByCode(DicDataEnum.PQD.getCode()).getData();
List<EleEpdPqdListVO> list = epdFeignClient.selectAll().getData();
List<EleEpdPqd> epdList = list.stream().filter(item -> Objects.equals(item.getDataType(), pqd.getId()))
.findFirst()
.map(EleEpdPqdListVO::getEleEpdPqdVOS)
.orElse(new ArrayList<>());
// 处理 harmStart 和 harmEnd
List<EleEpdPqd> resultList = epdList.stream()
.flatMap(item -> {
if (item.getHarmStart() != null && item.getHarmEnd() != null) {
// 生成从 harmStart 到 harmEnd 的新对象
List<EleEpdPqd> expandedList = new ArrayList<>();
for (int i = item.getHarmStart(); i <= item.getHarmEnd(); i++) {
EleEpdPqd newItem = copyEleEpdPqd(item);
newItem.setName(item.getName() + "_" + i);
expandedList.add(newItem);
}
return expandedList.stream();
} else {
// 保持原对象
return Stream.of(item);
}
})
.collect(Collectors.toList());
Map<String,List<EleEpdPqd>> map2 = resultList.stream().collect(Collectors.groupingBy(EleEpdPqd::getName,LinkedHashMap::new,Collectors.toList()));
try {
for (PqdData pqdData : pqdDataList) {
boolean hasMatchedField = false;
Map<String, Object> fieldValues = extractFieldValues(pqdData);
for (Map.Entry<String, Object> entry : fieldValues.entrySet()) {
String sourceFieldName = StringUtils.capitalize(entry.getKey());
Object value = entry.getValue();
if (value == null || isCommonField(sourceFieldName)) {
continue;
}
String tableName = map1.get(sourceFieldName);
String otherName = sourceFieldName;
List<EleEpdPqd> v = map2.get(sourceFieldName);
if (!CollectionUtils.isEmpty(v)) {
otherName = toCamelCase(v.get(0).getOtherName());
}
if (StrUtil.isBlank(tableName) || StrUtil.isBlank(otherName)) {
continue;
}
hasMatchedField = true;
if (!splitDataMap.containsKey(tableName)) {
splitDataMap.put(tableName, new ArrayList<>());
}
createAndAddTargetData((List<Object>) splitDataMap.get(tableName), tableName, pqdData, otherName, value);
}
if (!hasMatchedField) {
remainingPqdData.add(pqdData);
}
}
result.put("splitData", splitDataMap);
result.put("remainingPqdData", remainingPqdData);
log.info("PqdData数据拆分完成拆分为{}个表,剩余{}条未匹配数据需插入InfluxDB",
splitDataMap.size(), remainingPqdData.size());
} catch (Exception e) {
log.error("PqdData数据拆分失败", e);
throw new RuntimeException("PqdData数据拆分失败", e);
}
return result;
}
private Map<String, Object> extractFieldValues(PqdData pqdData) {
Map<String, Object> fieldValues = new HashMap<>();
Field[] fields = PqdData.class.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
try {
Object value = field.get(pqdData);
if (value != null) {
fieldValues.put(field.getName(), value);
}
} catch (IllegalAccessException e) {
log.warn("获取字段 {} 的值失败", field.getName(), e);
}
}
return fieldValues;
}
private boolean isCommonField(String fieldName) {
Set<String> commonFields = new HashSet<>(Arrays.asList(
"time", "lineId", "phasicType", "valueType", "clDid",
"process", "qualityFlag"
));
return commonFields.contains(fieldName);
}
private void createAndAddTargetData(List<Object> dataList, String tableName,
PqdData pqdData, String targetField, Object value) {
switch (tableName.toLowerCase()) {
case "data_v":
dataList.add(createRStatDataVD(pqdData, targetField, value));
break;
case "data_i":
dataList.add(createRStatDataID(pqdData, targetField, value));
break;
case "data_flicker":
dataList.add(createRStatDataFlicker(pqdData, targetField, value));
break;
case "data_fluc":
dataList.add(createRStatDataFluc(pqdData, targetField, value));
break;
case "data_harmphasic_i":
dataList.add(createRStatDataHarmphasicI(pqdData, targetField, value));
break;
case "data_harmphasic_v":
dataList.add(createRStatDataHarmphasicV(pqdData, targetField, value));
break;
case "data_harmpower_p":
dataList.add(createRStatDataHarmpowerP(pqdData, targetField, value));
break;
case "data_harmpower_q":
dataList.add(createRStatDataHarmpowerQ(pqdData, targetField, value));
break;
case "data_harmpower_s":
dataList.add(createRStatDataHarmpowerS(pqdData, targetField, value));
break;
case "data_harmrate_v":
dataList.add(createRStatDataHarmrateV(pqdData, targetField, value));
break;
case "data_harmrate_i":
dataList.add(createRStatDataHarmrateI(pqdData, targetField, value));
break;
case "data_inharm_v":
dataList.add(createRStatDataInharmV(pqdData, targetField, value));
break;
case "data_plt":
dataList.add(createRStatDataPlt(pqdData, targetField, value));
break;
default:
log.warn("不支持的目标表: {}", tableName);
break;
}
}
private Object createRStatDataVD(PqdData pqdData, String targetField, Object value) {
DataV data = new DataV();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataID(PqdData pqdData, String targetField, Object value) {
DataI data = new DataI();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setValueType(pqdData.getPhaseType());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataFlicker(PqdData pqdData, String targetField, Object value) {
DataFlicker data = new DataFlicker();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataFluc(PqdData pqdData, String targetField, Object value) {
DataFluc data = new DataFluc();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataHarmphasicI(PqdData pqdData, String targetField, Object value) {
DataHarmPhasicI data = new DataHarmPhasicI();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataHarmphasicV(PqdData pqdData, String targetField, Object value) {
DataHarmPhasicV data = new DataHarmPhasicV();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataHarmpowerP(PqdData pqdData, String targetField, Object value) {
DataHarmPowerP data = new DataHarmPowerP();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataHarmpowerQ(PqdData pqdData, String targetField, Object value) {
DataHarmPowerQ data = new DataHarmPowerQ();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataHarmpowerS(PqdData pqdData, String targetField, Object value) {
DataHarmPowerS data = new DataHarmPowerS();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataHarmrateV(PqdData pqdData, String targetField, Object value) {
DataHarmRateV data = new DataHarmRateV();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataHarmrateI(PqdData pqdData, String targetField, Object value) {
DataHarmRateI data = new DataHarmRateI();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataInharmV(PqdData pqdData, String targetField, Object value) {
DataInHarmV data = new DataInHarmV();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private Object createRStatDataPlt(PqdData pqdData, String targetField, Object value) {
DataPlt data = new DataPlt();
data.setTime(pqdData.getTime());
data.setLineId(pqdData.getLineId());
data.setPhaseType(pqdData.getPhaseType());
data.setValueType(pqdData.getValueType());
data.setClDid(pqdData.getClDid());
data.setProcess(pqdData.getProcess());
data.setQualityFlag("0");
setFieldValue(data, targetField, value);
return data;
}
private void setFieldValue(Object obj, String fieldName, Object value) {
try {
String camelCaseFieldName = toCamelCase(fieldName);
Field field = obj.getClass().getDeclaredField(camelCaseFieldName);
field.setAccessible(true);
field.set(obj, value);
} catch (NoSuchFieldException | IllegalAccessException e) {
log.warn("设置字段 {} 的值失败", fieldName, e);
}
}
public static String toCamelCase(String input) {
if (input == null || input.isEmpty()) {
return input;
}
StringBuilder result = new StringBuilder();
boolean toUpper = false;
for (char c : input.toCharArray()) {
if (c == '_') {
toUpper = true;
} else {
if (toUpper) {
result.append(Character.toUpperCase(c));
toUpper = false;
} else {
result.append(c);
}
}
}
// 确保首字母小写以匹配Java实体字段命名规范
if (result.length() > 0 && Character.isUpperCase(result.charAt(0))) {
result.setCharAt(0, Character.toLowerCase(result.charAt(0)));
}
return result.toString();
}
private EleEpdPqd copyEleEpdPqd(EleEpdPqd source) {
if (source == null) {
return null;
}
EleEpdPqd target = new EleEpdPqd();
BeanUtils.copyProperties(source, target);
return target;
}
}