feat(topology): 添加拓扑图目标指标功能并重构数据处理逻辑
- 在AppLineTopologyDiagram相关类中添加target字段用于绑定指标 - 重构DeviceMessageClient的getLineInfo方法参数结构 - 实现CsLineTopologyFeignClient的queryTopologyDiagram接口及降级处理 - 更新MqttMessageHandler中拓扑图数据处理逻辑,支持自定义指标查询 - 添加PqdData数据拆分服务IPqdDataSplitService及其实现 - 优化PortableOfflLogServiceImpl中的数据入库逻辑 - 修复CsTerminalReplyServiceImpl中时间范围查询条件 - 移除未使用的导入和代码,优化服务依赖注入
This commit is contained in:
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -44,5 +44,6 @@ public class AppLineTopologyDiagramParm extends BaseEntity {
|
||||
|
||||
private Double lat;
|
||||
|
||||
private String target;
|
||||
|
||||
}
|
||||
@@ -45,5 +45,7 @@ public class AppLineTopologyDiagramPO extends BaseEntity {
|
||||
@TableField(value = "lat")
|
||||
private Double lat;
|
||||
|
||||
@TableField(value = "target")
|
||||
private String target;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user