ids);
+ void updateCause(@Param("code") Integer code, @Param("indexEvt") String indexEvt);
+
+ void updateType(@Param("code") Integer code, @Param("indexEvt") String indexEvt);
+
}
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/PqDeviceMapper.java b/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/PqDeviceMapper.java
index 14c9324..1b18788 100644
--- a/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/PqDeviceMapper.java
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/PqDeviceMapper.java
@@ -4,6 +4,7 @@ import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.influx.bo.po.PqDevice;
import com.njcn.influx.bo.po.PqDeviceBak;
+import org.apache.ibatis.annotations.Param;
/**
*
@@ -16,4 +17,6 @@ import com.njcn.influx.bo.po.PqDeviceBak;
@DS("master")
public interface PqDeviceMapper extends BaseMapper {
+ PqDevice selectByLineId(@Param("lineId") String lineId);
+
}
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/PqsEventLogMapper.java b/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/PqsEventLogMapper.java
new file mode 100644
index 0000000..87dddd3
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/PqsEventLogMapper.java
@@ -0,0 +1,16 @@
+package com.njcn.influx.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.njcn.influx.bo.po.PqsEventLog;
+
+/**
+ * Description:
+ * Date: 2026/04/20 上午 10:21【需求编号】
+ *
+ * @author clam
+ * @version V1.0.0
+ */
+public interface PqsEventLogMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/mapping/OracleRmpEventDetailPOMapper.xml b/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/mapping/OracleRmpEventDetailPOMapper.xml
index 6902932..3fcc2d0 100644
--- a/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/mapping/OracleRmpEventDetailPOMapper.xml
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/mapping/OracleRmpEventDetailPOMapper.xml
@@ -37,4 +37,22 @@
+
+
+ update pqs_eventdetail set eventreason = (select
+ a.dic_index from pqs_dicdata a,pqs_dictype b where b.dictype_name =
+ '暂降原因' and a.dic_type = b.dictype_index and a.triphase = #{code} and
+ a.state = 1 and b.state = 1)
+ where
+ eventdetail_index = #{indexEvt}
+
+
+ update pqs_eventdetail set EVENTTYPE = (select
+ a.dic_index from pqs_dicdata a,pqs_dictype b where b.dictype_name =
+ '暂降类型' and a.dic_type = b.dictype_index and a.triphase = #{code} and
+ a.state = 1 and b.state = 1)
+ where
+ eventdetail_index = #{indexEvt}
+
+
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/mapping/PqDeviceMapper.xml b/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/mapping/PqDeviceMapper.xml
new file mode 100644
index 0000000..c9f6b47
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/mapping/PqDeviceMapper.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ DEV_INDEX, GD_INDEX, SUB_INDEX, "NAME", "STATUS", DEVTYPE, LOGONTIME, UPDATETIME,
+ NODE_INDEX, PORTID, DEVFLAG, DEV_SERIES, DEV_KEY, IP, DEVMODEL, CALLFLAG, DATATYPE
+
+
+
+
+
\ No newline at end of file
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/mapping/PqsEventLogMapper.xml b/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/mapping/PqsEventLogMapper.xml
new file mode 100644
index 0000000..9826796
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/mapper/mapping/PqsEventLogMapper.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ID, EVENTDETAIL_INDEX, fileupFlag, dealFlag, CreatTime, UpdateTime, REMARK
+
+
\ No newline at end of file
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/service/OracleEventDetailToMysqlService.java b/influx-data/influx-source/src/main/java/com/njcn/influx/service/OracleEventDetailToMysqlService.java
index fda22d0..772f120 100644
--- a/influx-data/influx-source/src/main/java/com/njcn/influx/service/OracleEventDetailToMysqlService.java
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/service/OracleEventDetailToMysqlService.java
@@ -14,4 +14,5 @@ import java.time.LocalDateTime;
public interface OracleEventDetailToMysqlService extends IService {
void eventBatch(LocalDateTime start, LocalDateTime end);
+
}
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/service/OracleToMysqlService.java b/influx-data/influx-source/src/main/java/com/njcn/influx/service/OracleToMysqlService.java
new file mode 100644
index 0000000..55ef26d
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/service/OracleToMysqlService.java
@@ -0,0 +1,16 @@
+package com.njcn.influx.service;
+
+import java.time.LocalDateTime;
+
+/**
+ * Description:
+ * Date: 2026/04/20 上午 9:53【需求编号】
+ *
+ * @author clam
+ * @version V1.0.0
+ */
+public interface OracleToMysqlService {
+
+ void OracleToMySqlJob(LocalDateTime result, LocalDateTime modifiedResult);
+ void retryAndCleanEvery10Min();
+}
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/service/PqsEventLogService.java b/influx-data/influx-source/src/main/java/com/njcn/influx/service/PqsEventLogService.java
new file mode 100644
index 0000000..0508654
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/service/PqsEventLogService.java
@@ -0,0 +1,17 @@
+package com.njcn.influx.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.njcn.influx.bo.po.PqsEventLog;
+
+/**
+ *
+ * 服务类
+ *
+ *
+ * @author wr
+ * @since 2024-03-05
+ */
+
+public interface PqsEventLogService extends IService {
+
+}
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/service/RmpEventDetailService.java b/influx-data/influx-source/src/main/java/com/njcn/influx/service/RmpEventDetailService.java
new file mode 100644
index 0000000..1c81ace
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/service/RmpEventDetailService.java
@@ -0,0 +1,15 @@
+package com.njcn.influx.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.njcn.influx.bo.po.RmpEventDetailPO;
+
+/**
+ * Description:
+ * Date: 2026/04/20 上午 11:28【需求编号】
+ *
+ * @author clam
+ * @version V1.0.0
+ */
+public interface RmpEventDetailService extends IService {
+ void syncToMysql(String eventId);
+}
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/EventAsyncService.java b/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/EventAsyncService.java
new file mode 100644
index 0000000..8f4da64
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/EventAsyncService.java
@@ -0,0 +1,244 @@
+package com.njcn.influx.service.impl;
+
+import com.jcraft.jsch.ChannelSftp;
+
+import com.njcn.influx.bo.po.OracleRmpEventDetailPO;
+import com.njcn.influx.bo.po.PqDevice;
+import com.njcn.influx.bo.po.PqsEventLog;
+import com.njcn.influx.component.WaveFileComponent;
+import com.njcn.influx.component.dto.WaveDataDTO;
+import com.njcn.influx.config.OtherConfig;
+import com.njcn.influx.config.TargetConfig;
+import com.njcn.influx.event.cause.jna.QvvrCauseDLL;
+import com.njcn.influx.event.cause.model.DataFeature;
+import com.njcn.influx.event.cause.model.EventAnalysisDTO;
+import com.njcn.influx.event.type.jna.QvvrDLL;
+import com.njcn.influx.mapper.OracleRmpEventDetailPOMapper;
+import com.njcn.influx.mapper.PqDeviceMapper;
+import com.njcn.influx.service.PqsEventLogService;
+import com.njcn.influx.service.RmpEventDetailService;
+import com.njcn.influx.sftp.SftpClient;
+import com.sun.jna.Memory;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class EventAsyncService {
+
+
+
+
+ private final RmpEventDetailService rmpEventDetailService;
+
+ private final PqDeviceMapper pqDeviceMapper;
+ private final WaveFileComponent waveFileComponent;
+
+ private final OtherConfig config;
+
+ private final TargetConfig targetConfig;
+
+ private final OracleRmpEventDetailPOMapper oracleRmpEventDetailPOMapper;
+ private final PqsEventLogService pqsEventLogService;
+
+ @Value("${business.dealFlag:true}")
+ private Boolean dealFlag;
+ @Value("${business.upLoadFlag:true}")
+ private Boolean upLoadFlag;
+
+
+ // ============================
+ // 文件同步 + 高级算法
+ // ============================
+// @Async("eventTaskExecutor")
+ public void asyncHandleEvent(OracleRmpEventDetailPO detail ) {
+ try {
+ log.info("异步处理事件:{} 文件:{}", detail.getEventId(), detail.getWavePath());
+ // ========== 1. 查看波形文件是否存在 ==========
+ PqDevice pqDevice = pqDeviceMapper.selectByLineId(detail.getMeasurementPointId());
+ String wavePath = config.getWavePath();
+ String cfgPath = wavePath + File.separator + pqDevice.getIp() + File.separator + detail.getWavePath() + ".CFG" ;
+ String datPath = wavePath + File.separator + pqDevice.getIp() + File.separator + detail.getWavePath() + ".DAT" ;
+
+
+ log.info("本地磁盘波形文件路径----" + cfgPath);
+ InputStream cfgStream = getFileInputStreamByFilePath(cfgPath);
+ InputStream datStream = getFileInputStreamByFilePath(datPath);
+
+ if((Objects.nonNull(cfgStream)&&Objects.nonNull(datStream))){
+ // ========== 2. 高级算法更新原因/类型 ==========
+ if(dealFlag){
+ EventAnalysisDTO eventAnalysisDTO = null;
+ try {
+ eventAnalysisDTO = advancedAlgorithm(cfgStream, datStream);
+ log.info("暂降原因:"+eventAnalysisDTO.getCause()+"----暂降类型:"+eventAnalysisDTO.getType());
+ oracleRmpEventDetailPOMapper.updateCause(eventAnalysisDTO.getCause(),detail.getEventId());
+ oracleRmpEventDetailPOMapper.updateType(eventAnalysisDTO.getType(),detail.getEventId());
+ pqsEventLogService.lambdaUpdate().set(PqsEventLog::getDealflag,1).set(PqsEventLog::getUpdatetime,new Date()).eq(PqsEventLog::getEventdetailIndex,detail.getEventId()).update();
+ } catch (Exception e) {
+ pqsEventLogService.lambdaUpdate().set(PqsEventLog::getRemark,e.getMessage().length()>50?e.getMessage().substring(50):e.getMessage()).set(PqsEventLog::getUpdatetime,new Date()).eq(PqsEventLog::getEventdetailIndex,detail.getEventId()).update();
+
+ }
+
+ }
+ if(upLoadFlag){
+ // ========== 4. SFTP文件同步 ==========
+ try {
+ syncFileToSftp(pqDevice.getIp(), detail.getWavePath(), cfgPath, datPath);
+ pqsEventLogService.lambdaUpdate().set(PqsEventLog::getFileupflag,1).set(PqsEventLog::getUpdatetime,new Date()).eq(PqsEventLog::getEventdetailIndex,detail.getEventId()).update();
+
+ } catch (Exception e) {
+ pqsEventLogService.lambdaUpdate().set(PqsEventLog::getRemark,e.getMessage().length()>50?e.getMessage().substring(50):e.getMessage()).set(PqsEventLog::getUpdatetime,new Date()).eq(PqsEventLog::getEventdetailIndex,detail.getEventId()).update();
+
+ }
+
+ }
+
+ rmpEventDetailService.syncToMysql(detail.getEventId());
+
+ }
+
+ } catch (Exception e) {
+ log.error("异步处理失败 eventId:{}", detail.getEventId(), e);
+ }
+
+ }
+
+ // ==================
+ // 已修复:SFTP上传(无reset,无mark异常)
+ // ==================
+ private void syncFileToSftp(String deviceIp, String wavePath, String cfgFilePath, String datFilePath) throws Exception {
+ try (SftpClient client = new SftpClient() ) {
+ client.connect(targetConfig);
+ ChannelSftp channel = client.getChannel();
+
+ String remoteDir = targetConfig.getBasePath() + "/" + deviceIp;
+ client.createRemoteDirectory(remoteDir);
+
+ String remoteCfg = remoteDir + "/" + wavePath + ".CFG";
+ String remoteDat = remoteDir + "/" + wavePath + ".DAT";
+
+ channel.put(new FileInputStream(cfgFilePath), remoteCfg);
+ channel.put(new FileInputStream(datFilePath), remoteDat);
+ log.info("SFTP上传成功:{}", remoteCfg);
+
+ } catch (Exception e) {
+ log.error("SFTP上传失败", e);
+ throw new Exception("SFTP上传失败:"+(e.getMessage().length()>50?e.getMessage().substring(50):e.getMessage()));
+ }
+ }
+
+
+ // ==================
+ // 高级算法:更新 EVENTREASON / EVENTTYPE
+ // ==================
+ private EventAnalysisDTO advancedAlgorithm(InputStream cfgStream , InputStream datStream) throws Exception {
+ EventAnalysisDTO eventAnalysis = new EventAnalysisDTO();
+ log.info("执行高级算法:{}");
+ WaveDataDTO waveDataDTO = waveFileComponent.getComtradeNoAddPoints(cfgStream, datStream, 0);
+
+ List> listWaveData = waveDataDTO.getListWaveData();
+ // 暂降类型
+ // 创建数据结构
+ QvvrDLL.QvvrDataStruct typeDataStruct = new QvvrDLL.QvvrDataStruct();
+ System.out.println("初始化qvvrdll成功-----------");
+ typeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();
+ System.out.println("采样率-----------" + typeDataStruct.smp_rate);
+ typeDataStruct.smp_len = listWaveData.size();
+ System.out.println("波形长度-----------" + listWaveData.size());
+
+ // 获取ABC三相的瞬时数据
+ for (int i = 0; i < listWaveData.size(); i++) {
+ typeDataStruct.smp_va[i] = listWaveData.get(i).get(1);
+ typeDataStruct.smp_vb[i] = listWaveData.get(i).get(2);
+ typeDataStruct.smp_vc[i] = listWaveData.get(i).get(3);
+ }
+
+
+ // 执行算法分析 - 直接调用C DLL
+ try {
+ QvvrDLL.INSTANCE.qvvr_fun(typeDataStruct);
+
+ log.info("调用qvvrdll成功-----------");
+
+ if (typeDataStruct.evt_num > 0) {
+ // 全局比较找出最小三相电压特征值
+ float globalMinVoltage = Float.MAX_VALUE;
+ int globalFaultType = 10;
+ for (int i = 0; i < typeDataStruct.evt_num; i++) {
+ QvvrDLL.EventBuffer evt = typeDataStruct.evt_buf[i];
+ for (int j = 0; j < evt.u_min_num; j++) {
+ float u3min = evt.u3_min[j];
+ if (u3min < globalMinVoltage) {
+ globalMinVoltage = u3min;
+ globalFaultType = evt.qvvr_cata_type[j];
+ }
+ }
+ }
+ eventAnalysis.setType(globalFaultType);
+ } else {
+ eventAnalysis.setType(DataFeature.TYPE10);
+ }
+ System.out.println("结束qvvrdll方法调用-----------");
+ } catch (Exception e) {
+ eventAnalysis.setType(DataFeature.TYPE10);
+ eventAnalysis.setTypeFlag(0);
+ }
+
+
+ // 暂降原因JNA的方式
+ QvvrCauseDLL.QvvrDataStruct causeDataStruct = new QvvrCauseDLL.QvvrDataStruct();
+ causeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();
+ causeDataStruct.smp_len = listWaveData.size();
+ // 获取ABC三相的瞬时数据
+ for (int i = 0; i < listWaveData.size(); i++) {
+ causeDataStruct.smp_va[i] = listWaveData.get(i).get(1);
+ causeDataStruct.smp_vb[i] = listWaveData.get(i).get(2);
+ causeDataStruct.smp_vc[i] = listWaveData.get(i).get(3);
+ }
+ // 执行算法分析 - 直接调用C DLL
+ try {
+ QvvrCauseDLL.INSTANCE.qvvr_fun_cause(causeDataStruct);
+ eventAnalysis.setCause(causeDataStruct.cause);
+ if (causeDataStruct.no_cal != 0) {
+ eventAnalysis.setCauseFlag(0);
+ }
+ } catch (Exception e) {
+ eventAnalysis.setCause(DataFeature.CAUSE_TYPE0);
+ eventAnalysis.setCauseFlag(0);
+ }
+ System.out.println("暂降原因分析完毕===============");
+ System.out.println("cause:" + eventAnalysis);
+ return eventAnalysis;
+ }
+
+ public InputStream getFileInputStreamByFilePath(String filePath) {
+ File file = new File(filePath);
+ if (file.isFile() && file.exists()) {
+ InputStream inputStream;
+ try {
+ inputStream = Files.newInputStream(file.toPath());
+ if (inputStream.available() < 1) {
+ return null;
+ }
+ return inputStream;
+ } catch (IOException e) {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/OracleToMysqlServiceImpl.java b/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/OracleToMysqlServiceImpl.java
new file mode 100644
index 0000000..ac07ce3
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/OracleToMysqlServiceImpl.java
@@ -0,0 +1,147 @@
+package com.njcn.influx.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.njcn.influx.bo.po.*;
+import com.njcn.influx.mapper.OracleRmpEventDetailPOMapper;
+import com.njcn.influx.mapper.PqDeviceMapper;
+import com.njcn.influx.mapper.RmpEventDetailPOMapper;
+import com.njcn.influx.service.OracleToMysqlService;
+import com.njcn.influx.service.PqLineBakService;
+import com.njcn.influx.service.PqsEventLogService;
+import com.njcn.influx.service.RmpEventDetailService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.nio.file.Files;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Description:
+ * Date: 2026/04/20 上午 9:54【需求编号】
+ *
+ * @author clam
+ * @version V1.0.0
+ */
+@RequiredArgsConstructor
+@Service
+@Slf4j
+public class OracleToMysqlServiceImpl implements OracleToMysqlService {
+
+ private final RmpEventDetailService rmpEventDetailService;
+ private final OracleRmpEventDetailPOMapper oracleRmpEventDetailPOMapper;
+
+
+ private final PqsEventLogService pqsEventLogService;
+ private final EventAsyncService eventAsyncService;
+ @Value("${business.dealFlag:true}")
+ private Boolean dealFlag;
+ @Value("${business.upLoadFlag:true}")
+ private Boolean upLoadFlag;
+ @Override
+ public void OracleToMySqlJob(LocalDateTime start, LocalDateTime end) {
+ log.info("===== 定时扫描事件开始 =====");
+
+ List oracleRmpEventDetailPOList = oracleRmpEventDetailPOMapper.selectList(new LambdaQueryWrapper().between(OracleRmpEventDetailPO::getCreateTime,start,end));
+ for (OracleRmpEventDetailPO detail : oracleRmpEventDetailPOList) {
+ String eventId = detail.getEventId();
+
+ // 2. 判断是否已存在日志,避免重复
+ Integer cnt = pqsEventLogService.lambdaQuery().eq(PqsEventLog::getEventdetailIndex,eventId).count();
+
+ if (cnt == null ||cnt < 1){
+ // 3. 初始化日志:0未上传 0未计算
+ PqsEventLog pqsEventLog = new PqsEventLog();
+ pqsEventLog.setId(UUID.randomUUID().toString());
+ pqsEventLog.setEventdetailIndex(eventId);
+ //判断是否配置数据同步或者高级算法功能
+ if(dealFlag){
+ pqsEventLog.setDealflag(0);
+ }else {
+ pqsEventLog.setDealflag(2);
+ }
+ if(dealFlag){
+ pqsEventLog.setFileupflag(0);
+ }else {
+ pqsEventLog.setFileupflag(2);
+ }
+
+ pqsEventLog.setFileupflag(0);
+ pqsEventLog.setCreattime(new Date());
+ pqsEventLog.setUpdatetime(new Date());
+ pqsEventLogService.save(pqsEventLog);
+
+ String wavename = detail.getWavePath();
+
+ rmpEventDetailService.syncToMysql(eventId);
+
+ // ============================
+ // WAVENAME 为空:直接标记
+ // ============================
+ if (wavename == null || wavename.trim().isEmpty()) {
+
+ continue;
+ }
+
+ // ============================
+ // WAVENAME 非空:线程池异步处理
+ // ============================
+ eventAsyncService.asyncHandleEvent(detail);
+ }
+
+
+ }
+ }
+
+ @Override
+ public void retryAndCleanEvery10Min() {
+ log.info("===== 10分钟重试补偿 + 过期清理 =====");
+
+ // 1. 扫描未处理:fileup=0 deal=0
+ List todoList = pqsEventLogService.lambdaQuery().eq(PqsEventLog::getFileupflag, 0)
+ .or()
+ .eq(PqsEventLog::getDealflag, 0).list();
+
+ for (PqsEventLog log : todoList) {
+ String eventId = log.getEventdetailIndex();
+ Date createTime = log.getCreattime();
+ OracleRmpEventDetailPO oracleRmpEventDetailPO = oracleRmpEventDetailPOMapper.selectById(eventId);
+ // 查询最新WAVENAME
+
+
+ boolean isWaveEmpty = (oracleRmpEventDetailPO.getWavePath() == null || oracleRmpEventDetailPO.getWavePath().isEmpty());
+
+ // ======================
+ // 超过2天:置为2
+ // ======================
+ if (createTime != null && System.currentTimeMillis() - createTime.getTime() > 2 * 86400000L) {
+ if (isWaveEmpty) {
+ pqsEventLogService.lambdaUpdate().set(PqsEventLog::getDealflag,2).set(PqsEventLog::getFileupflag,2).set(PqsEventLog::getUpdatetime,new Date()).eq(PqsEventLog::getEventdetailIndex,eventId);
+ continue;
+ }
+ }
+
+ // ======================
+ // 有文件:重试异步处理
+ // ======================
+ if (!isWaveEmpty) {
+ eventAsyncService.asyncHandleEvent(oracleRmpEventDetailPO);
+ }
+ }
+
+ }
+
+}
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/PqsEventLogServiceImpl.java b/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/PqsEventLogServiceImpl.java
new file mode 100644
index 0000000..222aecc
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/PqsEventLogServiceImpl.java
@@ -0,0 +1,21 @@
+package com.njcn.influx.service.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+import com.njcn.influx.service.PqsEventLogService;
+import com.njcn.influx.bo.po.PqsEventLog;
+import com.njcn.influx.mapper.PqsEventLogMapper;
+import org.springframework.stereotype.Service;
+
+/**
+ * Description:
+ * Date: 2026/04/20 上午 10:23【需求编号】
+ *
+ * @author clam
+ * @version V1.0.0
+ */
+@Service
+@DS("master")
+public class PqsEventLogServiceImpl extends ServiceImpl implements PqsEventLogService {
+}
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/RmpEventDetailServiceImpl.java b/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/RmpEventDetailServiceImpl.java
new file mode 100644
index 0000000..7568396
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/service/impl/RmpEventDetailServiceImpl.java
@@ -0,0 +1,142 @@
+package com.njcn.influx.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.njcn.influx.bo.po.DictData;
+import com.njcn.influx.bo.po.OracleRmpEventDetailPO;
+import com.njcn.influx.bo.po.PqLineBak;
+import com.njcn.influx.bo.po.RmpEventDetailPO;
+import com.njcn.influx.mapper.OracleRmpEventDetailPOMapper;
+import com.njcn.influx.mapper.RmpEventDetailPOMapper;
+import com.njcn.influx.service.PqLineBakService;
+import com.njcn.influx.service.RmpEventDetailService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Description:
+ * Date: 2026/04/20 上午 11:29【需求编号】
+ *
+ * @author clam
+ * @version V1.0.0
+ */
+@Service
+@RequiredArgsConstructor
+public class RmpEventDetailServiceImpl extends ServiceImpl implements RmpEventDetailService {
+ private final OracleRmpEventDetailPOMapper oracleRmpEventDetailPOMapper;
+ private final PqLineBakService pqLineBakService;
+
+ @Override
+ public void syncToMysql(String eventId) {
+ OracleRmpEventDetailPO oracleDetail = oracleRmpEventDetailPOMapper.selectById(eventId);
+
+ List list = pqLineBakService.list();
+
+ //lineId:Oracle监测点ID id:Mysql监测点ID
+ Map oracleRelationMysql = list.stream().collect(Collectors.toMap(PqLineBak::getLineId, PqLineBak::getId));
+ //获取Oracle字典 暂降类型:12 暂降原因:13
+ List oracleReason= oracleRmpEventDetailPOMapper.selectByDicCodeList("暂降原因");
+ List oracleType= oracleRmpEventDetailPOMapper.selectByDicCodeList("暂降类型");
+ //获取Mysql字典
+ List eventType = this.getBaseMapper().selectByDicCodeList("Event_Statis");
+ List mysqlReason = this.getBaseMapper().selectByDicCodeList("Event_Reason");
+ List mysqlType = this.getBaseMapper().selectByDicCodeList("Event_Type");
+ //字典类型
+ Map mapReason = getRelationList(oracleReason, mysqlReason);
+ Map mapType = getRelationList(oracleType, mysqlType);
+
+ if(oracleRelationMysql.containsKey(oracleDetail.getMeasurementPointId())){
+ String mysqlLineID = oracleRelationMysql.get(oracleDetail.getMeasurementPointId());
+ RmpEventDetailPO po=new RmpEventDetailPO();
+ po.setEventId(eventId);
+ po.setMeasurementPointId(mysqlLineID);
+ po.setEventType(eventTypeId(oracleDetail.getEventType(),eventType));
+ po.setAdvanceReason(getDicId(oracleDetail.getAdvanceReason(),mapReason));
+ po.setAdvanceType(getDicId(oracleDetail.getAdvanceType(),mapType));
+ po.setEventassIndex(oracleDetail.getEventassIndex());
+ po.setDqTime(oracleDetail.getDqTime());
+ po.setDealTime(oracleDetail.getDealTime());
+ po.setNum(oracleDetail.getNum());
+ po.setFileFlag(oracleDetail.getFileFlag());
+ po.setDealFlag(oracleDetail.getDealFlag());
+
+ if(Objects.nonNull(oracleDetail.getFirstTime())) {
+ po.setFirstTime(oracleDetail.getFirstTime().plus(oracleDetail.getFirstMs().intValue(), ChronoUnit.MILLIS));
+ }
+ po.setFirstType(oracleDetail.getFirstType());
+ po.setFirstMs(oracleDetail.getFirstMs());
+ po.setEnergy(oracleDetail.getEnergy());
+ po.setSeverity(oracleDetail.getSeverity());
+ po.setSagsource(oracleDetail.getSagsource());
+ LocalDateTime startTime = oracleDetail.getStartTime();
+ LocalDateTime time = startTime.plus(oracleDetail.getMs(), ChronoUnit.MILLIS);
+ po.setStartTime(time);
+ po.setDuration(oracleDetail.getDuration().divide(BigDecimal.valueOf(1000)));
+ po.setFeatureAmplitude(oracleDetail.getFeatureAmplitude());
+ po.setPhase(oracleDetail.getPhase());
+ po.setEventDescribe(oracleDetail.getEventDescribe());
+ po.setWavePath(oracleDetail.getWavePath());
+ po.setTransientValue(oracleDetail.getTransientValue());
+ this.saveOrUpdate(po);
+ }
+ }
+
+ //获取暂降类型id
+ private String eventTypeId(String eventType, List eventTypeList){
+ String code="";
+ //事件类型(0:扰动,1:暂降,2:暂升,3:中断,4:其他,5:录波)
+ if("0".equals(eventType)){
+ code="Disturbance";
+ }
+ if("1".equals(eventType)){
+ code="Voltage_Dip";
+ }
+ if("2".equals(eventType)){
+ code="Voltage_Rise";
+ }
+ if("3".equals(eventType)){
+ code="Short_Interruptions";
+ }
+ if("4".equals(eventType)){
+ code="Other";
+ }
+ if("5".equals(eventType)){
+ code="Recording_Wave";
+ }
+ String finalCode = code;
+ DictData dictData = eventTypeList.stream().filter(x -> finalCode.equals(x.getCode())).findFirst().get();
+ if(ObjectUtil.isNotNull(dictData)){
+ return dictData.getId();
+ }
+ return "";
+ }
+
+ //类型匹配
+ private Map getRelationList(List oracleReason,List mysqlReason){
+ Map map=new HashMap<>();
+ for (DictData dictData : oracleReason) {
+ for (DictData data : mysqlReason) {
+ if(dictData.getAlgoDescribe().equals(data.getAlgoDescribe())){
+ map.put(dictData.getId(),data.getId());
+ }
+ }
+ }
+ return map;
+ }
+
+ private String getDicId(String dicReason,Map map){
+ if(map.containsKey(dicReason)){
+ return map.get(dicReason);
+ }
+ return "";
+ }
+}
diff --git a/influx-data/influx-source/src/main/java/com/njcn/influx/sftp/SftpClient.java b/influx-data/influx-source/src/main/java/com/njcn/influx/sftp/SftpClient.java
new file mode 100644
index 0000000..053f038
--- /dev/null
+++ b/influx-data/influx-source/src/main/java/com/njcn/influx/sftp/SftpClient.java
@@ -0,0 +1,126 @@
+package com.njcn.influx.sftp;
+
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.*;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.SftpException;
+import com.njcn.influx.config.TargetConfig;
+import lombok.Data;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.util.Vector;
+
+/**
+ * Description:
+ * Date: 2025/10/16 下午 3:00【需求编号】
+ *SFTP客户端实现
+ * @author clam
+ * @version V1.0.0
+ */
+@Service
+@Data
+public class SftpClient implements AutoCloseable{
+ private static final Logger logger = LoggerFactory.getLogger(SftpClient.class);
+
+ private JSch jsch;
+ private Session session;
+ private ChannelSftp channel;
+
+ public void connect(TargetConfig config) throws JSchException {
+ jsch = new JSch();
+
+ // 设置私钥(如果提供)
+ if (config.getPrivateKeyPath() != null && !config.getPrivateKeyPath().isEmpty()) {
+ jsch.addIdentity(config.getPrivateKeyPath());
+ }
+
+ session = jsch.getSession(config.getUsername(), config.getHost(), config.getPort());
+
+ // 设置密码(如果提供)
+ if (config.getPassword() != null && !config.getPassword().isEmpty()) {
+ session.setPassword(config.getPassword());
+ }
+
+ // 配置SSH连接
+ java.util.Properties sshConfig = new java.util.Properties();
+ sshConfig.put("StrictHostKeyChecking", "no");
+ session.setConfig(sshConfig);
+
+ session.connect(30000); // 30秒超时
+
+ // 打开SFTP通道
+ channel = (ChannelSftp) session.openChannel("sftp");
+ channel.connect(30000);
+ }
+ public void uploadFile(String localFile, String remotePath) throws SftpException {
+ File file = new File(localFile);
+ String remoteFile = ensureRemotePath(remotePath, file.getName());
+
+ // 确保远程目录存在
+ createRemoteDirectory(remotePath);
+
+ // 上传文件
+ channel.put(localFile, remoteFile);
+ }
+
+ public ChannelSftp.LsEntry getRemoteFileInfo(String remotePath) throws SftpException {
+ @SuppressWarnings("unchecked")
+ Vector files = channel.ls(remotePath);
+ if (files != null && !files.isEmpty()) {
+ return files.get(0);
+ }
+ return null;
+ }
+
+ private String ensureRemotePath(String remotePath, String fileName) {
+ if (remotePath.endsWith("/")) {
+ return remotePath + fileName;
+ } else {
+ return remotePath + "/" + fileName;
+ }
+ }
+
+ public void createRemoteDirectory(String remotePath) throws SftpException {
+
+ // 处理Windows路径分隔符
+ String normalizedPath = remotePath.replace("\\", "/");
+ // 去掉开头的/(避免根目录重复创建)
+ if (normalizedPath.startsWith("/")) {
+ normalizedPath = normalizedPath.substring(1);
+ }
+ String[] directories = normalizedPath.split("/");
+ StringBuilder currentPath = new StringBuilder();
+
+ // 递归创建多层目录
+ for (String dir : directories) {
+ if (dir.isEmpty()) {
+ continue;
+ }
+ currentPath.append("/").append(dir);
+ try {
+ channel.mkdir(currentPath.toString());
+ logger.debug("创建远程目录成功: {}", currentPath);
+ } catch (SftpException e) {
+ if (e.id != ChannelSftp.SSH_FX_FAILURE) {
+ logger.error("创建远程目录失败: {}", currentPath, e);
+ throw e;
+ } else {
+ logger.debug("远程目录已存在: {}", currentPath);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void close() {
+ if (channel != null) {
+ channel.disconnect();
+ }
+ if (session != null) {
+ session.disconnect();
+ }
+ }
+}
diff --git a/influx-data/influx-target/pom.xml b/influx-data/influx-target/pom.xml
index 70a6e63..066f923 100644
--- a/influx-data/influx-target/pom.xml
+++ b/influx-data/influx-target/pom.xml
@@ -50,6 +50,37 @@
influx-target
+
+
+ src/main/resources
+ true
+
+ *.yml
+
+
+
+ src/main/resources
+ false
+
+ *.dll
+ *.xlsx
+
+
+
+ src/main/resources
+ false
+
+ *.so
+
+
+
+ src/main/java
+ false
+
+ **/*.xml
+
+
+
org.springframework.boot
diff --git a/influx-data/influx-target/src/main/java/com/njcn/influx/controller/OracleToInfluxDBController.java b/influx-data/influx-target/src/main/java/com/njcn/influx/controller/OracleToInfluxDBController.java
index e972a88..6f57206 100644
--- a/influx-data/influx-target/src/main/java/com/njcn/influx/controller/OracleToInfluxDBController.java
+++ b/influx-data/influx-target/src/main/java/com/njcn/influx/controller/OracleToInfluxDBController.java
@@ -3,10 +3,7 @@ package com.njcn.influx.controller;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
-import com.njcn.influx.service.OracleEventDetailToMysqlService;
-import com.njcn.influx.service.OracleMonitorStatusToMysqlService;
-import com.njcn.influx.service.OracleToInfluxDBService;
-import com.njcn.influx.service.PqsOnlineratePOService;
+import com.njcn.influx.service.*;
import com.njcn.oracle.bo.param.DataAsynParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@@ -44,6 +41,7 @@ public class OracleToInfluxDBController {
private final OracleEventDetailToMysqlService oracleEventDetailToMysqlService;
private final OracleMonitorStatusToMysqlService oracleMonitorStatusToMysqlService;
+ private final OracleToMysqlService oracleToMysqlService;
@PostMapping("/dataSync")
@ApiOperation("数据同步")
@@ -119,6 +117,20 @@ public class OracleToInfluxDBController {
}
return true;
}
+
+ @GetMapping("/eventRecall")
+ @ApiOperation("eventDetail表数据同步补招接口")
+ public Boolean eventRecall(@RequestParam("startDateTime") String startDateTime,@RequestParam("endDateTime") String endDateTime) {
+ try {
+ LocalDateTime startDate = LocalDateTimeUtil.beginOfDay(LocalDateTimeUtil.parse(startDateTime, DatePattern.NORM_DATETIME_PATTERN));
+ LocalDateTime endDate = LocalDateTimeUtil.endOfDay(LocalDateTimeUtil.parse(endDateTime, DatePattern.NORM_DATETIME_PATTERN));
+ oracleToMysqlService.OracleToMySqlJob(startDate, endDate );
+
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return true;
+ }
@GetMapping("/mSync")
@ApiOperation("监测点信息同步")
public Boolean monitorTimeSync() {
diff --git a/influx-data/influx-target/src/main/java/com/njcn/influx/job/OracleToInfluxDBJob.java b/influx-data/influx-target/src/main/java/com/njcn/influx/job/OracleToInfluxDBJob.java
index 97b65d1..ebd4a0c 100644
--- a/influx-data/influx-target/src/main/java/com/njcn/influx/job/OracleToInfluxDBJob.java
+++ b/influx-data/influx-target/src/main/java/com/njcn/influx/job/OracleToInfluxDBJob.java
@@ -1,123 +1,125 @@
-package com.njcn.influx.job;
-
-import com.njcn.influx.bo.param.TableEnum;
-import com.njcn.influx.service.OracleEventDetailToMysqlService;
-import com.njcn.influx.service.OracleMonitorStatusToMysqlService;
-import com.njcn.influx.service.OracleToInfluxDBService;
-import com.njcn.influx.service.PqsOnlineratePOService;
-import com.njcn.oracle.bo.param.DataAsynParam;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.temporal.ChronoUnit;
-
-/**
- * Description:
- * Date: 2024/1/18 10:15【需求编号】
- *
- * @author clam
- * @version V1.0.0
- */
-@Component
-@EnableScheduling
-@RequiredArgsConstructor
-@Slf4j
-public class OracleToInfluxDBJob {
-
-
- private final OracleToInfluxDBService oracleToInfluxDBService;
-
- private final OracleEventDetailToMysqlService oracleEventDetailToMysqlService;
- private final OracleMonitorStatusToMysqlService oracleMonitorStatusToMysqlService;
-
- private final PqsOnlineratePOService pqsOnlineratePOService;
- /*@Scheduled(cron="0 5 0 * * ?")
- public void execute() {
- DataAsynParam dataAsynParam = new DataAsynParam();
- dataAsynParam.setStartTime(LocalDate.now().plusDays(-1));
- dataAsynParam.setEndTime(LocalDate.now().plusDays(-1));
- dataAsynParam.setTableNames(TableEnum.getExecutableTypes());
- dataAsynParam.setExcuteType(2);
- oracleToInfluxDBService.dataBacthSysc(dataAsynParam);
- }*/
-
- //每小时03分钟时执行上一个小时的数据同步
- //河北这边比较特殊,
- @Scheduled(cron="0 15 * * * ?")
- public void executeHours() {
- DataAsynParam dataAsynParam = new DataAsynParam();
- // 获取当前时间
- LocalDateTime now = LocalDateTime.now();
-
- // 减去一个小时
- LocalDateTime oneHourAgo = now.minusHours(2);
-
- // 将分钟和秒设置为0
- LocalDateTime result = oneHourAgo.truncatedTo(ChronoUnit.HOURS);
- // 加上59分钟59秒
- LocalDateTime modifiedResult = result.plusMinutes(59).plusSeconds(59);
- dataAsynParam.setStartDateTime(result);
- dataAsynParam.setEndDateTime(modifiedResult);
- dataAsynParam.setTableNames(TableEnum.getExecutableTypes());
- dataAsynParam.setExcuteType(2);
- oracleToInfluxDBService.hourseDataBacthSysc(dataAsynParam);
- }
- //每10分钟执行一次pqOnlinerate表同步
- @Scheduled(cron="0 0/10 * * * ?")
- public void pqOnlinerate() {
- DataAsynParam dataAsynParam = new DataAsynParam();
- // 获取当前时间
- LocalDateTime now = LocalDateTime.now();
- dataAsynParam.setStartDateTime(now);
- pqsOnlineratePOService.minutesDataBacthSysc(dataAsynParam);
- }
-
- /**
- * 每小时同步oracle数据库暂态事件
- * @date 2024/3/5
- */
- @Scheduled(cron="0 0/10 * * * ?")
- public void executeEvent() {
- // 获取当前时间
- LocalDateTime now = LocalDateTime.now();
- // 减去一个小时
- LocalDateTime oneHourAgo = now.minusHours(1);
- // 将分钟和秒设置为0
- LocalDateTime result = oneHourAgo.truncatedTo(ChronoUnit.HOURS);
- // 加上59分钟59秒
- LocalDateTime modifiedResult = result.plusMinutes(59).plusSeconds(59);
- oracleEventDetailToMysqlService.eventBatch(result,modifiedResult);
- }
-
- /**
- * 每天同步台账装置的运行状态,监测点的运行状态
- * @date 2024/3/5
- */
- @Scheduled(cron="0 0/10 * * * ?")
- public void synLedgerRunFlag() {
- oracleMonitorStatusToMysqlService.monitorStatusSync();
- }
-
- /**
- * 每天同步台账装置的最后更新时间
- * @date 2024/3/5
- */
- @Scheduled(cron="0 45 0 * * ?")
- public void synLedgerUpdateTime() {
- oracleMonitorStatusToMysqlService.devUpdateTimeSync();
- }
-
- /**
- * 每天同步台账监测点部分信息 仅数据中心使用
- * @date 2024/3/5
- */
- /* @Scheduled(cron="0 30 0 * * ?")
- public void synLedgerMonitor() {
- oracleMonitorStatusToMysqlService.monitorTimeSync();
- }*/
-}
+//package com.njcn.influx.job;
+//
+//import com.njcn.influx.bo.param.TableEnum;
+//import com.njcn.influx.service.OracleEventDetailToMysqlService;
+//import com.njcn.influx.service.OracleMonitorStatusToMysqlService;
+//import com.njcn.influx.service.OracleToInfluxDBService;
+//import com.njcn.influx.service.PqsOnlineratePOService;
+//import com.njcn.oracle.bo.param.DataAsynParam;
+//import lombok.RequiredArgsConstructor;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.scheduling.annotation.EnableScheduling;
+//import org.springframework.scheduling.annotation.Scheduled;
+//import org.springframework.stereotype.Component;
+//
+//import java.time.LocalDate;
+//import java.time.LocalDateTime;
+//import java.time.temporal.ChronoUnit;
+//
+///**
+// * Description:
+// * Date: 2024/1/18 10:15【需求编号】
+// *
+// * @author clam
+// * @version V1.0.0
+// */
+//@Component
+//@EnableScheduling
+//@RequiredArgsConstructor
+//@Slf4j
+//public class OracleToInfluxDBJob {
+//
+//
+// private final OracleToInfluxDBService oracleToInfluxDBService;
+//
+// private final OracleEventDetailToMysqlService oracleEventDetailToMysqlService;
+// private final OracleMonitorStatusToMysqlService oracleMonitorStatusToMysqlService;
+//
+// private final PqsOnlineratePOService pqsOnlineratePOService;
+// /*@Scheduled(cron="0 5 0 * * ?")
+// public void execute() {
+// DataAsynParam dataAsynParam = new DataAsynParam();
+// dataAsynParam.setStartTime(LocalDate.now().plusDays(-1));
+// dataAsynParam.setEndTime(LocalDate.now().plusDays(-1));
+// dataAsynParam.setTableNames(TableEnum.getExecutableTypes());
+// dataAsynParam.setExcuteType(2);
+// oracleToInfluxDBService.dataBacthSysc(dataAsynParam);
+// }*/
+//
+// //每小时03分钟时执行上一个小时的数据同步
+// //河北这边比较特殊,
+// @Scheduled(cron="0 15 * * * ?")
+// public void executeHours() {
+// DataAsynParam dataAsynParam = new DataAsynParam();
+// // 获取当前时间
+// LocalDateTime now = LocalDateTime.now();
+//
+// // 减去一个小时
+// LocalDateTime oneHourAgo = now.minusHours(2);
+//
+// // 将分钟和秒设置为0
+// LocalDateTime result = oneHourAgo.truncatedTo(ChronoUnit.HOURS);
+// // 加上59分钟59秒
+// LocalDateTime modifiedResult = result.plusMinutes(59).plusSeconds(59);
+// dataAsynParam.setStartDateTime(result);
+// dataAsynParam.setEndDateTime(modifiedResult);
+// dataAsynParam.setTableNames(TableEnum.getExecutableTypes());
+// dataAsynParam.setExcuteType(2);
+// oracleToInfluxDBService.hourseDataBacthSysc(dataAsynParam);
+// }
+// //每10分钟执行一次pqOnlinerate表同步
+//// @Scheduled(cron="0 0/10 * * * ?")
+//// public void pqOnlinerate() {
+//// DataAsynParam dataAsynParam = new DataAsynParam();
+//// // 获取当前时间
+//// LocalDateTime now = LocalDateTime.now();
+//// dataAsynParam.setStartDateTime(now);
+//// pqsOnlineratePOService.minutesDataBacthSysc(dataAsynParam);
+//// }
+//
+// /**
+// * 每小时同步oracle数据库暂态事件
+// * @date 2024/3/5
+// */
+// @Scheduled(cron="0 0/10 * * * ?")
+// public void executeEvent() {
+// // 获取当前时间
+// LocalDateTime now = LocalDateTime.now();
+// // 减去一个小时
+// LocalDateTime oneHourAgo = now.minusHours(1);
+// // 将分钟和秒设置为0
+// LocalDateTime result = oneHourAgo.truncatedTo(ChronoUnit.HOURS);
+// // 加上59分钟59秒
+// LocalDateTime modifiedResult = result.plusMinutes(59).plusSeconds(59);
+// oracleEventDetailToMysqlService.eventBatch(result,modifiedResult);
+// }
+//
+// /**
+// * 每天同步台账装置的运行状态,监测点的运行状态
+// * @date 2024/3/5
+// */
+// @Scheduled(cron="0 0/10 * * * ?")
+// public void synLedgerRunFlag() {
+// oracleMonitorStatusToMysqlService.monitorStatusSync();
+// }
+//
+// /**
+// * 每天同步台账装置的最后更新时间
+// * @date 2024/3/5
+// */
+// @Scheduled(cron="0 45 0 * * ?")
+// public void synLedgerUpdateTime() {
+// oracleMonitorStatusToMysqlService.devUpdateTimeSync();
+// }
+//
+// /**
+// * 每天同步台账监测点部分信息 仅数据中心使用
+// * @date 2024/3/5
+// */
+// /* @Scheduled(cron="0 30 0 * * ?")
+// public void synLedgerMonitor() {
+// oracleMonitorStatusToMysqlService.monitorTimeSync();
+// }*/
+//}
+//
+//
diff --git a/influx-data/influx-target/src/main/java/com/njcn/influx/job/OracleToMySqlJob.java b/influx-data/influx-target/src/main/java/com/njcn/influx/job/OracleToMySqlJob.java
new file mode 100644
index 0000000..a2bd60d
--- /dev/null
+++ b/influx-data/influx-target/src/main/java/com/njcn/influx/job/OracleToMySqlJob.java
@@ -0,0 +1,50 @@
+package com.njcn.influx.job;
+
+
+import com.njcn.influx.service.OracleToMysqlService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+
+
+/**
+ * Description:
+ * Date: 2026/04/20 上午 9:44【需求编号】
+ *
+ * @author clam
+ * @version V1.0.0
+ */
+@Component
+@EnableScheduling
+@RequiredArgsConstructor
+@Slf4j
+public class OracleToMySqlJob {
+
+ private final OracleToMysqlService oracleToMysqlService;
+
+
+ @Scheduled(cron = "${business.executeEventExpression}")
+ public void executeEvent() {
+ // 获取当前时间
+ LocalDateTime now = LocalDateTime.now();
+ // 减去一个小时
+ LocalDateTime oneHourAgo = now.minusHours(3);
+
+ oracleToMysqlService.OracleToMySqlJob(oneHourAgo,now);
+ }
+
+
+ // ==============================
+ // 每10分钟:重试 + 2天过期处理
+ // ==============================
+ @Scheduled(cron = "${business.retryAndCleanEvery10Min}")
+ public void retryAndCleanEvery10Min() {
+
+ oracleToMysqlService.retryAndCleanEvery10Min();;
+ }
+}
diff --git a/influx-data/influx-target/src/main/resources/application-bd.yml b/influx-data/influx-target/src/main/resources/application-bd.yml
new file mode 100644
index 0000000..72a79af
--- /dev/null
+++ b/influx-data/influx-target/src/main/resources/application-bd.yml
@@ -0,0 +1,130 @@
+
+business:
+ #分片次数,一定为24的约数,1 2 3 4 6 8 12 24
+ slice: 4
+ # 0.pq 1.pms
+ type: 0
+ #处理波形数据位置
+ wavePath: D:\Comtrade
+ retryAndCleanEvery10Min: 0 */10 * * * ?
+ executeEventExpression: 0 */3 * * * ?
+server:
+ port: 8093
+ #springsecurity默认过期时间30m
+ servlet:
+ session:
+ timeout: 1440m
+ target:
+ host: 192.168.1.67
+ port: 22
+ username: root
+ password: 'dnzl@#001'
+ basePath: /home/hndnzl
+ privateKeyPath:
+
+spring:
+ security:
+ user:
+ name: data_njcn
+ password: dnzl@#002
+ #influxDB内容配置
+ influx:
+ url: http://192.168.1.103:18086
+ user: admin
+ password: 123456
+ database: pqsbase_wx
+ mapper-location: com.njcn.influx.imapper
+ application:
+ name: oracle-influx
+ autoconfigure:
+ exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
+ datasource:
+ dynamic:
+ druid:
+ initial-size: 10
+ # 初始化大小,最小,最大
+ min-idle: 20
+ maxActive: 500
+ # 配置获取连接等待超时的时间
+ maxWait: 60000
+ # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+ timeBetweenEvictionRunsMillis: 60000
+ # 配置一个连接在池中最小生存的时间,单位是毫秒
+ minEvictableIdleTimeMillis: 300000
+ testWhileIdle: true
+ testOnBorrow: true
+ validation-query: SELECT 1 from dual
+ testOnReturn: false
+ # 打开PSCache,并且指定每个连接上PSCache的大小
+ poolPreparedStatements: true
+ maxPoolPreparedStatementPerConnectionSize: 20
+ filters: stat,wall
+ filter:
+ wall:
+ config:
+ multi-statement-allow: true
+ none-base-statement-allow: true
+ enabled: true
+ # 配置DruidStatFilter
+ web-stat-filter:
+ enabled: true
+ url-pattern: "/*"
+ exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
+ # 配置DruidStatViewServlet
+ stat-view-servlet:
+ enabled: true
+ url-pattern: "/druid/*"
+ # IP白名单(没有配置或者为空,则允许所有访问)
+ allow: #127.0.0.1,192.168.163.1
+ # IP黑名单 (存在共同时,deny优先于allow)
+ deny: #192.168.1.73
+ # 禁用HTML页面上的“Reset All”功能
+ reset-enable: false
+ # 登录名
+ login-username: admin
+ # 登录密码
+ login-password: njcnpqs
+ query-timeout: 36000
+ primary: master
+ strict: false
+ datasource:
+ master:
+ url: jdbc:oracle:thin:@127.0.0.1:1521:pqsbase
+ username: pqsadmin
+ password: '@#001njcnpqs'
+ driver-class-name: oracle.jdbc.driver.OracleDriver
+ target:
+ url: jdbc:mysql://192.168.1.103:13307/pqsinfo_hn?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=CTT
+ username: root
+ password: njcnpqs
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ redis:
+ database: 15
+ host: 192.168.1.103
+ port: 16379
+ password: njcnpqs
+ timeout: 5000
+ lettuce:
+ pool:
+ max-active: 8
+ max-wait: -1
+ max-idle: 8
+ min-idle: 0
+ #不做限制的参数配置
+#mybatis配置信息
+mybatis-plus:
+ #别名扫描
+ type-aliases-package: com.njcn.oracle.bo
+ mapper-locations: classpath*:com/njcn/**/mapping/*.xml
+ configuration:
+ #驼峰命名
+ map-underscore-to-camel-case: true
+ #配置sql日志输出
+ # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+ #关闭日志输出
+ log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+ global-config:
+ db-config:
+ #指定主键生成策略
+ id-type: assign_uuid
+
diff --git a/influx-data/influx-target/src/main/resources/application-hn.yml b/influx-data/influx-target/src/main/resources/application-hn.yml
new file mode 100644
index 0000000..16488df
--- /dev/null
+++ b/influx-data/influx-target/src/main/resources/application-hn.yml
@@ -0,0 +1,130 @@
+
+business:
+ #分片次数,一定为24的约数,1 2 3 4 6 8 12 24
+ slice: 4
+ # 0.pq 1.pms
+ type: 0
+ #处理波形数据位置
+ wavePath: F:\Comtrade
+ retryAndCleanEvery10Min: 0 */10 * * * ?
+ executeEventExpression: 0 */3 * * * ?
+server:
+ port: 8093
+ #springsecurity默认过期时间30m
+ servlet:
+ session:
+ timeout: 1440m
+ target:
+ host: 10.95.53.49
+ port: 9389
+ username: hndnzl
+ password: '@#001njcnPQS'
+ basePath: /home/hndnzl
+ privateKeyPath:
+
+spring:
+ security:
+ user:
+ name: data_njcn
+ password: dnzl@#002
+ #influxDB内容配置
+ influx:
+ url: http://10.95.53.49:8086
+ user: pqsdata
+ password: njcn@#001
+ database: pqsbase
+ mapper-location: com.njcn.influx.imapper
+ application:
+ name: oracle-influx
+ autoconfigure:
+ exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
+ datasource:
+ dynamic:
+ druid:
+ initial-size: 10
+ # 初始化大小,最小,最大
+ min-idle: 20
+ maxActive: 500
+ # 配置获取连接等待超时的时间
+ maxWait: 60000
+ # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+ timeBetweenEvictionRunsMillis: 60000
+ # 配置一个连接在池中最小生存的时间,单位是毫秒
+ minEvictableIdleTimeMillis: 300000
+ testWhileIdle: true
+ testOnBorrow: true
+ validation-query: SELECT 1 from dual
+ testOnReturn: false
+ # 打开PSCache,并且指定每个连接上PSCache的大小
+ poolPreparedStatements: true
+ maxPoolPreparedStatementPerConnectionSize: 20
+ filters: stat,wall
+ filter:
+ wall:
+ config:
+ multi-statement-allow: true
+ none-base-statement-allow: true
+ enabled: true
+ # 配置DruidStatFilter
+ web-stat-filter:
+ enabled: true
+ url-pattern: "/*"
+ exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
+ # 配置DruidStatViewServlet
+ stat-view-servlet:
+ enabled: true
+ url-pattern: "/druid/*"
+ # IP白名单(没有配置或者为空,则允许所有访问)
+ allow: #127.0.0.1,192.168.163.1
+ # IP黑名单 (存在共同时,deny优先于allow)
+ deny: #192.168.1.73
+ # 禁用HTML页面上的“Reset All”功能
+ reset-enable: false
+ # 登录名
+ login-username: admin
+ # 登录密码
+ login-password: njcnpqs
+ query-timeout: 36000
+ primary: master
+ strict: false
+ datasource:
+ master:
+ url: jdbc:oracle:thin:@10.95.53.40:11521:pqsbase
+ username: pqsadmin
+ password: "@#001njcnpqs"
+ driver-class-name: oracle.jdbc.driver.OracleDriver
+ target:
+ url: jdbc:mysql://10.95.53.49:13306/pqsinfo_hn?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=CTT
+ username: root
+ password: njcnpqs
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ redis:
+ database: 15
+ host: 10.95.53.49
+ port: 16379
+ password: njcnpqs
+ timeout: 5000
+ lettuce:
+ pool:
+ max-active: 8
+ max-wait: -1
+ max-idle: 8
+ min-idle: 0
+ #不做限制的参数配置
+#mybatis配置信息
+mybatis-plus:
+ #别名扫描
+ type-aliases-package: com.njcn.oracle.bo
+ mapper-locations: classpath*:com/njcn/**/mapping/*.xml
+ configuration:
+ #驼峰命名
+ map-underscore-to-camel-case: true
+ #配置sql日志输出
+ # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+ #关闭日志输出
+ log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+ global-config:
+ db-config:
+ #指定主键生成策略
+ id-type: assign_uuid
+
diff --git a/influx-data/influx-target/src/main/resources/application.yml b/influx-data/influx-target/src/main/resources/application.yml
index faed30b..dd97f41 100644
--- a/influx-data/influx-target/src/main/resources/application.yml
+++ b/influx-data/influx-target/src/main/resources/application.yml
@@ -1,119 +1,3 @@
-
-business:
- #分片次数,一定为24的约数,1 2 3 4 6 8 12 24
- slice: 4
- # 0.pq 1.pms
- type: 0
-server:
- port: 8090
- #springsecurity默认过期时间30m
- servlet:
- session:
- timeout: 1440m
-
spring:
- security:
- user:
- name: data_njcn
- password: dnzl@#002
- #influxDB内容配置
- influx:
- url: http://192.168.1.102:8086
- user: admin
- password: 123456
- database: pqsbase_sjzx
- mapper-location: com.njcn.influx.imapper
- application:
- name: oracle-influx
- autoconfigure:
- exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
- datasource:
- dynamic:
- druid:
- initial-size: 10
- # 初始化大小,最小,最大
- min-idle: 20
- maxActive: 500
- # 配置获取连接等待超时的时间
- maxWait: 60000
- # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
- timeBetweenEvictionRunsMillis: 60000
- # 配置一个连接在池中最小生存的时间,单位是毫秒
- minEvictableIdleTimeMillis: 300000
- testWhileIdle: true
- testOnBorrow: true
- validation-query: SELECT 1 from dual
- testOnReturn: false
- # 打开PSCache,并且指定每个连接上PSCache的大小
- poolPreparedStatements: true
- maxPoolPreparedStatementPerConnectionSize: 20
- filters: stat,wall
- filter:
- wall:
- config:
- multi-statement-allow: true
- none-base-statement-allow: true
- enabled: true
- # 配置DruidStatFilter
- web-stat-filter:
- enabled: true
- url-pattern: "/*"
- exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
- # 配置DruidStatViewServlet
- stat-view-servlet:
- enabled: true
- url-pattern: "/druid/*"
- # IP白名单(没有配置或者为空,则允许所有访问)
- allow: #127.0.0.1,192.168.163.1
- # IP黑名单 (存在共同时,deny优先于allow)
- deny: #192.168.1.73
- # 禁用HTML页面上的“Reset All”功能
- reset-enable: false
- # 登录名
- login-username: admin
- # 登录密码
- login-password: njcnpqs
- query-timeout: 36000
- primary: master
- strict: false
- datasource:
- master:
- url: jdbc:oracle:thin:@192.168.1.101:1521:pqsbase
- username: pqsadmin
- password: Pqsadmin123
- driver-class-name: oracle.jdbc.driver.OracleDriver
- target:
- url: jdbc:mysql://192.168.1.102:13306/pqsinfo?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=CTT
- username: root
- password: njcnpqs
- driver-class-name: com.mysql.cj.jdbc.Driver
- redis:
- database: 15
- host: 192.168.1.22
- port: 16379
- password: njcnpqs
- timeout: 5000
- lettuce:
- pool:
- max-active: 8
- max-wait: -1
- max-idle: 8
- min-idle: 0
- #不做限制的参数配置
-#mybatis配置信息
-mybatis-plus:
- #别名扫描
- type-aliases-package: com.njcn.oracle.bo
- mapper-locations: classpath*:com/njcn/**/mapping/*.xml
- configuration:
- #驼峰命名
- map-underscore-to-camel-case: true
- #配置sql日志输出
- # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- #关闭日志输出
- log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
- global-config:
- db-config:
- #指定主键生成策略
- id-type: assign_uuid
-
+ profiles:
+ active: bd
\ No newline at end of file
diff --git a/influx-data/influx-target/src/main/resources/application_hb.yml b/influx-data/influx-target/src/main/resources/application_hb.yml
index 057a2ab..c10dbdf 100644
--- a/influx-data/influx-target/src/main/resources/application_hb.yml
+++ b/influx-data/influx-target/src/main/resources/application_hb.yml
@@ -1,102 +1,102 @@
-#文件位置配置
-business:
- #分片次数,一定为24的约数,1 2 3 4 6 8 12 24
- slice: 4
- # 0.pq 1.pms
- type: 1
-
-server:
- port: 8090
-spring:
- security:
- user:
- name: data_njcn
- password: dnzl@#002
- #influxDB内容配置
- influx:
- url: http://25.36.232.36:8086
- user: admin
- password: admin
- database: pqsbase_hbcs
- mapper-location: com.njcn.influx.imapper
- application:
- name: oracle-influx
- autoconfigure:
- exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
- datasource:
- dynamic:
- druid:
- initial-size: 10
- # 初始化大小,最小,最大
- min-idle: 20
- maxActive: 500
- # 配置获取连接等待超时的时间
- maxWait: 60000
- # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
- timeBetweenEvictionRunsMillis: 60000
- # 配置一个连接在池中最小生存的时间,单位是毫秒
- minEvictableIdleTimeMillis: 300000
- testWhileIdle: true
- testOnBorrow: true
- validation-query: SELECT 1 from dual
- testOnReturn: false
- # 打开PSCache,并且指定每个连接上PSCache的大小
- poolPreparedStatements: true
- maxPoolPreparedStatementPerConnectionSize: 20
- filters: stat,wall
- filter:
- wall:
- config:
- multi-statement-allow: true
- none-base-statement-allow: true
- enabled: true
- # 配置DruidStatFilter
- web-stat-filter:
- enabled: true
- url-pattern: "/*"
- exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
- # 配置DruidStatViewServlet
- stat-view-servlet:
- enabled: true
- url-pattern: "/druid/*"
- # IP白名单(没有配置或者为空,则允许所有访问)
- allow: #127.0.0.1,192.168.163.1
- # IP黑名单 (存在共同时,deny优先于allow)
- deny: #192.168.1.73
- # 禁用HTML页面上的“Reset All”功能
- reset-enable: false
- # 登录名
- login-username: admin
- # 登录密码
- login-password: njcnpqs
- query-timeout: 36000
- primary: master
- strict: false
- datasource:
- master:
- url: jdbc:oracle:thin:@10.122.32.73:11521/dwxb
- username: pqsadmin
- password: pqsadmin_123
- driver-class-name: oracle.jdbc.driver.OracleDriver
- target:
- url: jdbc:mysql://25.36.232.37:13306/pmsinfo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT
- username: root
- password: Huawei12#
- driver-class-name: com.mysql.cj.jdbc.Driver
-#mybatis配置信息
-mybatis-plus:
- #别名扫描
- type-aliases-package: com.njcn.oracle.bo
- mapper-locations: classpath*:com/njcn/**/mapping/*.xml
- configuration:
- #驼峰命名
- map-underscore-to-camel-case: true
- #配置sql日志输出
- # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- #关闭日志输出
- log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
- global-config:
- db-config:
- #指定主键生成策略
- id-type: assign_uuid
-
+##文件位置配置
+#business:
+# #分片次数,一定为24的约数,1 2 3 4 6 8 12 24
+# slice: 4
+# # 0.pq 1.pms
+# type: 1
+#
+#server:
+# port: 8090
+#spring:
+# security:
+# user:
+# name: data_njcn
+# password: dnzl@#002
+# #influxDB内容配置
+# influx:
+# url: http://25.36.232.36:8086
+# user: admin
+# password: admin
+# database: pqsbase_hbcs
+# mapper-location: com.njcn.influx.imapper
+# application:
+# name: oracle-influx
+# autoconfigure:
+# exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
+# datasource:
+# dynamic:
+# druid:
+# initial-size: 10
+# # 初始化大小,最小,最大
+# min-idle: 20
+# maxActive: 500
+# # 配置获取连接等待超时的时间
+# maxWait: 60000
+# # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+# timeBetweenEvictionRunsMillis: 60000
+# # 配置一个连接在池中最小生存的时间,单位是毫秒
+# minEvictableIdleTimeMillis: 300000
+# testWhileIdle: true
+# testOnBorrow: true
+# validation-query: SELECT 1 from dual
+# testOnReturn: false
+# # 打开PSCache,并且指定每个连接上PSCache的大小
+# poolPreparedStatements: true
+# maxPoolPreparedStatementPerConnectionSize: 20
+# filters: stat,wall
+# filter:
+# wall:
+# config:
+# multi-statement-allow: true
+# none-base-statement-allow: true
+# enabled: true
+# # 配置DruidStatFilter
+# web-stat-filter:
+# enabled: true
+# url-pattern: "/*"
+# exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
+# # 配置DruidStatViewServlet
+# stat-view-servlet:
+# enabled: true
+# url-pattern: "/druid/*"
+# # IP白名单(没有配置或者为空,则允许所有访问)
+# allow: #127.0.0.1,192.168.163.1
+# # IP黑名单 (存在共同时,deny优先于allow)
+# deny: #192.168.1.73
+# # 禁用HTML页面上的“Reset All”功能
+# reset-enable: false
+# # 登录名
+# login-username: admin
+# # 登录密码
+# login-password: njcnpqs
+# query-timeout: 36000
+# primary: master
+# strict: false
+# datasource:
+# master:
+# url: jdbc:oracle:thin:@10.122.32.73:11521/dwxb
+# username: pqsadmin
+# password: pqsadmin_123
+# driver-class-name: oracle.jdbc.driver.OracleDriver
+# target:
+# url: jdbc:mysql://25.36.232.37:13306/pmsinfo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT
+# username: root
+# password: Huawei12#
+# driver-class-name: com.mysql.cj.jdbc.Driver
+##mybatis配置信息
+#mybatis-plus:
+# #别名扫描
+# type-aliases-package: com.njcn.oracle.bo
+# mapper-locations: classpath*:com/njcn/**/mapping/*.xml
+# configuration:
+# #驼峰命名
+# map-underscore-to-camel-case: true
+# #配置sql日志输出
+# # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+# #关闭日志输出
+# log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+# global-config:
+# db-config:
+# #指定主键生成策略
+# id-type: assign_uuid
+#
diff --git a/influx-data/influx-target/src/main/resources/application_sjzx.yml b/influx-data/influx-target/src/main/resources/application_sjzx.yml
index e04c7dc..ca9a589 100644
--- a/influx-data/influx-target/src/main/resources/application_sjzx.yml
+++ b/influx-data/influx-target/src/main/resources/application_sjzx.yml
@@ -1,101 +1,101 @@
-#文件位置配置
-business:
-#分片次数,一定为24的约数,1 2 3 4 6 8 12 24
- slice: 4
- # 0.pq 1.pms
- type: 0
-server:
- port: 8090
-spring:
- security:
- user:
- name: data_njcn
- password: dnzl@#002
- #influxDB内容配置
- influx:
- url: http://192.168.1.102:8086
- user: admin
- password: 123456
- database: pqsbase_sjzx
- mapper-location: com.njcn.influx.imapper
- application:
- name: oracle-influx
- autoconfigure:
- exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
- datasource:
- dynamic:
- druid:
- initial-size: 10
- # 初始化大小,最小,最大
- min-idle: 20
- maxActive: 500
- # 配置获取连接等待超时的时间
- maxWait: 60000
- # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
- timeBetweenEvictionRunsMillis: 60000
- # 配置一个连接在池中最小生存的时间,单位是毫秒
- minEvictableIdleTimeMillis: 300000
- testWhileIdle: true
- testOnBorrow: true
- validation-query: SELECT 1 from dual
- testOnReturn: false
- # 打开PSCache,并且指定每个连接上PSCache的大小
- poolPreparedStatements: true
- maxPoolPreparedStatementPerConnectionSize: 20
- filters: stat,wall
- filter:
- wall:
- config:
- multi-statement-allow: true
- none-base-statement-allow: true
- enabled: true
- # 配置DruidStatFilter
- web-stat-filter:
- enabled: true
- url-pattern: "/*"
- exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
- # 配置DruidStatViewServlet
- stat-view-servlet:
- enabled: true
- url-pattern: "/druid/*"
- # IP白名单(没有配置或者为空,则允许所有访问)
- allow: #127.0.0.1,192.168.163.1
- # IP黑名单 (存在共同时,deny优先于allow)
- deny: #192.168.1.73
- # 禁用HTML页面上的“Reset All”功能
- reset-enable: false
- # 登录名
- login-username: admin
- # 登录密码
- login-password: njcnpqs
- query-timeout: 36000
- primary: master
- strict: false
- datasource:
- master:
- url: jdbc:oracle:thin:@192.168.1.101:1521:pqsbase
- username: pqsadmin
- password: Pqsadmin123
- driver-class-name: oracle.jdbc.driver.OracleDriver
- target:
- url: jdbc:mysql://192.168.1.102:13306/pqsinfo?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=CTT
- username: root
- password: njcnpqs
- driver-class-name: com.mysql.cj.jdbc.Driver
-#mybatis配置信息
-mybatis-plus:
- #别名扫描
- type-aliases-package: com.njcn.oracle.bo
- mapper-locations: classpath*:com/njcn/**/mapping/*.xml
- configuration:
- #驼峰命名
- map-underscore-to-camel-case: true
- #配置sql日志输出
-# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- #关闭日志输出
- log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
- global-config:
- db-config:
- #指定主键生成策略
- id-type: assign_uuid
-
+##文件位置配置
+#business:
+##分片次数,一定为24的约数,1 2 3 4 6 8 12 24
+# slice: 4
+# # 0.pq 1.pms
+# type: 0
+#server:
+# port: 8090
+#spring:
+# security:
+# user:
+# name: data_njcn
+# password: dnzl@#002
+# #influxDB内容配置
+# influx:
+# url: http://192.168.1.102:8086
+# user: admin
+# password: 123456
+# database: pqsbase_sjzx
+# mapper-location: com.njcn.influx.imapper
+# application:
+# name: oracle-influx
+# autoconfigure:
+# exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
+# datasource:
+# dynamic:
+# druid:
+# initial-size: 10
+# # 初始化大小,最小,最大
+# min-idle: 20
+# maxActive: 500
+# # 配置获取连接等待超时的时间
+# maxWait: 60000
+# # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+# timeBetweenEvictionRunsMillis: 60000
+# # 配置一个连接在池中最小生存的时间,单位是毫秒
+# minEvictableIdleTimeMillis: 300000
+# testWhileIdle: true
+# testOnBorrow: true
+# validation-query: SELECT 1 from dual
+# testOnReturn: false
+# # 打开PSCache,并且指定每个连接上PSCache的大小
+# poolPreparedStatements: true
+# maxPoolPreparedStatementPerConnectionSize: 20
+# filters: stat,wall
+# filter:
+# wall:
+# config:
+# multi-statement-allow: true
+# none-base-statement-allow: true
+# enabled: true
+# # 配置DruidStatFilter
+# web-stat-filter:
+# enabled: true
+# url-pattern: "/*"
+# exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
+# # 配置DruidStatViewServlet
+# stat-view-servlet:
+# enabled: true
+# url-pattern: "/druid/*"
+# # IP白名单(没有配置或者为空,则允许所有访问)
+# allow: #127.0.0.1,192.168.163.1
+# # IP黑名单 (存在共同时,deny优先于allow)
+# deny: #192.168.1.73
+# # 禁用HTML页面上的“Reset All”功能
+# reset-enable: false
+# # 登录名
+# login-username: admin
+# # 登录密码
+# login-password: njcnpqs
+# query-timeout: 36000
+# primary: master
+# strict: false
+# datasource:
+# master:
+# url: jdbc:oracle:thin:@192.168.1.101:1521:pqsbase
+# username: pqsadmin
+# password: Pqsadmin123
+# driver-class-name: oracle.jdbc.driver.OracleDriver
+# target:
+# url: jdbc:mysql://192.168.1.102:13306/pqsinfo?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=CTT
+# username: root
+# password: njcnpqs
+# driver-class-name: com.mysql.cj.jdbc.Driver
+##mybatis配置信息
+#mybatis-plus:
+# #别名扫描
+# type-aliases-package: com.njcn.oracle.bo
+# mapper-locations: classpath*:com/njcn/**/mapping/*.xml
+# configuration:
+# #驼峰命名
+# map-underscore-to-camel-case: true
+# #配置sql日志输出
+## log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+# #关闭日志输出
+# log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+# global-config:
+# db-config:
+# #指定主键生成策略
+# id-type: assign_uuid
+#
diff --git a/influx-data/influx-target/src/main/resources/libqvvr_balance_dll.so b/influx-data/influx-target/src/main/resources/libqvvr_balance_dll.so
new file mode 100644
index 0000000000000000000000000000000000000000..b3058734d53dfb944691677be16c63d14e9914e4
GIT binary patch
literal 114976
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