feat(test): 添加谐波分析测试功能并重构设备测试类

- 添加新的BaseJunitTest测试类用于谐波分析功能测试
- 在AppTest中添加压降落点区域判定算法实现
- 重构AppTest类的依赖注入方式,从构造器注入改为字段注入
- 添加多个InfluxDB数据写入测试方法用于设备通信状态记录
- 实现完整的谐波报表生成功能包括Excel导出和数据处理逻辑
- 添加设备单位数据映射和统计方法用于报表展示
- 实现自定义报表模板解析和数据填充功能
- 添加数据库查询优化和并发处理支持
This commit is contained in:
xy
2026-06-30 13:38:43 +08:00
parent d84d91a241
commit 9f5c273180
8 changed files with 1506 additions and 31 deletions

View File

@@ -8,7 +8,7 @@ microservice:
gateway: gateway:
url: @gateway.url@ url: @gateway.url@
server: server:
port: 10220 port: 20220
#feign接口开启服务熔断降级处理 #feign接口开启服务熔断降级处理
feign: feign:
sentinel: sentinel:
@@ -45,8 +45,8 @@ spring:
#项目日志的配置 #项目日志的配置
logging: logging:
# config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&username=@nacos.username@&password=@nacos.password@&group=DEFAULT_GROUP&dataId=logback.xml config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&username=@nacos.username@&password=@nacos.password@&group=DEFAULT_GROUP&dataId=logback.xml
config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&group=DEFAULT_GROUP&dataId=logback.xml # config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&group=DEFAULT_GROUP&dataId=logback.xml
level: level:
root: warn root: warn

View File

@@ -3,12 +3,12 @@ package com.njcn;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import com.njcn.csdevice.CsDeviceBootApplication; import com.njcn.csdevice.CsDeviceBootApplication;
import com.njcn.csdevice.pojo.dto.PqsCommunicateDto; import com.njcn.csdevice.pojo.dto.PqsCommunicateDto;
import com.njcn.csdevice.pojo.po.CsEquipmentDeliveryPO; import com.njcn.csdevice.service.DeviceFtpService;
import com.njcn.csdevice.service.*; import com.njcn.csdevice.service.ICsCommunicateService;
import com.njcn.influx.pojo.po.PqsCommunicate; import com.njcn.csdevice.service.IRStatIntegrityDService;
import com.njcn.influx.query.InfluxQueryWrapper; import com.njcn.csdevice.service.IRStatOnlineRateDService;
import com.njcn.influx.utils.InfluxDbUtils; import com.njcn.influx.utils.InfluxDbUtils;
import lombok.AllArgsConstructor; import lombok.NoArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.influxdb.InfluxDB; import org.influxdb.InfluxDB;
@@ -20,12 +20,15 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@@ -37,7 +40,7 @@ import static org.junit.Assert.assertTrue;
@WebAppConfiguration @WebAppConfiguration
@SpringBootTest(classes = CsDeviceBootApplication.class) @SpringBootTest(classes = CsDeviceBootApplication.class)
@Slf4j @Slf4j
@AllArgsConstructor @NoArgsConstructor
public class AppTest{ public class AppTest{
@Autowired @Autowired
@@ -46,9 +49,69 @@ public class AppTest{
@Autowired @Autowired
private ICsCommunicateService csCommunicateService; private ICsCommunicateService csCommunicateService;
private final IRStatIntegrityDService statIntegrityDService; @Autowired
private final IRStatOnlineRateDService statOnlineRateDService; private IRStatIntegrityDService statIntegrityDService;
@Autowired
private IRStatOnlineRateDService statOnlineRateDService;
public static void main(String[] args) {
String eventValue = "122.5493";
String persistTime = "0.2410";
String data = determineDropZone(eventValue, persistTime);
System.out.println("data==:" + data);
}
public static String determineDropZone(String eventValue, String persistTime) {
if (eventValue != null && !eventValue.trim().isEmpty() && persistTime != null && !persistTime.trim().isEmpty()) {
BigDecimal vvm;
BigDecimal vvtm;
try {
vvm = (new BigDecimal(eventValue.trim())).divide(new BigDecimal("100"), 6, RoundingMode.HALF_UP);
vvtm = new BigDecimal(persistTime.trim());
} catch (Exception var6) {
Exception e = var6;
log.error("判定压降落点区域入参解析失败eventValue={}, persistTime={}", new Object[]{eventValue, persistTime, e});
return null;
}
if (vvtm.compareTo(new BigDecimal("0.001")) >= 0 && vvm.compareTo(BigDecimal.ZERO) != 0) {
if (inRange(vvm, "0.9", "1") && inRange(vvtm, "0.001", "60")) {
return "A区";
} else if (inRange(vvm, "0", "0.9") && inRange(vvtm, "0.001", "0.05")) {
return "A区";
} else if (inRange(vvm, "0.5", "0.7") && inRange(vvtm, "0.05", "0.2")) {
return "B区";
} else if (inRange(vvm, "0.7", "0.8") && inRange(vvtm, "0.05", "0.5")) {
return "B区";
} else if (inRange(vvm, "0.8", "0.9") && inRange(vvtm, "0.05", "60")) {
return "B区";
} else if (inRange(vvm, "0", "0.5") && inRange(vvtm, "0.05", "1")) {
return "C区";
} else if (inRange(vvm, "0.5", "0.7") && inRange(vvtm, "0.2", "1")) {
return "C区";
} else if (inRange(vvm, "0.7", "0.8") && inRange(vvtm, "0.5", "1")) {
return "C区";
} else if (inRange(vvm, "0", "0.8") && inRange(vvtm, "1", "60")) {
return "D区";
} else {
log.warn("压降落点区域未匹配任何规则eventValue={}, persistTime={}", eventValue, persistTime);
return null;
}
} else {
return "A区";
}
} else {
log.warn("判定压降落点区域入参为空eventValue={}, persistTime={}", eventValue, persistTime);
return null;
}
}
private static boolean inRange(BigDecimal value, String lowerInclusive, String upperExclusive) {
return value.compareTo(new BigDecimal(lowerInclusive)) >= 0
&& value.compareTo(new BigDecimal(upperExclusive)) < 0;
}
/** /**
* Rigorous Test :-) * Rigorous Test :-)
@@ -59,7 +122,6 @@ public class AppTest{
assertTrue( true ); assertTrue( true );
} }
/** /**
* 测试下载文件 * 测试下载文件
*/ */
@@ -95,18 +157,76 @@ public class AppTest{
} }
public static void main(String[] args) {
InfluxDbUtils influxDbUtils = new InfluxDbUtils("admin", "123456", "http://192.168.1.24:8086", "pqsbase_zl", "");
public static void test2() {
InfluxDbUtils influxDbUtils = new InfluxDbUtils("admin", "123456", "http://192.168.1.103:18086", "pqsbase", "");
Map<String, String> tags = new HashMap<>(); Map<String, String> tags = new HashMap<>();
tags.put("dev_id","da7aa071bf89864bedea8833133676b7"); tags.put("dev_id","0eb0262f706445ac9c69931a60357561");
Map<String,Object> fields = new HashMap<>(); Map<String,Object> fields = new HashMap<>();
fields.put("type",1); // fields.put("type",1);
fields.put("description","通讯正常"); // fields.put("description","通讯正常");
long time = LocalDateTime.parse("2025-08-02 18:00:00", DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); fields.put("type",0);
fields.put("description","通讯中断");
long time = LocalDateTime.parse("2024-01-06 06:00:00", DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
Point point = influxDbUtils.pointBuilder("pqs_communicate", time, TimeUnit.MILLISECONDS, tags, fields); Point point = influxDbUtils.pointBuilder("pqs_communicate", time, TimeUnit.MILLISECONDS, tags, fields);
BatchPoints batchPoints = BatchPoints.database(influxDbUtils.getDbName()).retentionPolicy("").consistency(InfluxDB.ConsistencyLevel.ALL).build(); BatchPoints batchPoints = BatchPoints.database(influxDbUtils.getDbName()).retentionPolicy("").consistency(InfluxDB.ConsistencyLevel.ALL).build();
batchPoints.point(point); batchPoints.point(point);
influxDbUtils.batchInsert(influxDbUtils.getDbName(), "", InfluxDB.ConsistencyLevel.ALL, TimeUnit.MILLISECONDS, Collections.singletonList(batchPoints.lineProtocol())); influxDbUtils.batchInsert(influxDbUtils.getDbName(), "", InfluxDB.ConsistencyLevel.ALL, TimeUnit.MILLISECONDS, Collections.singletonList(batchPoints.lineProtocol()));
} }
public static void test22() {
InfluxDbUtils influxDbUtils = new InfluxDbUtils("admin", "123456", "http://192.168.1.103:18086", "pqsbase", "");
Map<String, String> tags = new HashMap<>();
tags.put("dev_id","0eb0262f706445ac9c69931a60357561");
Map<String,Object> fields = new HashMap<>();
fields.put("type",1);
fields.put("description","通讯正常");
// fields.put("type",0);
// fields.put("description","通讯中断");
long time = LocalDateTime.parse("2024-01-06 12:00:00", DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
Point point = influxDbUtils.pointBuilder("pqs_communicate", time, TimeUnit.MILLISECONDS, tags, fields);
BatchPoints batchPoints = BatchPoints.database(influxDbUtils.getDbName()).retentionPolicy("").consistency(InfluxDB.ConsistencyLevel.ALL).build();
batchPoints.point(point);
influxDbUtils.batchInsert(influxDbUtils.getDbName(), "", InfluxDB.ConsistencyLevel.ALL, TimeUnit.MILLISECONDS, Collections.singletonList(batchPoints.lineProtocol()));
}
public static void test3() {
InfluxDbUtils influxDbUtils = new InfluxDbUtils("admin", "123456", "http://192.168.1.103:18086", "pqsbase", "");
Map<String, String> tags = new HashMap<>();
tags.put("dev_id","0eb0262f706445ac9c69931a60357561");
Map<String,Object> fields = new HashMap<>();
fields.put("type",0);
fields.put("description","通讯中断");
// fields.put("type",1);
// fields.put("description","通讯正常");
long time = LocalDateTime.parse("2024-01-06 18:00:00", DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
Point point = influxDbUtils.pointBuilder("pqs_communicate", time, TimeUnit.MILLISECONDS, tags, fields);
BatchPoints batchPoints = BatchPoints.database(influxDbUtils.getDbName()).retentionPolicy("").consistency(InfluxDB.ConsistencyLevel.ALL).build();
batchPoints.point(point);
influxDbUtils.batchInsert(influxDbUtils.getDbName(), "", InfluxDB.ConsistencyLevel.ALL, TimeUnit.MILLISECONDS, Collections.singletonList(batchPoints.lineProtocol()));
}
public static void test33() {
InfluxDbUtils influxDbUtils = new InfluxDbUtils("admin", "123456", "http://192.168.1.103:18086", "pqsbase", "");
Map<String, String> tags = new HashMap<>();
tags.put("dev_id","0eb0262f706445ac9c69931a60357561");
Map<String,Object> fields = new HashMap<>();
// fields.put("type",0);
// fields.put("description","通讯中断");
fields.put("type",1);
fields.put("description","通讯正常");
long time = LocalDateTime.parse("2024-01-06 22:00:00", DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
Point point = influxDbUtils.pointBuilder("pqs_communicate", time, TimeUnit.MILLISECONDS, tags, fields);
BatchPoints batchPoints = BatchPoints.database(influxDbUtils.getDbName()).retentionPolicy("").consistency(InfluxDB.ConsistencyLevel.ALL).build();
batchPoints.point(point);
influxDbUtils.batchInsert(influxDbUtils.getDbName(), "", InfluxDB.ConsistencyLevel.ALL, TimeUnit.MILLISECONDS, Collections.singletonList(batchPoints.lineProtocol()));
}
} }

View File

@@ -0,0 +1,130 @@
package com.njcn.csharmonic.pojo.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @author xy
*/
@Data
public class FrontWarnVo implements Serializable {
/**
* id
*/
private String id;
/**
* 监测点id
*/
private String lineId;
/**
* 装置id
*/
private String deviceId;
/**
* 事件时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime startTime;
/**
* 事件类型
*/
private String tag;
/**
* 暂态事件波形文件路
*/
private String wavePath;
/**
* 瞬时波形图,存在多张的情况
*/
private String instantPics;
/**
* RMS波形图存在多张的情况
*/
private String rmsPics;
/**
* 事件类型(0:暂态事件1:稳态事件 2:设备事
* 件)
*/
private Integer type;
/**
* 逻辑子设备id
* 电能质量设备是监测点、治理设备是各个模块
*/
private Integer clDid;
/**
* 事件等级(1:Ⅰ级 2:Ⅱ级 3:Ⅲ级)
*/
private Integer level;
/**
* 发生位置 grid:电网侧load:负载侧
*/
private String location;
/**
* 流程信息(用于数据控制 1:设备登记2功能调试3出厂调试 4设备投运)
*/
private Integer process;
/**
* 告警故障编码一般显示为Hex
*/
private String code;
/**
* 持续时间
*/
private Double persistTime;
/**
* 暂降幅值
*/
private Double amplitude;
/**
* 相别
*/
private String phase;
/**
* 暂降原因
*/
private String advanceReason;
/**
* 暂降类型
*/
private String advanceType;
/**
* 暂态事件落点(A区/B区/C区/D区;解析失败或未匹配返回 null)
*/
private String landPoint;
/**
* 暂降源与监测位置关系 0-未知、1-上游、2-下游
*/
private String sagSource;
/**
* 暂降严重度
*/
private Double severity;
}

View File

@@ -8,7 +8,7 @@ microservice:
gateway: gateway:
url: @gateway.url@ url: @gateway.url@
server: server:
port: 10222 port: 20222
#feign接口开启服务熔断降级处理 #feign接口开启服务熔断降级处理
feign: feign:
sentinel: sentinel:
@@ -45,8 +45,8 @@ spring:
#项目日志的配置 #项目日志的配置
logging: logging:
# config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&username=@nacos.username@&password=@nacos.password@&group=DEFAULT_GROUP&dataId=logback.xml config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&username=@nacos.username@&password=@nacos.password@&group=DEFAULT_GROUP&dataId=logback.xml
config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&group=DEFAULT_GROUP&dataId=logback.xml # config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&group=DEFAULT_GROUP&dataId=logback.xml
level: level:
root: warn root: warn

View File

@@ -0,0 +1,841 @@
package com.njcn;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONTokener;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.csdevice.api.CsCommTerminalFeignClient;
import com.njcn.csdevice.api.CsLineFeignClient;
import com.njcn.csdevice.pojo.po.CsLinePO;
import com.njcn.csharmonic.CsHarmonicBootApplication;
import com.njcn.csharmonic.enums.CsHarmonicResponseEnum;
import com.njcn.csharmonic.service.ICsSysExcelRelationService;
import com.njcn.csharmonic.service.ILineTargetService;
import com.njcn.device.biz.pojo.po.PqsDeviceUnit;
import com.njcn.harmonic.common.mapper.ExcelRptTempMapper;
import com.njcn.harmonic.common.pojo.dto.DeviceUnitCommDTO;
import com.njcn.harmonic.common.pojo.vo.ReportTemplateVO;
import com.njcn.harmonic.common.service.CustomReportTableService;
import com.njcn.harmonic.enums.HarmonicResponseEnum;
import com.njcn.harmonic.pojo.dto.ReportTemplateDTO;
import com.njcn.harmonic.pojo.param.ReportSearchParam;
import com.njcn.harmonic.pojo.po.ExcelRptTemp;
import com.njcn.oss.constant.GeneralConstant;
import com.njcn.oss.constant.OssPath;
import com.njcn.oss.enums.OssResponseEnum;
import com.njcn.oss.utils.FileStorageUtil;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.api.EpdFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.system.pojo.po.EleEpdPqd;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年12月10日 15:05
*/
@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = CsHarmonicBootApplication.class)
public class BaseJunitTest {
@Autowired
private ILineTargetService lineTargetService;
@Autowired
private ICsSysExcelRelationService sysExcelService;
@Autowired
private DicDataFeignClient dicDataFeignClient;
@Autowired
private CsLineFeignClient csLineFeignClient;
@Autowired
private ExcelRptTempMapper excelRptTempMapper;
@Autowired
private CsCommTerminalFeignClient csCommTerminalFeignClient;
@Autowired
private CustomReportTableService customReportTableService;
@Autowired
private FileStorageUtil fileStorageUtil;
@Autowired
private EpdFeignClient epdFeignClient;
private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
private static final Map<String, String> PHASE_MAPPING = new HashMap<String, String>() {
{
this.put("AB", "A");
this.put("BC", "B");
this.put("CA", "C");
this.put("M", "T");
}
};
public void getCustomReport(ReportSearchParam reportSearchParam, Map<String, String> newMap, DeviceUnitCommDTO deviceUnitCommDTO, HttpServletResponse response) {
TimeInterval timeInterval = new TimeInterval();
ExcelRptTemp excelRptTemp = (ExcelRptTemp)this.excelRptTempMapper.selectById(reportSearchParam.getTempId());
if (Objects.isNull(excelRptTemp)) {
throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_ACTIVE);
} else {
if (Objects.isNull(reportSearchParam.getCustomType())) {
this.analyzeReport(reportSearchParam, excelRptTemp, newMap, deviceUnitCommDTO, response);
}
}
}
private void analyzeReport(ReportSearchParam reportSearchParam, ExcelRptTemp excelRptTemp, Map<String, String> newMap, DeviceUnitCommDTO deviceUnitCommDTO, HttpServletResponse response) {
List<Future<?>> futures = new ArrayList();
List<ReportTemplateDTO> reportTemplateDTOList = new ArrayList();
List<ReportTemplateDTO> reportLimitList = new ArrayList();
List<ReportTemplateDTO> terminalList = new ArrayList();
JSONArray jsonArray;
try {
InputStream fileStream = this.fileStorageUtil.getFileStream(excelRptTemp.getContent());
Throwable var12 = null;
try {
jsonArray = new JSONArray(new JSONTokener(fileStream, new JSONConfig()));
this.parseTemplate(jsonArray, reportTemplateDTOList, reportLimitList, terminalList);
} catch (Throwable var32) {
var12 = var32;
throw var32;
} finally {
if (fileStream != null) {
if (var12 != null) {
try {
fileStream.close();
} catch (Throwable var30) {
var12.addSuppressed(var30);
}
} else {
fileStream.close();
}
}
}
} catch (Exception var34) {
Exception e = var34;
if (e instanceof BusinessException) {
throw new BusinessException(e.getMessage());
}
throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_JSON);
}
DictData dictData = (DictData)this.dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.EPD.getCode(), DicDataTypeEnum.CS_DATA_TYPE.getCode()).getData();
if (Objects.isNull(dictData)) {
throw new BusinessException(CommonResponseEnum.FAIL, "字典类型模板缺少!");
} else {
DictData epdDic = (DictData)this.dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.EPD.getCode(), DicDataTypeEnum.CS_DATA_TYPE.getCode()).getData();
List<EleEpdPqd> eleEpdPqdList = (List)this.epdFeignClient.dictMarkByDataType(epdDic.getId()).getData();
Map<String, String> tMap = new HashMap();
eleEpdPqdList.forEach((item) -> {
String phase;
if (Objects.isNull(PHASE_MAPPING.get(item.getPhase()))) {
phase = item.getPhase();
} else {
phase = (String)PHASE_MAPPING.get(item.getPhase());
}
if (ObjectUtils.isNotNull(new Object[]{item.getHarmStart()}) && ObjectUtils.isNotNull(new Object[]{item.getHarmEnd()})) {
for(int i = item.getHarmStart(); i <= item.getHarmEnd() + 1; ++i) {
tMap.put((item.getOtherName() + "_" + i + phase + item.getResourcesId()).toUpperCase(), item.getPrimaryFormula());
}
} else {
tMap.put((item.getOtherName() + phase + item.getResourcesId()).toUpperCase(), item.getPrimaryFormula());
}
});
eleEpdPqdList = (List)eleEpdPqdList.stream().filter((it) -> {
return "T".equals(it.getPhase()) || "M".equals(it.getPhase());
}).collect(Collectors.toList());
List<String> noPhaseList = (List)eleEpdPqdList.stream().filter((it) -> {
return StrUtil.isNotBlank(it.getOtherName());
}).map((it) -> {
return it.getOtherName().toUpperCase();
}).collect(Collectors.toList());
reportLimitList = (List)(new LinkedHashSet(reportLimitList)).stream().sorted(Comparator.comparing(ReportTemplateDTO::getItemName)).collect(Collectors.toList());
Map<String, Float> limitMap = this.overLimitDeal(reportLimitList, reportSearchParam);
Map<String, ReportTemplateDTO> limitTargetMapX = (Map)reportLimitList.stream().collect(Collectors.toMap(ReportTemplateDTO::getItemName, Function.identity()));
List<ReportTemplateDTO> endList = new CopyOnWriteArrayList();
if (CollUtil.isNotEmpty(reportTemplateDTOList)) {
reportTemplateDTOList = (List)(new LinkedHashSet(reportTemplateDTOList)).stream().sorted(Comparator.comparing(ReportTemplateDTO::getItemName)).collect(Collectors.toList());
Map<String, List<ReportTemplateDTO>> classMap = (Map)reportTemplateDTOList.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getResourceId));
Map<String, ReportTemplateDTO> assNoPassMap = new HashMap();
classMap.forEach((classKey, templateValue) -> {
Map<String, List<ReportTemplateDTO>> valueTypeMap = (Map)templateValue.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getStatMethod));
futures.add(this.executorService.submit(() -> {
DynamicDataSourceContextHolder.push("sjzx");
try {
valueTypeMap.forEach((valueTypeKey, valueTypeVal) -> {
Map<String, List<ReportTemplateDTO>> phaseMap = (Map)valueTypeVal.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getPhase));
phaseMap.forEach((phaseKey, phaseVal) -> {
StringBuilder sql = new StringBuilder("SELECT ");
if ("MAX".equalsIgnoreCase(valueTypeKey)) {
this.assSqlByMysql(tMap, (String)newMap.get("LEVEL"), (String)newMap.get("PT"), (String)newMap.get("CT"), phaseVal, sql, endList, "MAX", reportSearchParam, limitTargetMapX, limitMap, assNoPassMap, noPhaseList);
} else if ("MIN".equalsIgnoreCase(valueTypeKey)) {
this.assSqlByMysql(tMap, (String)newMap.get("LEVEL"), (String)newMap.get("PT"), (String)newMap.get("CT"), phaseVal, sql, endList, "MIN", reportSearchParam, limitTargetMapX, limitMap, assNoPassMap, noPhaseList);
} else if ("AVG".equalsIgnoreCase(valueTypeKey)) {
this.assSqlByMysql(tMap, (String)newMap.get("LEVEL"), (String)newMap.get("PT"), (String)newMap.get("CT"), phaseVal, sql, endList, "AVG", reportSearchParam, limitTargetMapX, limitMap, assNoPassMap, noPhaseList);
} else if ("CP95".equalsIgnoreCase(valueTypeKey)) {
this.assSqlByMysql(tMap, (String)newMap.get("LEVEL"), (String)newMap.get("PT"), (String)newMap.get("CT"), phaseVal, sql, endList, "CP95", reportSearchParam, limitTargetMapX, limitMap, assNoPassMap, noPhaseList);
}
});
});
} finally {
DynamicDataSourceContextHolder.poll();
}
}));
});
Iterator var21 = futures.iterator();
while(var21.hasNext()) {
Future<?> future = (Future)var21.next();
try {
future.get();
} catch (ExecutionException | InterruptedException var31) {
Exception e = var31;
e.printStackTrace();
}
}
this.dealTargetResult(assNoPassMap, limitTargetMapX, endList);
}
Map<String, Object> dataMap = new HashMap();
this.resultAssemble(endList, reportSearchParam, newMap, deviceUnitCommDTO, jsonArray,dataMap);
this.downReport(jsonArray, dataMap);
}
}
@SneakyThrows
@Test
public void test() {
HttpServletResponse response = null;
ReportSearchParam reportSearchParam = new ReportSearchParam();
reportSearchParam.setLineId("00B78D00A87A1");
reportSearchParam.setTempId("58f0be3e6360e73fa47dae1defcee23b");
reportSearchParam.setStartTime("2026-03-01");
reportSearchParam.setEndTime("2026-03-19");
reportSearchParam.setResourceType(1);
String tempId = getTempId("58f0be3e6360e73fa47dae1defcee23b", "00B78D01840B0");
//修改模板id
reportSearchParam.setTempId(tempId);
//原代码
TimeInterval timeInterval = new TimeInterval();
//ExcelRptTemp excelRptTemp = excelRptTempMapper.selectById(reportSearchParam.getTempId());
ExcelRptTemp excelRptTemp = excelRptTempMapper.selectById(tempId);
if (Objects.isNull(excelRptTemp)) {
throw new BusinessException(CsHarmonicResponseEnum.CUSTOM_REPORT_ACTIVE);
}
if (Objects.isNull(reportSearchParam.getCustomType())) {
//通用报表
Map<String,String> map = csLineFeignClient.getCustomDetailByLineId(reportSearchParam.getLineId()).getData();
Map<String,String> newMap = convertKeysToUpperCase(map);
PqsDeviceUnit deviceUnit = csCommTerminalFeignClient.lineUnitDetail(reportSearchParam.getLineId()).getData();
DeviceUnitCommDTO deviceUnitCommDTO = BeanUtil.copyProperties(deviceUnit, DeviceUnitCommDTO.class);
this.getCustomReport(reportSearchParam,newMap,deviceUnitCommDTO,response);
}
}
private void downReport(JSONArray jsonArray, Map<String, Object> dataMap) {
Workbook workbook = new XSSFWorkbook();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String sheetName = jsonObject.getStr("name");
JSONArray data = jsonObject.getJSONArray("data");
Sheet sheet = workbook.createSheet(sheetName);
if (data != null) {
for (int j = 0; j < data.size(); j++) {
Row row = sheet.createRow(j);
JSONArray rowData = data.getJSONArray(j);
if (rowData != null) {
for (int k = 0; k < rowData.size(); k++) {
Cell cell = row.createCell(k);
JSONObject cellObj = rowData.getJSONObject(k);
if (cellObj != null && !cellObj.isEmpty()) {
Object v = cellObj.get("v");
if (v != null) {
Object vData = dataMap.get(v);
if (vData != null) {
if (vData instanceof String) {
cell.setCellValue((String) vData);
} else if (vData instanceof Number) {
cell.setCellValue(((Number) vData).doubleValue());
} else if (vData instanceof Boolean) {
cell.setCellValue((Boolean) vData);
} else {
cell.setCellValue(vData.toString());
}
} else {
if (v instanceof String) {
cell.setCellValue((String) v);
} else if (v instanceof Number) {
cell.setCellValue(((Number) v).doubleValue());
} else if (v instanceof Boolean) {
cell.setCellValue((Boolean) v);
} else {
cell.setCellValue(v.toString());
}
}
}
}
}
}
}
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
workbook.write(baos);
workbook.close();
} catch (IOException e) {
throw new BusinessException(OssResponseEnum.DOWNLOAD_FILE_STREAM_ERROR);
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
fileStorageUtil.uploadStream(bais, OssPath.ALGORITHM, "稳态报表.xlsx");
try {
bais.close();
baos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// private void downReport(JSONArray jsonArray, HttpServletResponse response) {
// InputStream reportStream = IoUtil.toStream(jsonArray.toString(), "UTF-8");
// fileStorageUtil.uploadStream(reportStream, OssPath.ALGORITHM,"报表测试.xlsx");
// //jsonArray 这边解析发现 存储的是Luckysheet 相关的数据想把这部分数据解析为excel表格存储怎么处理
// }
public void resultAssemble(List<ReportTemplateDTO> endList, ReportSearchParam reportSearchParam, Map<String, String> finalTerminalMap, DeviceUnitCommDTO deviceUnitCommDTO, JSONArray jsonArray,Map<String, Object> dataMap) {
if (CollUtil.isNotEmpty(endList)) {
Map<String, String> unit = this.unitMap(deviceUnitCommDTO);
Map<String, List<ReportTemplateDTO>> assMap = (Map)endList.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getItemName));
jsonArray.forEach((item) -> {
JSONObject jsonObject = (JSONObject)item;
JSONArray itemArr = (JSONArray)jsonObject.get("celldata");
itemArr.forEach((it) -> {
if (Objects.nonNull(it) && !"null".equals(it.toString())) {
JSONObject data = (JSONObject)it;
JSONObject son = (JSONObject)data.get("v");
if (son.containsKey("v")) {
String v = son.getStr("v");
String tem;
List rDto;
if (v.charAt(0) == '$' && v.contains("#")) {
tem = "";
rDto = (List)assMap.get(v.replace("$", "").toUpperCase());
if (Objects.nonNull(rDto)) {
tem = ((ReportTemplateDTO)rDto.get(0)).getValue();
if (StringUtils.isBlank(tem)) {
tem = "/";
}
son.set("v", tem);
dataMap.put(v, tem);
if (Objects.nonNull(((ReportTemplateDTO)rDto.get(0)).getOverLimitFlag()) && ((ReportTemplateDTO)rDto.get(0)).getOverLimitFlag() == 1) {
son.set("fc", "#990000");
}
}
} else if (v.charAt(0) == '%' && v.contains("#")) {
tem = "";
rDto = (List)assMap.get(v.replace("%", "").toUpperCase());
if (Objects.nonNull(rDto)) {
tem = ((ReportTemplateDTO)rDto.get(0)).getValue();
if (StringUtils.isBlank(tem)) {
tem = "/";
}
son.set("v", tem);
dataMap.put(v, tem);
if ("不合格".equals(tem)) {
son.set("fc", "#990000");
dataMap.put("fc", "#990000");
}
}
} else if (v.charAt(0) == '&') {
tem = v.replace("&", "").toUpperCase();
if (finalTerminalMap.size() > 0) {
if ("STATIS_TIME".equals(tem)) {
String localTime = " 23:59:59";
LocalDate localDate = LocalDateTimeUtil.parseDate(reportSearchParam.getEndTime(), "yyyy-MM-dd");
LocalDate nowDate = LocalDate.now();
if (nowDate.isAfter(localDate)) {
son.set("v", reportSearchParam.getStartTime() + " 00:00:00" + "_" + reportSearchParam.getEndTime() + localTime);
dataMap.put(v, reportSearchParam.getStartTime() + " 00:00:00" + "_" + reportSearchParam.getEndTime() + localTime);
} else {
localTime = " " + LocalTime.now().format(DatePattern.NORM_TIME_FORMATTER);
son.set("v", reportSearchParam.getStartTime() + " 00:00:00" + "_" + nowDate + localTime);
dataMap.put(v, reportSearchParam.getStartTime() + " 00:00:00" + "_" + nowDate + localTime);
}
} else {
son.set("v", finalTerminalMap.getOrDefault(tem, "/"));
dataMap.put(v, finalTerminalMap.getOrDefault(tem, "/"));
}
}
}
if (v.charAt(0) == '@' && v.contains("#")) {
tem = v.replace("@", "");
son.set("v", unit.getOrDefault(tem, "/"));
dataMap.put(v, unit.getOrDefault(tem, "/"));
}
}
}
});
});
}
}
private Map<String, String> unitMap(DeviceUnitCommDTO deviceUnit) {
List<DictData> dictData = (List)this.dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEVICE_UNIT.getCode()).getData();
Map<String, String> unit = new HashMap();
List<String> list = (List)dictData.stream().map(DictData::getCode).collect(Collectors.toList());
Iterator var5 = list.iterator();
while(var5.hasNext()) {
String s = (String)var5.next();
if (s.equals(DicDataEnum.EFFECTIVE.getCode())) {
unit.put(s + "#i", deviceUnit.getIeffective());
unit.put(s + "#v", deviceUnit.getLineVoltage());
}
if (s.equals(DicDataEnum.POWER.getCode())) {
unit.put(s + "#p", deviceUnit.getTotalActiveP());
unit.put(s + "#q", deviceUnit.getTotalNoP());
unit.put(s + "#s", deviceUnit.getTotalViewP());
}
if (s.equals(DicDataEnum.DISTORTION.getCode())) {
unit.put(s + "#v", deviceUnit.getVdistortion());
}
if (s.equals(DicDataEnum.VOLTAGE.getCode())) {
unit.put(s + "#v", deviceUnit.getVoltageDev());
}
if (s.equals(DicDataEnum.UNIT_FREQUENCY.getCode())) {
unit.put(s + "#freq", deviceUnit.getUnitFrequency());
unit.put(s + "#freqDev", deviceUnit.getUnitFrequencyDev());
}
if (s.equals(DicDataEnum.UNBALANCE.getCode())) {
unit.put(s + "#v", "%");
unit.put(s + "#vPos", deviceUnit.getPositiveV());
unit.put(s + "#vNeg", deviceUnit.getNoPositiveV());
unit.put(s + "#vZero", deviceUnit.getNoPositiveV());
unit.put(s + "#i", "%");
unit.put(s + "#iPos", "A");
unit.put(s + "#iNeg", "A");
unit.put(s + "#iZero", "A");
}
if (s.equals(DicDataEnum.FUND.getCode())) {
unit.put(s + "#i", deviceUnit.getIfund());
unit.put(s + "#v", deviceUnit.getVfundEffective());
}
}
return unit;
}
private void dealTargetResult(Map<String, ReportTemplateDTO> assNoPassMap, Map<String, ReportTemplateDTO> limitTargetMapX, List<ReportTemplateDTO> endList) {
assNoPassMap.forEach((key, val) -> {
limitTargetMapX.remove(key);
if ("Freq_Dev".toUpperCase().equals(val.getTemplateName())) {
val.setValue("±" + val.getValue());
}
String expend = "";
if (Objects.nonNull(val.getLowValue())) {
expend = val.getLowValue() + ",";
}
if (val.getOverLimitFlag() == 1) {
val.setValue("不合格 (" + expend + val.getValue() + ")");
} else {
val.setValue("合格 (" + expend + val.getValue() + ")");
}
endList.add(val);
});
limitTargetMapX.forEach((key, val) -> {
if (Objects.isNull(val.getOverLimitFlag())) {
val.setValue("/");
} else {
val.setValue("合格");
}
endList.add(val);
});
}
private void assSqlByMysql(Map<String, String> tMap, String dataLevel, String pt, String ct, List<ReportTemplateDTO> data, StringBuilder sql, List<ReportTemplateDTO> endList, String method, ReportSearchParam reportSearchParam, Map<String, ReportTemplateDTO> limitMap, Map<String, Float> overLimitMap, Map<String, ReportTemplateDTO> assNoPassMap, List<String> noPhaseList) {
int i;
if ("CP95".equals(method)) {
for(i = 0; i < data.size(); ++i) {
if (i == data.size() - 1) {
sql.append("MAX").append("(").append(((ReportTemplateDTO)data.get(i)).getTemplateName()).append(")").append(Objects.equals(dataLevel, "Secondary") ? " " + this.appendData(tMap, ((ReportTemplateDTO)data.get(i)).getTemplateName() + ((ReportTemplateDTO)data.get(i)).getPhase() + ((ReportTemplateDTO)data.get(0)).getResourceId(), this.getData(pt), this.getData(ct)) : "").append(" as ").append("\"" + ((ReportTemplateDTO)data.get(i)).getItemName() + "\"");
} else {
sql.append("MAX").append("(").append(((ReportTemplateDTO)data.get(i)).getTemplateName()).append(")").append(Objects.equals(dataLevel, "Secondary") ? " " + this.appendData(tMap, ((ReportTemplateDTO)data.get(i)).getTemplateName() + ((ReportTemplateDTO)data.get(i)).getPhase() + ((ReportTemplateDTO)data.get(0)).getResourceId(), this.getData(pt), this.getData(ct)) : "").append(" as ").append("\"" + ((ReportTemplateDTO)data.get(i)).getItemName() + "\"").append(",");
}
}
} else {
for(i = 0; i < data.size(); ++i) {
if (i == data.size() - 1) {
sql.append(method).append("(").append(((ReportTemplateDTO)data.get(i)).getTemplateName()).append(")").append(Objects.equals(dataLevel, "Secondary") ? " " + this.appendData(tMap, ((ReportTemplateDTO)data.get(i)).getTemplateName() + ((ReportTemplateDTO)data.get(i)).getPhase() + ((ReportTemplateDTO)data.get(0)).getResourceId(), this.getData(pt), this.getData(ct)) : "").append(" as ").append("\"" + ((ReportTemplateDTO)data.get(i)).getItemName() + "\"");
} else {
sql.append(method).append("(").append(((ReportTemplateDTO)data.get(i)).getTemplateName()).append(")").append(Objects.equals(dataLevel, "Secondary") ? " " + this.appendData(tMap, ((ReportTemplateDTO)data.get(i)).getTemplateName() + ((ReportTemplateDTO)data.get(i)).getPhase() + ((ReportTemplateDTO)data.get(0)).getResourceId(), this.getData(pt), this.getData(ct)) : "").append(" as ").append("\"" + ((ReportTemplateDTO)data.get(i)).getItemName() + "\"").append(",");
}
}
}
sql.append(' ').append("FROM ").append(((ReportTemplateDTO)data.get(0)).getResourceId());
sql.append(" WHERE ").append("line_id").append("=").append("'").append(reportSearchParam.getLineId()).append("'");
if (!"M".equals(((ReportTemplateDTO)data.get(0)).getPhase())) {
sql.append(" AND ").append("phasic_type").append("=").append("'").append(((ReportTemplateDTO)data.get(0)).getPhase()).append("'");
}
sql.append(" AND ").append("value_type").append("=").append("'").append(((ReportTemplateDTO)data.get(0)).getStatMethod()).append("'");
if (noPhaseList.contains(((ReportTemplateDTO)data.get(0)).getTemplateName())) {
if (((ReportTemplateDTO)data.get(0)).getTemplateName().equalsIgnoreCase("v_unbalance")) {
System.out.println(44);
}
sql.append(" AND ").append("phasic_type").append("=").append("'").append("T").append("'");
}
sql.append(" AND ").append("time ").append(">=").append("'").append(reportSearchParam.getStartTime()).append(" 00:00:00").append("'").append(" AND ").append("time ").append("<").append("'").append(reportSearchParam.getEndTime()).append(" 23:59:59").append("'");
System.out.println(sql);
List<Map<String, Object>> mapList = SqlRunner.DEFAULT.selectList(sql.toString(), new Object[0]);
if (!CollUtil.isEmpty(mapList) && !Objects.isNull(mapList.get(0))) {
Map<String, Object> map = this.convertKeysToUpperCase((Map)mapList.get(0));
Iterator var16 = data.iterator();
label124:
while(true) {
while(true) {
while(true) {
double v;
String key;
do {
ReportTemplateDTO item;
do {
while(true) {
if (!var16.hasNext()) {
break label124;
}
item = (ReportTemplateDTO)var16.next();
if (map.containsKey(item.getItemName())) {
v = Double.parseDouble(map.get(item.getItemName()).toString());
item.setValue(String.format("%.3f", v));
if (overLimitMap.containsKey(item.getLimitName())) {
Float tagVal = (Float)overLimitMap.get(item.getLimitName());
if (item.getLimitName().equalsIgnoreCase("UVOLTAGE_DEV")) {
Float tagVal_U = (Float)overLimitMap.get("UVOLTAGE_DEV");
if (!(v > (double)tagVal) && !(v < (double)tagVal_U)) {
item.setOverLimitFlag(0);
} else {
item.setOverLimitFlag(1);
}
} else if (v > (double)tagVal) {
item.setOverLimitFlag(1);
} else {
item.setOverLimitFlag(0);
}
}
break;
}
item.setValue("/");
}
} while(limitMap.isEmpty());
key = item.getLimitName() + "#" + item.getStatMethod() + "#PQ_OVERLIMIT";
} while(!limitMap.containsKey(key));
ReportTemplateDTO tem = (ReportTemplateDTO)limitMap.get(key);
double limitVal = Double.parseDouble(tem.getValue());
if ("VOLTAGE_DEV".equalsIgnoreCase(tem.getLimitName())) {
double limitLowVal = Double.parseDouble(tem.getLowValue());
if (!(v > limitVal) && !(v < limitLowVal)) {
if (!assNoPassMap.containsKey(key)) {
tem.setOverLimitFlag(0);
assNoPassMap.put(key, tem);
}
} else {
tem.setOverLimitFlag(1);
assNoPassMap.put(key, tem);
}
} else if (v > limitVal) {
tem.setOverLimitFlag(1);
assNoPassMap.put(key, tem);
} else if (!assNoPassMap.containsKey(key)) {
tem.setOverLimitFlag(0);
assNoPassMap.put(key, tem);
}
}
}
}
} else {
data = (List)data.stream().peek((itemx) -> {
itemx.setValue("/");
}).collect(Collectors.toList());
}
endList.addAll(data);
}
public Double getData(String data) {
double ratio = 1.0;
String[] parts = data.split(":");
if (parts.length == 2) {
try {
int num1 = Integer.parseInt(parts[0]);
int num2 = Integer.parseInt(parts[1]);
ratio = (double)num1 / (double)num2;
} catch (NumberFormatException var7) {
System.out.println("字符串格式错误");
}
}
return ratio;
}
public String appendData(Map<String, String> tMap, String name, double pt, double ct) {
String format = (String)tMap.get(name);
String result;
if (Objects.equals(format, "*PT")) {
result = "*" + pt + "/1000";
} else if (Objects.equals(format, "*CT")) {
result = "*" + ct;
} else if (Objects.equals(format, "*PT*CT")) {
result = "*" + pt + "*" + ct + "/1000";
} else {
result = "";
}
return result;
}
private Map<String, Float> overLimitDeal(List<ReportTemplateDTO> reportLimitList, ReportSearchParam reportSearchParam) {
Map<String, Float> limitMap = new HashMap();
if (CollUtil.isNotEmpty(reportLimitList)) {
StringBuilder sql = new StringBuilder("SELECT ");
for(int i = 0; i < reportLimitList.size(); ++i) {
if (i == reportLimitList.size() - 1) {
sql.append("UVOLTAGE_DEV").append(",");
sql.append(((ReportTemplateDTO)reportLimitList.get(i)).getTemplateName()).append(' ');
} else {
sql.append(((ReportTemplateDTO)reportLimitList.get(i)).getTemplateName()).append(",");
}
}
sql.append("FROM ").append(((ReportTemplateDTO)reportLimitList.get(0)).getResourceId()).append(" WHERE ").append("id ='").append(reportSearchParam.getLineId()).append("'");
limitMap = this.excelRptTempMapper.dynamicSqlMap(sql.toString());
if (Objects.isNull(limitMap)) {
throw new BusinessException("当前报表测点限值缺失!");
}
Iterator var8 = reportLimitList.iterator();
while(var8.hasNext()) {
ReportTemplateDTO item = (ReportTemplateDTO)var8.next();
if (((Map)limitMap).containsKey(item.getTemplateName())) {
if (item.getTemplateName().equalsIgnoreCase("VOLTAGE_DEV")) {
item.setLowValue(((Float)((Map)limitMap).get("UVOLTAGE_DEV")).toString());
}
item.setValue(((Float)((Map)limitMap).get(item.getTemplateName())).toString());
}
}
}
limitMap = this.convertKeysToUpperCase((Map)limitMap);
return limitMap;
}
private void parseTemplate(JSONArray jsonArray, List<ReportTemplateDTO> reportTemplateDTOList, List<ReportTemplateDTO> reportLimitList, List<ReportTemplateDTO> terminalList) {
try {
jsonArray.forEach((item) -> {
JSONObject jsonObject = (JSONObject)item;
JSONArray itemArr = (JSONArray)jsonObject.get("celldata");
itemArr.forEach((it) -> {
if (Objects.nonNull(it) && !"null".equals(it.toString())) {
JSONObject data = (JSONObject)it;
JSONObject son = (JSONObject)data.get("v");
if (son.containsKey("v")) {
String v = son.getStr("v");
ReportTemplateDTO reportTemplateDTO;
String[] vItem;
if (v.charAt(0) == '$' && v.contains("#")) {
v = v.replace("$", "");
reportTemplateDTO = new ReportTemplateDTO();
reportTemplateDTO.setItemName(v.toUpperCase());
vItem = v.split("#");
if (vItem.length == 5) {
reportTemplateDTO.setTemplateName(vItem[0].toUpperCase());
reportTemplateDTO.setPhase(vItem[1].substring(0, 1).toUpperCase());
reportTemplateDTO.setStatMethod(vItem[2].toUpperCase());
reportTemplateDTO.setResourceId(vItem[3].toUpperCase());
reportTemplateDTO.setLimitName(vItem[4].toUpperCase());
} else if (vItem.length == 4) {
reportTemplateDTO.setTemplateName(vItem[0].toUpperCase());
reportTemplateDTO.setPhase("T");
reportTemplateDTO.setStatMethod(vItem[1].toUpperCase());
reportTemplateDTO.setResourceId(vItem[2].toUpperCase());
reportTemplateDTO.setLimitName(vItem[3].toUpperCase());
}
reportTemplateDTOList.add(reportTemplateDTO);
} else if (v.charAt(0) == '%' && v.contains("#")) {
reportTemplateDTO = new ReportTemplateDTO();
v = v.replace("%", "");
reportTemplateDTO.setItemName(v.toUpperCase());
vItem = v.split("#");
if (vItem.length == 3) {
reportTemplateDTO.setTemplateName(vItem[0].toUpperCase());
reportTemplateDTO.setStatMethod(vItem[1].toUpperCase());
reportTemplateDTO.setResourceId(vItem[2].toUpperCase());
}
reportLimitList.add(reportTemplateDTO);
} else if (v.charAt(0) == '&') {
reportTemplateDTO = new ReportTemplateDTO();
v = v.replace("&", "");
reportTemplateDTO.setItemName(v.toUpperCase());
reportTemplateDTO.setTemplateName(v.toUpperCase());
terminalList.add(reportTemplateDTO);
}
}
}
});
});
} catch (Exception var6) {
throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_JSON);
}
}
/**
* map key转大写
*/
public <V> Map<String, V> convertKeysToUpperCase(Map<String, V> originalMap) {
Map<String, V> newMap = new HashMap<>();
if (CollUtil.isNotEmpty(originalMap)) {
for (Map.Entry<String, V> entry : originalMap.entrySet()) {
newMap.put(entry.getKey().toUpperCase(), entry.getValue());
}
}
return newMap;
}
//获取模板id
public String getTempId(String oldTempId, String lineId) {
//根据模板类型的id获取模板
List<ReportTemplateVO> result = sysExcelService.queryList(oldTempId);
if (CollUtil.isEmpty(result)) {
throw new BusinessException("未配置相关模板");
}
//根据监测点获取接线方式
CsLinePO po = csLineFeignClient.getById(lineId).getData();
//根据接线方式获取模板id
int conType = po.getConType();
DictData dicData;
//角型
if (conType == 1) {
dicData = dicDataFeignClient.getDicDataByCode(DicDataEnum.STAR_TRIANGLE.getCode()).getData();
}
//v型
else if (conType == 2){
dicData = dicDataFeignClient.getDicDataByCode(DicDataEnum.OPEN_DELTA.getCode()).getData();
}
//星型 或 其他
else {
dicData = dicDataFeignClient.getDicDataByCode(DicDataEnum.STAR.getCode()).getData();
}
String tempId;
Optional<ReportTemplateVO> vo = result.stream().filter(item -> Objects.equals(dicData.getId(),item.getWiringMethod())).findFirst();
if (vo.isPresent()) {
tempId = vo.get().getId();
} else {
throw new BusinessException("未找到此接线方式的模板");
}
return tempId;
}
public static void main(String[] args) {
String fullPath = "comtrade/00:B7:8D:00:A8:7A/PQMonitor_PQM1_00100_20260204_162453_071_WAV.hdr";
int lastSlashIndex = fullPath.lastIndexOf('/');
String hdrPath = fullPath.substring(0, lastSlashIndex + 1);
String hdrName = fullPath.substring(lastSlashIndex + 1);
System.out.println(hdrPath);
System.out.println(hdrName);
}
}

View File

@@ -8,7 +8,7 @@ microservice:
gateway: gateway:
url: @gateway.url@ url: @gateway.url@
server: server:
port: 10224 port: 20224
#feign接口开启服务熔断降级处理 #feign接口开启服务熔断降级处理
feign: feign:
sentinel: sentinel:
@@ -41,8 +41,8 @@ spring:
#项目日志的配置 #项目日志的配置
logging: logging:
# config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&username=@nacos.username@&password=@nacos.password@&group=DEFAULT_GROUP&dataId=logback.xml config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&username=@nacos.username@&password=@nacos.password@&group=DEFAULT_GROUP&dataId=logback.xml
config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&group=DEFAULT_GROUP&dataId=logback.xml # config: http://@nacos.url@/nacos/v1/cs/configs?tenant=@nacos.namespace@&group=DEFAULT_GROUP&dataId=logback.xml
level: level:
root: warn root: warn

View File

@@ -0,0 +1,321 @@
package com.njcn;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.njcn.csdevice.api.CsDeviceUserFeignClient;
import com.njcn.csdevice.api.CsLineFeignClient;
import com.njcn.csdevice.pojo.dto.CsLineDTO;
import com.njcn.csdevice.pojo.param.UserDevParam;
import com.njcn.csdevice.pojo.po.CsDeviceUserPO;
import com.njcn.csharmonic.api.RStatLimitRateDFeignClient;
import com.njcn.csharmonic.pojo.param.RStatLimitQueryParam;
import com.njcn.csharmonic.pojo.po.CsEventUserPO;
import com.njcn.csharmonic.pojo.po.CsHarmonic;
import com.njcn.csharmonic.pojo.po.RStatLimitRateDPO;
import com.njcn.cssystem.CsSystemBootApplication;
import com.njcn.harmonic.pojo.param.StatSubstationBizBaseParam;
import com.njcn.user.api.AppUserFeignClient;
import com.njcn.user.pojo.po.User;
import lombok.SneakyThrows;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import javax.annotation.Resource;
import java.io.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = CsSystemBootApplication.class)
public class ZipTest {
private static final int BUFFER_SIZE = 4096;
@Resource
private CsLineFeignClient csLineFeignClient;
@Resource
private RStatLimitRateDFeignClient rStatLimitRateDClient;
@Resource
private CsDeviceUserFeignClient csDeviceUserFeignClient;
@Resource
private AppUserFeignClient appUserFeignClient;
@SneakyThrows
@Test
public void test11() {
List<CsHarmonic> list1 = new ArrayList<>();
List<CsEventUserPO> list2 = new ArrayList<>();
//获取所有监测点
List<CsLineDTO> allLine = csLineFeignClient.getAllLineDetail().getData();
if (CollUtil.isNotEmpty(allLine)) {
//监测点id集合
List<String> lineList = allLine.stream().map(CsLineDTO::getDeviceId).distinct().collect(Collectors.toList());
//设备id集合
List<String> devList = allLine.stream().map(CsLineDTO::getDeviceId).distinct().collect(Collectors.toList());
//获取监测点和设备关系
Map<String,String> lineDevMap = allLine.stream().collect(Collectors.toMap(CsLineDTO::getLineId,CsLineDTO::getDeviceId));
//获取设备和用户关系
UserDevParam param = new UserDevParam();
param.setList(devList);
List<CsDeviceUserPO> userList = csDeviceUserFeignClient.getList(param).getData();
//根据设备id分组 组是subUserId的集合
Map<String, List<String>> userDevMap = userList.stream().collect(Collectors.groupingBy(
CsDeviceUserPO::getDeviceId,
Collectors.mapping(
CsDeviceUserPO::getSubUserId,
Collectors.toList()
)
));
//获取管理员信息
List<User> adminList = appUserFeignClient.getAdminInfo().getData();
//获取用户id集合
List<String> userIdList = adminList.stream().map(User::getId).collect(Collectors.toList());
//获取越限数据
StatSubstationBizBaseParam rateLine = new StatSubstationBizBaseParam();
rateLine.setIds(lineList);
String date = DateUtil.yesterday().toString(DatePattern.NORM_DATE_PATTERN);
rateLine.setStartTime(date);
rateLine.setEndTime(date);
RStatLimitQueryParam rStatLimitQueryParam = RStatLimitQueryParam.builder().ids(lineList).date(date).endDate(date).build();
List<RStatLimitRateDPO> limitRates = rStatLimitRateDClient.monitorIdsGetLimitRateInfo(rStatLimitQueryParam).getData();
if (CollUtil.isNotEmpty(limitRates)) {
limitRates.forEach(item->{
//新增cs_harmonic数据
String id = IdUtil.fastSimpleUUID();
CsHarmonic csharmonic = new CsHarmonic();
csharmonic.setId(id);
csharmonic.setLineId(item.getLineId());
csharmonic.setTime(LocalDate.parse(date));
csharmonic.setTag(buildOverlimitTag(item));
list1.add(csharmonic);
//根据监测点id获取设备
String deviceId = lineDevMap.get(item.getLineId());
//根据设备获取用户
List<String> userIds = userDevMap.get(deviceId);
//添加管理员用户
List<String> result = Stream.concat(userIdList.stream(), userIds.stream())
.distinct()
.collect(Collectors.toList());
result.forEach(userId->{
//新增cs_event_user数据
CsEventUserPO po = new CsEventUserPO();
po.setUserId(userId);
po.setEventId(id);
po.setStatus(0);
list2.add(po);
});
});
}
}
if (CollUtil.isNotEmpty(list1)) {
System.out.println("list1==:" + list1);
System.out.println("list2==:" + list2);
}
}
@SneakyThrows
@Test
public void test() {
String ZipFilePath = "C:\\Users\\徐扬\\Desktop\\test.zip";
File zipFile = new File(ZipFilePath);
ZipFile zip = new ZipFile(zipFile);
//遍历zip文件中的所有条目
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
//在这里执行后续操作
ZipEntry entry = entries.nextElement();
System.out.println(entry.getName());
InputStream inputStream = zip.getInputStream(entry);
// OutputStream outputStream = new FileOutputStream("path/to/output/file");
// byte[] buffer = new byte[1024];int length;
// while ((length = inputStream.read(buffer)) > 0) {
// outputStream.write(buffer, 0, length);
// }
// outputStream.close();
inputStream.close();
}
}
public void unzip(String ZipFilePath, String DestFilePath) throws IOException {
File Destination_Directory = new File(DestFilePath);
if (!Destination_Directory.exists()) {
Destination_Directory.mkdir();
}
ZipInputStream Zip_Input_Stream = new ZipInputStream(new FileInputStream(ZipFilePath));
ZipEntry Zip_Entry = Zip_Input_Stream.getNextEntry();
while (Zip_Entry != null) {
String File_Path = DestFilePath + File.separator + Zip_Entry.getName();
if (!Zip_Entry.isDirectory()) {
extractFile(Zip_Input_Stream, File_Path);
} else {
File directory = new File(File_Path);
directory.mkdirs();
}
Zip_Input_Stream.closeEntry();
Zip_Entry = Zip_Input_Stream.getNextEntry();
}
Zip_Input_Stream.close();
}
private static void extractFile(ZipInputStream Zip_Input_Stream, String File_Path)
throws IOException {
BufferedOutputStream Buffered_Output_Stream =
new BufferedOutputStream(new FileOutputStream(File_Path));
byte[] Bytes = new byte[BUFFER_SIZE];
int Read_Byte = 0;
while ((Read_Byte = Zip_Input_Stream.read(Bytes)) != -1) {
Buffered_Output_Stream.write(Bytes, 0, Read_Byte);
}
Buffered_Output_Stream.close();
}
/**
* 构建越限标签字符串
*
* @param item 越限统计数据
* @return 越限标签
*/
private String buildOverlimitTag(RStatLimitRateDPO item) {
String tag = "";
// 基础越限项
Integer freqDevOvertime = item.getFreqDevOvertime();
if (freqDevOvertime > 0) {
tag = tag + "频率偏差越限" + freqDevOvertime + "次,";
}
Integer voltageDevOvertime = item.getVoltageDevOvertime();
if (voltageDevOvertime > 0) {
tag = tag + "电压偏差越限" + voltageDevOvertime + "次,";
}
Integer ubalanceOvertime = item.getUbalanceOvertime();
if (ubalanceOvertime > 0) {
tag = tag + "三相电压不平衡度越限" + ubalanceOvertime + "次,";
}
Integer flickerOvertime = item.getFlickerOvertime();
if (flickerOvertime > 0) {
tag = tag + "闪变越限" + flickerOvertime + "次,";
}
Integer uaberranceOvertime = item.getUaberranceOvertime();
if (uaberranceOvertime > 0) {
tag = tag + "电压总谐波畸变率越限" + uaberranceOvertime + "次,";
}
Integer iNegOvertime = item.getINegOvertime();
if (iNegOvertime > 0) {
tag = tag + "负序电流越限" + iNegOvertime + "次,";
}
// 谐波电压含有率2-25 次)
tag = buildHarmonicVoltageTags(item, tag);
// 谐波电流有效值2-25 次)
tag = buildHarmonicCurrentTags(item, tag);
// 间谐波电压含有率0.5-15.5 次)
tag = buildInterharmonicVoltageTags(item, tag);
// 去除末尾逗号
return trimTrailingComma(tag);
}
/**
* 批量构建谐波电压含有率 tag2-25 次)
*
* @param item 数据对象
* @param originalTag 原始 tag
* @return 组装后的 tag
*/
public static String buildHarmonicVoltageTags(Object item, String originalTag) {
String tag = originalTag;
for (int i = 2; i <= 25; i++) {
String fieldName = "uharm" + i + "Overtime";
Integer value = (Integer) ReflectUtil.getFieldValue(item, fieldName);
if (value != null && value > 0) {
tag = tag + i + "次谐波电压含有率越限" + value + "次,";
}
}
return tag;
}
/**
* 批量构建谐波电流有效值 tag2-25 次)
*
* @param item 数据对象
* @param originalTag 原始 tag
* @return 组装后的 tag
*/
public static String buildHarmonicCurrentTags(Object item, String originalTag) {
String tag = originalTag;
for (int i = 2; i <= 25; i++) {
String fieldName = "iharm" + i + "Overtime";
Integer value = (Integer) ReflectUtil.getFieldValue(item, fieldName);
if (value != null && value > 0) {
tag = tag + i + "次谐波电流有效值越限" + value + "次,";
}
}
return tag;
}
/**
* 批量构建间谐波电压含有率 tag0.5-15.5 次)
*
* @param item 数据对象
* @param originalTag 原始 tag
* @return 组装后的 tag
*/
public static String buildInterharmonicVoltageTags(Object item, String originalTag) {
String tag = originalTag;
for (int i = 1; i <= 16; i++) {
String fieldName = "inuharm" + i + "Overtime";
Integer value = (Integer) ReflectUtil.getFieldValue(item, fieldName);
if (value != null && value > 0) {
double harmonicOrder = i * 1.0 - 0.5;
tag = tag + harmonicOrder + "次间谐波电压含有率越限" + value + "次,";
}
}
return tag;
}
/**
* 去除字符串末尾的逗号
*
* @param str 原字符串
* @return 处理后的字符串
*/
public static String trimTrailingComma(String str) {
return StrUtil.endWith(str, ",") ? StrUtil.subPre(str, str.length() - 1) : str;
}
}

73
pom.xml
View File

@@ -38,11 +38,44 @@
<!-- <nacos.url>${middle.server.url}:18848</nacos.url>--> <!-- <nacos.url>${middle.server.url}:18848</nacos.url>-->
<!-- <nacos.namespace>b0b0dedf-baa9-407f-bef6-988b9e0a640d</nacos.namespace>--> <!-- <nacos.namespace>b0b0dedf-baa9-407f-bef6-988b9e0a640d</nacos.namespace>-->
<middle.server.url>192.168.1.103</middle.server.url> <!--103 测试环境-->
<service.server.url>192.168.2.126</service.server.url> <!-- <middle.server.url>192.168.1.103</middle.server.url>-->
<docker.server.url>192.168.1.103</docker.server.url> <!-- <service.server.url>192.168.2.126</service.server.url>-->
<nacos.url>${middle.server.url}:18848</nacos.url> <!-- <docker.server.url>192.168.1.103</docker.server.url>-->
<nacos.namespace>72972c43-3c20-4452-a261-66624e17da97</nacos.namespace> <!-- <nacos.url>${middle.server.url}:18848</nacos.url>-->
<!-- <nacos.namespace>72972c43-3c20-4452-a261-66624e17da97</nacos.namespace>-->
<middle.server.url>192.168.1.102</middle.server.url>
<service.server.url>192.168.1.102</service.server.url>
<docker.server.url>192.168.1.102</docker.server.url>
<nacos.url>${middle.server.url}:38848</nacos.url>
<nacos.namespace></nacos.namespace>
<!-- <middle.server.url>192.168.1.102</middle.server.url>-->
<!-- <service.server.url>192.168.2.126</service.server.url>-->
<!-- <docker.server.url>192.168.1.102</docker.server.url>-->
<!-- <nacos.url>${middle.server.url}:38848</nacos.url>-->
<!-- <nacos.namespace></nacos.namespace>-->
<!-- <middle.server.url>192.168.1.102</middle.server.url>-->
<!-- <service.server.url>192.168.2.126</service.server.url>-->
<!-- <docker.server.url>192.168.1.102</docker.server.url>-->
<!-- <nacos.url>${middle.server.url}:38848</nacos.url>-->
<!-- <nacos.namespace>ec678e30-97aa-4e50-a9f1-fbf8a5e3833f</nacos.namespace>-->
<!--李凡测试环境-->
<!-- <middle.server.url>192.168.2.134</middle.server.url>-->
<!-- <service.server.url>192.168.2.134</service.server.url>-->
<!-- <docker.server.url>192.168.2.134</docker.server.url>-->
<!-- <nacos.url>${middle.server.url}:18848</nacos.url>-->
<!-- <nacos.namespace></nacos.namespace>-->
<!--103 归档环境-->
<!-- <middle.server.url>192.168.1.103</middle.server.url>-->
<!-- <service.server.url>192.168.2.126</service.server.url>-->
<!-- <docker.server.url>192.168.1.103</docker.server.url>-->
<!-- <nacos.url>${middle.server.url}:18848</nacos.url>-->
<!-- <nacos.namespace>29a9e805-0e63-4c3a-9520-ddee9d7ff758</nacos.namespace>-->
<!-- <middle.server.url>192.168.1.103</middle.server.url>--> <!-- <middle.server.url>192.168.1.103</middle.server.url>-->
<!-- <service.server.url>192.168.1.103</service.server.url>--> <!-- <service.server.url>192.168.1.103</service.server.url>-->
@@ -50,6 +83,25 @@
<!-- <nacos.url>${middle.server.url}:18848</nacos.url>--> <!-- <nacos.url>${middle.server.url}:18848</nacos.url>-->
<!-- <nacos.namespace></nacos.namespace>--> <!-- <nacos.namespace></nacos.namespace>-->
<!-- <middle.server.url>192.168.1.103</middle.server.url>-->
<!-- <service.server.url>192.168.2.126</service.server.url>-->
<!-- <docker.server.url>192.168.1.103</docker.server.url>-->
<!-- <nacos.url>${middle.server.url}:18848</nacos.url>-->
<!-- <nacos.namespace></nacos.namespace>-->
<!--103金仓-->
<!-- <middle.server.url>192.168.1.103</middle.server.url>-->
<!-- <service.server.url>192.168.2.126</service.server.url>-->
<!-- <docker.server.url>192.168.1.103</docker.server.url>-->
<!-- <nacos.url>${middle.server.url}:18848</nacos.url>-->
<!-- <nacos.namespace>62aba33d-a6ce-497b-9d42-f353a28d5f59</nacos.namespace>-->
<!-- <middle.server.url>192.168.1.162</middle.server.url>-->
<!-- <service.server.url>192.168.1.162</service.server.url>-->
<!-- <docker.server.url>192.168.1.162</docker.server.url>-->
<!-- <nacos.url>${middle.server.url}:18848</nacos.url>-->
<!-- <nacos.namespace></nacos.namespace>-->
<!-- <middle.server.url>172.20.10.6</middle.server.url>--> <!-- <middle.server.url>172.20.10.6</middle.server.url>-->
<!-- <service.server.url>172.20.10.6</service.server.url>--> <!-- <service.server.url>172.20.10.6</service.server.url>-->
<!-- <docker.server.url>172.20.10.6</docker.server.url>--> <!-- <docker.server.url>172.20.10.6</docker.server.url>-->
@@ -94,6 +146,10 @@
<!-- <nacos.url>${middle.server.url}:8848</nacos.url>--> <!-- <nacos.url>${middle.server.url}:8848</nacos.url>-->
<!-- <nacos.namespace>07267985-7a34-4389-bb1e-47ff06cfc792</nacos.namespace>--> <!-- <nacos.namespace>07267985-7a34-4389-bb1e-47ff06cfc792</nacos.namespace>-->
<!--nacos开启鉴权后的用户名-->
<nacos.username>nacos</nacos.username>
<!--nacos的ip:port-->
<nacos.password>njcnpqs</nacos.password>
<!--sentinel:port--> <!--sentinel:port-->
<sentinel.url>${middle.server.url}:8080</sentinel.url> <sentinel.url>${middle.server.url}:8080</sentinel.url>
<!--网关地址主要用于配置swagger中认证token--> <!--网关地址主要用于配置swagger中认证token-->
@@ -125,6 +181,7 @@
<mysql.version>8.0.19</mysql.version> <mysql.version>8.0.19</mysql.version>
<mariadb.version>2.4.0</mariadb.version> <mariadb.version>2.4.0</mariadb.version>
<oracle.version>21.6.0.0</oracle.version> <oracle.version>21.6.0.0</oracle.version>
<kingbase.version>9.0.0</kingbase.version>
<orai18n.version>21.1.0.0</orai18n.version> <orai18n.version>21.1.0.0</orai18n.version>
<mybatis-plus.version>3.4.2</mybatis-plus.version> <mybatis-plus.version>3.4.2</mybatis-plus.version>
<dynamic-datasource.version>3.5.1</dynamic-datasource.version> <dynamic-datasource.version>3.5.1</dynamic-datasource.version>
@@ -257,6 +314,11 @@
<artifactId>ojdbc8</artifactId> <artifactId>ojdbc8</artifactId>
<version>${oracle.version}</version> <version>${oracle.version}</version>
</dependency> </dependency>
<dependency>
<groupId>cn.com.kingbase</groupId>
<artifactId>kingbase8</artifactId>
<version>${kingbase.version}</version>
</dependency>
<!-- 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK --> <!-- 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK -->
<dependency> <dependency>
<groupId>com.oracle.database.nls</groupId> <groupId>com.oracle.database.nls</groupId>
@@ -380,6 +442,7 @@
<artifactId>xxl-job-core</artifactId> <artifactId>xxl-job-core</artifactId>
<version>${xxl-job.version}</version> <version>${xxl-job.version}</version>
</dependency> </dependency>
<!--mqtt相关依赖-->
<dependency> <dependency>
<groupId>com.github.tocrhz</groupId> <groupId>com.github.tocrhz</groupId>
<artifactId>mqtt-spring-boot-starter</artifactId> <artifactId>mqtt-spring-boot-starter</artifactId>