Compare commits

...

75 Commits

Author SHA1 Message Date
412e97c4f1 1.区分辽宁通用功能调整 2026-07-17 10:04:38 +08:00
wr
60a519d996 1.微调 2026-07-16 17:40:37 +08:00
wr
16c95aa2f6 1.调整污染值监测点逻辑
2.解决devices模块Swagger页面无法展示问题
2026-07-16 17:19:49 +08:00
cdf
e313894417 添加前置类型 2026-07-15 13:17:20 +08:00
xy
a4e3a2f904 fix(user): 更新用户消息默认配置中的谐波信息设置
- 将用户的谐波信息默认值从0修改为1
- 保持其他消息类型配置不变
2026-07-14 16:10:34 +08:00
xy
840263d53b fix(harmonic): 修复电压闪变异常数据处理中的空指针问题
- 添加对 MAX 对象和闪变限制值的空值检查
- 为 CP95、AVG 和 MIN 数据点添加空值验证
- 防止在数据缺失时发生 NullPointerException
- 重构条件判断逻辑以提高代码健壮性
- 保留原有功能并增强错误处理能力
2026-07-13 10:18:44 +08:00
4a04c8f764 1.调整终端周期检测功能 2026-07-10 12:07:57 +08:00
wr
def4c066fe 1.微调 2026-07-08 16:58:59 +08:00
wr
5269496f24 1.微调 2026-07-08 15:38:40 +08:00
f594915363 1.添加终端周期检测功能 2026-07-08 09:21:30 +08:00
xy
29ca1e4a5f feat(EleEpdPqd): 添加根据告警码获取数据功能
- 在控制器中新增 findListByCode 方法实现告警码查询
- 在 Feign 客户端接口中添加对应的远程调用方法
- 在降级工厂中实现相应的异常处理逻辑
- 添加了参数验证注解支持
- 集成了 Swagger 文档注解便于接口文档生成
2026-07-07 20:29:40 +08:00
xy
2b0c5e82fa limitRate算法优化 2026-07-07 19:10:46 +08:00
6ddbdbb5be 1.添加终端周期检测功能 2026-07-07 10:21:55 +08:00
xy
0d3dd0748c feat(file): 添加四通道波形图生成功能
- 增加 Objects 工具类导入用于对象比较
- 实现四通道波形图的处理逻辑,支持 4 个数据详情的绘制
- 添加 getTitle2 方法用于生成电压电流标题
- 实现 composeImage 方法用于合成四张图片为一张
- 扩展波形图生成逻辑以支持瞬时数据和有效值数据的四通道显示
2026-07-06 13:30:10 +08:00
1cd3283ba5 1.迁移接口,简化部署模块 2026-07-02 14:11:49 +08:00
ce9b2b62d9 1.调整适配辽宁现场新能源场站 2026-07-01 15:14:57 +08:00
wr
687f878b5f 1.解决有功功率趋势统计调用ataprocessboot接口改造 2026-07-01 11:27:46 +08:00
764a7b1953 1.调整适配辽宁现场新能源场站 2026-07-01 10:28:50 +08:00
xy
26fa401acb Merge remote-tracking branch 'origin/main' 2026-06-29 11:44:49 +08:00
xy
88a99dbe9c fix(sys-dic-tree): 修复字典树查询状态过滤问题
- 在字典树查询中添加状态过滤条件 a.status = 0
- 确保只返回状态为可用的数据记录
- 修复了可能导致无效数据被查询到的逻辑缺陷
2026-06-29 11:44:38 +08:00
ae14d9a820 1.调整适配辽宁现场新能源场站 2026-06-29 10:38:13 +08:00
xy
709262c2b4 fix(auth): 解决非手机号注册用户查询异常及自动登录接口配置问题
- 在AppInfoSetController中添加空值检查,抛出业务异常提示非手机号注册用户需联系管理员
- 修改AuthController中自动登录接口为POST方法并更新相关参数配置
- 更新用户权限类型参数验证范围从0-2扩展到0-3以支持更多权限类型
2026-06-26 15:22:56 +08:00
e2e7669d47 1.限值负序电流调整 2026-06-26 11:52:29 +08:00
83907cd3ee 1.bug调整 2026-06-25 18:27:44 +08:00
xy
5a0e990f90 refactor(service): 移除线路治理状态设置逻辑
- 注释掉线路治理状态的条件判断代码
- 删除未治理和已治理状态的设置逻辑
- 保留其他线路信息设置功能
2026-06-25 15:52:50 +08:00
f00af22b33 1.台账增加默认排序
2.增加场站/用户监测规模接口
2026-06-23 21:30:27 +08:00
xy
7f13d3576d feat(user): 添加手机号重复注册检查并调整默认消息设置
- 添加手机号唯一性验证逻辑,防止重复注册
- 新增 REGISTER_PHONE_REPEAT 业务异常枚举
- 调整新用户默认消息配置:harmonicInfo从1改为0
- 调整新用户默认消息配置:runInfo从1改为0
- 调整新用户默认消息配置:alarmInfo从1改为0
2026-06-22 19:58:41 +08:00
xy
c4f5d1b543 refactor(dict): 重构字典类型查询方法参数类型
- 将 queryDictType 方法的 lineId 参数从 String 类型改为 Integer 类型
- 更新接口定义中的参数类型声明
- 修改控制器层方法签名以匹配新的参数类型
- 调整业务逻辑中对参数的处理方式,从字符串末尾字符判断改为整数比较
- 移除不再需要的 SysDicTreePOMapper 导入
- 更新 API 文档注解中的参数描述信息
2026-06-22 13:45:54 +08:00
xy
6451cfeb88 refactor(gateway): 移除CS系统应用版本获取接口配置
- 移除 /cs-system-boot/appVersion/getLastData 接口路径配置
- 清理相关的历史数据分析接口配置项
- 优化网关路由规则避免不必要的路径暴露
2026-06-18 15:44:52 +08:00
xy
6eedee7783 fix(user): 修复用户注册逻辑并更新Redis键格式
- 修改设备模板和监测点位置的Redis键格式,统一添加冒号后缀
- 移除未使用的ResponseEntity导入
- 简化用户注册流程,移除重复的手机号验证逻辑
- 在网关配置中添加新的白名单接口路径
2026-06-18 15:29:05 +08:00
hzj
21fe98db49 修改生成报告画图采样率 2026-06-18 10:21:07 +08:00
hzj
bf9779c06e 暂态原因计算问题 2026-06-17 16:06:29 +08:00
cdf
368103cad5 Merge remote-tracking branch 'origin/main' 2026-06-17 14:21:17 +08:00
cdf
507a7f7a09 辽宁CAS统一认证兼容 2026-06-17 14:19:52 +08:00
wr
c1dfcb9236 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	pqs-device/pq-device/pq-device-boot/src/main/java/com/njcn/device/pq/service/impl/RStatIntegrityDServiceImpl.java
2026-06-17 14:14:16 +08:00
wr
f5eb2c7af6 1.解决数据质量监测点数据完整性查询过慢问题 2026-06-17 14:11:24 +08:00
hzj
d36c30973d 添加日志查询慢接口 2026-06-17 13:54:44 +08:00
hzj
148e834f9c 代码优化 2026-06-16 16:25:50 +08:00
hzj
9a9a8151d9 代码优化 2026-06-16 15:55:22 +08:00
hzj
ca8bd9fea2 优化前置切换装置进程重置代码 2026-06-16 14:52:03 +08:00
wr
770b707b84 1.前置交互日志扩展模糊查询
2.解决暂态时间12小时制的问题
3.优化文件工具类
2026-06-16 09:58:24 +08:00
0196277eb2 1.台账增加默认排序
2.增加场站/用户监测规模接口
2026-06-15 10:21:14 +08:00
hzj
6e4a294b00 Merge remote-tracking branch 'origin/main' 2026-06-12 10:25:07 +08:00
xy
1e5acdd214 feat(mq): 添加日志消息处理功能
- 在BusinessTopic中新增ZL_LOG_TOPIC常量
- 添加LogTag接口用于日志标签定义
- 创建LogMessage类定义日志消息结构
- 实现LogMessageTemplate用于发送日志消息
- 集成RocketMQ增强模板支持日志消息发送
- 定义日志消息的数据类型和操作字段
2026-06-11 19:55:24 +08:00
hzj
2754969dfc 暂态高级算法异步 2026-06-11 16:59:16 +08:00
hzj
4c083c84e5 oss兼容 2026-06-10 17:51:24 +08:00
hzj
6e26c81ff9 oss兼容 2026-06-10 16:14:56 +08:00
hzj
ba7ae8da9e oss兼容 2026-06-10 16:08:37 +08:00
hzj
ef6c464897 oss兼容 2026-06-10 15:55:20 +08:00
hzj
743cbfbdcb 暂降报告修改 2026-06-09 15:46:34 +08:00
hzj
48cddd92b0 暂降报告修改 2026-06-09 11:09:19 +08:00
cdf
ee5526b0f7 区域报告修改,添加间谐波电压含有率 2026-06-08 16:38:15 +08:00
cdf
11306f1d00 区域报告修改,添加间谐波电压含有率 2026-06-08 16:33:53 +08:00
hzj
85ab4de719 区域报表修改 2026-06-08 11:30:36 +08:00
xy
552573df00 暂态报告新增是否只统计暂降条件 2026-06-08 10:13:47 +08:00
cdf
50181459bf 区域报告修改,添加间谐波电压含有率 2026-06-07 15:55:50 +08:00
cdf
748fd62afb Merge remote-tracking branch 'origin/main' 2026-06-05 18:42:14 +08:00
hzj
749c1d954c 区域报表修改 2026-06-05 16:32:55 +08:00
xy
6089be6b4a feat(report): 电压暂降事件报告导出功能优化 2026-06-05 11:16:15 +08:00
xy
eb89472670 微调 2026-06-04 18:28:51 +08:00
xy
56cd9a05c3 feat(echarts): 添加波形图绘制功能支持
- 新增drawWavePic方法用于绘制波形图
- 实现null数据段压缩算法,确保图表性能优化
- 添加markLine和markArea功能显示null段边界标记
- 集成到WavePicComponent组件中支持瞬时和RMS波形图生成
- 修复RestTemplate对Hutool JSON对象的支持问题
- 优化WaveUtil工具类处理空值数据逻辑
2026-06-04 18:27:47 +08:00
xy
aafd32c7fc refactor(sms): 重构短信发送功能并优化数据库配置
- 移除旧的短信发送实现和相关依赖
- 引入新的短信发送服务接口和实现
- 添加短信发送记录实体和数据访问层
- 创建短信发送控制器提供REST API
- 实现带重试机制的短信发送功能
- 添加系统凭证管理和缓存机制
- 更新数据库连接配置信息
- 修改统计查询接口参数类型
- 清理过时的代码和服务方法
2026-06-03 10:20:25 +08:00
cdf
46969f7e02 Merge remote-tracking branch 'origin/main' 2026-06-01 10:02:47 +08:00
xy
79cec4e21b feat(event): 新增压降落点区域判定功能
- 在EventAnalysisService中添加determineDropZone方法用于判定压降落点区域
- 实现压降落点区域判定逻辑,支持A/B/C/D四个区域的分类判断
- 添加精确的数值范围匹配算法,使用BigDecimal确保计算精度
- 集成日志记录功能,便于问题排查和监控
- 在RedisUtil中新增scanKeysByPattern方法支持模糊查询key功能
- 优化代码结构,移除冗余的导入包和空行
- 更新类级别的注解配置,添加@Slf4j注解支持日志功能
2026-05-27 18:10:15 +08:00
hzj
615fe78d61 辽宁稳态指标超标明细等页面丰富查询条件; 2026-05-22 14:05:53 +08:00
hzj
5fff0890e8 数据清洗移动包修改 2026-05-21 15:15:24 +08:00
hzj
f5e134b194 数据清洗移动包修改 2026-05-21 15:00:13 +08:00
hzj
291a20649e 添加控制task是否执行配置business:task-enabled: false为true是执行,false不执行,缺省默认为true只行,只有没有前置微服务版本配置false; 2026-05-21 11:11:38 +08:00
cdf
fdd6ff574f Merge remote-tracking branch 'origin/main' 2026-05-20 17:00:58 +08:00
hzj
7eef16599f 台账模版导入功能修复 2026-05-20 15:58:48 +08:00
xy
11750a4f3a fix(service): 修正电力参数默认相位设置
- 将新增记录时的默认相位从"M"改为"T"
- 将更新记录时的默认相位从"M"改为"T"
- 确保相位字段在空值情况下统一使用"T"作为默认值
2026-05-20 14:18:03 +08:00
cdf
e5ffa2ec29 修改自定义报表处理没有模板情况,使用默认模板 2026-05-18 16:13:28 +08:00
hzj
e6332f1c51 装置文件系统访问 2026-05-15 13:36:51 +08:00
cdf
23d87aecc8 修改自定义报表适配分钟/统计数据查询 2026-05-14 17:05:43 +08:00
xy
eff784e94e feat(mq): 添加治理心跳过期处理消息功能 2026-05-14 09:20:42 +08:00
192 changed files with 7761 additions and 3200 deletions

View File

@@ -129,10 +129,10 @@ public class EventRelevantAnalysisController extends BaseController {
@PostMapping("/updateEventToAss") @PostMapping("/updateEventToAss")
@ApiOperation("把暂降事件添加到指定事件中去") @ApiOperation("把暂降事件添加到指定事件中去")
public HttpResult<Page<AdvanceEventDetailVO>> updateEventToAss(@RequestBody Map<String,Object> map){ public HttpResult<Page<AdvanceEventDetailVO>> updateEventToAss(@RequestBody Map<String,Object> map){
if(!map.containsKey("eventId") || !map.containsKey("assId")){
throw new BusinessException("参数异常");
}
String methodDescribe = getMethodDescribe("updateEventToAss"); String methodDescribe = getMethodDescribe("updateEventToAss");
if(!map.containsKey("eventId") || !map.containsKey("assId")){
throw new BusinessException("参数异常");
}
List<String> eventIds = (List<String>) map.get("eventId"); List<String> eventIds = (List<String>) map.get("eventId");
if(CollectionUtil.isEmpty(eventIds)){ if(CollectionUtil.isEmpty(eventIds)){
throw new BusinessException("暂降事件不可为空"); throw new BusinessException("暂降事件不可为空");

View File

@@ -7,7 +7,6 @@ import com.njcn.advance.event.cause.model.DataFeature;
import com.njcn.advance.event.type.jna.*; import com.njcn.advance.event.type.jna.*;
import com.njcn.advance.pojo.dto.EventAnalysisDTO; import com.njcn.advance.pojo.dto.EventAnalysisDTO;
import com.njcn.advance.event.service.IEventAdvanceService; import com.njcn.advance.event.service.IEventAdvanceService;
import com.njcn.advance.pojo.dto.waveAnalysis.Rect;
import com.njcn.advance.utils.Utils; import com.njcn.advance.utils.Utils;
import com.njcn.common.config.GeneralInfo; import com.njcn.common.config.GeneralInfo;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
@@ -26,6 +25,8 @@ import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/** /**
* @author hongawen * @author hongawen
@@ -43,10 +44,14 @@ public class EventAdvanceServiceImpl implements IEventAdvanceService {
private final FileStorageUtil fileStorageUtil; private final FileStorageUtil fileStorageUtil;
private final Lock lock = new ReentrantLock();
@Override @Override
public EventAnalysisDTO analysisCauseAndType(EventAnalysisDTO eventAnalysis) { public EventAnalysisDTO analysisCauseAndType(EventAnalysisDTO eventAnalysis) {
WaveDataDTO waveDataDTO; //由于计算原因是异步操作这里需要加锁不然JNI调用ddl文件会存在内存Invalid memory access
lock.lock();
try {
WaveDataDTO waveDataDTO;
String waveName = eventAnalysis.getWaveName(); String waveName = eventAnalysis.getWaveName();
String wlFilePath = eventAnalysis.getWlFilePath(); String wlFilePath = eventAnalysis.getWlFilePath();
String cfgPath, datPath, cfgPath2, datPath2; String cfgPath, datPath, cfgPath2, datPath2;
@@ -112,7 +117,6 @@ public class EventAdvanceServiceImpl implements IEventAdvanceService {
try { try {
QvvrDLL.INSTANCE.qvvr_fun(typeDataStruct); QvvrDLL.INSTANCE.qvvr_fun(typeDataStruct);
System.out.println("调用qvvrdll成功-----------"); System.out.println("调用qvvrdll成功-----------");
if (typeDataStruct.evt_num > 0) { if (typeDataStruct.evt_num > 0) {
// 全局比较找出最小三相电压特征值 // 全局比较找出最小三相电压特征值
float globalMinVoltage = Float.MAX_VALUE; float globalMinVoltage = Float.MAX_VALUE;
@@ -127,25 +131,14 @@ public class EventAdvanceServiceImpl implements IEventAdvanceService {
} }
} }
} }
String str = WriteData2File(typeDataStruct);
if (Objects.isNull(wlFilePath)) {
String hdrPath = OssPath.WAVE_DIR + ip+StrUtil.SLASH;
String hdrName = waveName + GeneralConstant.HDR_LOWER;
fileStorageUtil.uploadStreamSpecifyName(new ByteArrayInputStream(str.getBytes()),hdrPath,hdrName);
} else {
// comtrade/00:B7:8D:00:A8:7A/PQMonitor_PQM1_00100_20260204_162453_071_WAV.hdr
String fullPath = wlFilePath + GeneralConstant.HDR_LOWER;
int lastSlashIndex = fullPath.lastIndexOf('/');
String hdrPath = fullPath.substring(0, lastSlashIndex + 1);
String hdrName = fullPath.substring(lastSlashIndex + 1);
fileStorageUtil.uploadStreamSpecifyName(new ByteArrayInputStream(str.getBytes()),hdrPath,hdrName);
}
//上传HR //上传HR
eventAnalysis.setType(globalFaultType); eventAnalysis.setType(globalFaultType);
} else { } else {
eventAnalysis.setType(DataFeature.TYPE10); eventAnalysis.setType(DataFeature.TYPE10);
} }
System.out.println("结束qvvrdll方法调用-----------"); System.out.println("结束qvvrdll方法调用-----------");
} catch (Exception e) { } catch (Exception e) {
eventAnalysis.setType(DataFeature.TYPE10); eventAnalysis.setType(DataFeature.TYPE10);
@@ -174,12 +167,33 @@ public class EventAdvanceServiceImpl implements IEventAdvanceService {
eventAnalysis.setCause(DataFeature.CAUSE_TYPE0); eventAnalysis.setCause(DataFeature.CAUSE_TYPE0);
eventAnalysis.setCauseFlag(0); eventAnalysis.setCauseFlag(0);
} }
String str = null;
try {
str = WriteData2File(typeDataStruct,causeDataStruct);
} catch (Exception e) {
throw new RuntimeException(e);
}
if (Objects.isNull(wlFilePath)) {
String hdrPath = OssPath.WAVE_DIR + ip+StrUtil.SLASH;
String hdrName = waveName + GeneralConstant.HDR_LOWER;
fileStorageUtil.uploadStreamSpecifyName(new ByteArrayInputStream(str.getBytes()),hdrPath,hdrName);
} else {
// comtrade/00:B7:8D:00:A8:7A/PQMonitor_PQM1_00100_20260204_162453_071_WAV.hdr
String fullPath = wlFilePath + GeneralConstant.HDR_LOWER;
int lastSlashIndex = fullPath.lastIndexOf('/');
String hdrPath = fullPath.substring(0, lastSlashIndex + 1);
String hdrName = fullPath.substring(lastSlashIndex + 1);
fileStorageUtil.uploadStreamSpecifyName(new ByteArrayInputStream(str.getBytes()),hdrPath,hdrName);
}
System.out.println("暂降原因分析完毕==============="); System.out.println("暂降原因分析完毕===============");
System.out.println("cause:" + eventAnalysis); System.out.println("cause:" + eventAnalysis);
} finally {
lock.unlock(); // 释放锁
}
return eventAnalysis; return eventAnalysis;
} }
public String WriteData2File(QvvrDLL.QvvrDataStruct rect) throws Exception { public String WriteData2File(QvvrDLL.QvvrDataStruct rect, QvvrCauseDLL.QvvrDataStruct causeDataStruct) throws Exception {
StringBuilder stringBuilder = new StringBuilder("{" + EnumEvt.NEWLINE.getProperty()); StringBuilder stringBuilder = new StringBuilder("{" + EnumEvt.NEWLINE.getProperty());
/** /**
@@ -414,7 +428,7 @@ public class EventAdvanceServiceImpl implements IEventAdvanceService {
*/ */
for (int k = 0; k < rect.evt_buf[i].u_min_num; k++) { for (int k = 0; k < rect.evt_buf[i].u_min_num; k++) {
setEigenVlaue(k, stringBuilder, EnumEvt.QVVR_CATA_CAUSE.getProperty(), null, setEigenVlaue(k, stringBuilder, EnumEvt.QVVR_CATA_CAUSE.getProperty(), null,
rect.evt_buf[i].qvvr_cata_cause[k]); causeDataStruct.cause);
if (rect.evt_buf[i].u_min_num - 1 == k) { if (rect.evt_buf[i].u_min_num - 1 == k) {
stringBuilder.delete(stringBuilder.lastIndexOf(","), stringBuilder.length() - 1); stringBuilder.delete(stringBuilder.lastIndexOf(","), stringBuilder.length() - 1);
@@ -458,6 +472,10 @@ public class EventAdvanceServiceImpl implements IEventAdvanceService {
stringBuilder.append(EnumEvt.setEnter(EnumEvt.setClose(2), 2)); stringBuilder.append(EnumEvt.setEnter(EnumEvt.setClose(2), 2));
} }
} }
if(rect.evt_num==0){
stringBuilder.append("]");
}
stringBuilder.append("}"); stringBuilder.append("}");
return stringBuilder.toString(); return stringBuilder.toString();

View File

@@ -168,7 +168,7 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
EntityGroupEvtData[] arrayObj = Arrays.copyOfRange(entityGroupEvtData, EntityGroupEvtData[] arrayObj = Arrays.copyOfRange(entityGroupEvtData,
i * FinalData.MAX_EVT_NUM, to); i * FinalData.MAX_EVT_NUM, to);
EntityMtrans entityMtrans = mEntry.getValue(); EntityMtrans entityMtrans = mEntry.getValue();
EntityGroupData entityGroupData = handleEvent.translate(arrayObj,entityMtrans); EntityGroupData entityGroupData = handleEvent.translate(arrayObj, entityMtrans);
// 处理分析结果 // 处理分析结果
handleEvent.show_group_info(entityGroupData, listSagEvent, listEventAssObj, date); handleEvent.show_group_info(entityGroupData, listSagEvent, listEventAssObj, date);
} }
@@ -177,51 +177,44 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
} }
disposeNonStandardData(handleEvent, baseList, listEventAssObj, listSagEvent, date);
int listSize = listEventAssObj.size();
int toIndex = 1000;
for (int i = 0; i < listSize; i += 1000) {
//作用为toIndex最后没有toIndex条数据则剩余几条newList中就装几条
disposeNonStandardData(handleEvent, baseList, listEventAssObj, listSagEvent, date); if (i + 1000 > listSize) {
toIndex = listSize - i;
int listSize = listEventAssObj.size();
int toIndex = 1000;
for (int i = 0; i < listSize; i += 1000) {
//作用为toIndex最后没有toIndex条数据则剩余几条newList中就装几条
if (i + 1000 > listSize) {
toIndex = listSize - i;
}
//分割lst
List<EventAssObj> newList = listEventAssObj.subList(i, i + toIndex);
//写入添加方法,需要写你的新增方法把newList分切后的数据新增进入数据库。
rmpEventDetailAssMapper.insertEventAssData(newList);
} }
//分割lst
List<EventAssObj> newList = listEventAssObj.subList(i, i + toIndex);
//写入添加方法,需要写你的新增方法把newList分切后的数据新增进入数据库。
rmpEventDetailAssMapper.insertEventAssData(newList);
}
List<RmpEventDetailPO> eventUpdateList = new ArrayList<>(); List<RmpEventDetailPO> eventUpdateList = new ArrayList<>();
for (int i = 0; i < listSagEvent.size(); i++) { for (int i = 0; i < listSagEvent.size(); i++) {
RmpEventDetailPO rmp = new RmpEventDetailPO(); RmpEventDetailPO rmp = new RmpEventDetailPO();
rmp.setEventId(listSagEvent.get(i).getIndexEventDetail()); rmp.setEventId(listSagEvent.get(i).getIndexEventDetail());
rmp.setEventassIndex(listSagEvent.get(i).getIndexEventAss()); rmp.setEventassIndex(listSagEvent.get(i).getIndexEventAss());
rmp.setDealTime(listSagEvent.get(i).getDealTime()); rmp.setDealTime(listSagEvent.get(i).getDealTime());
eventUpdateList.add(rmp); eventUpdateList.add(rmp);
if ((i + 1) % 1000 == 0) { if ((i + 1) % 1000 == 0) {
this.updateBatchById(eventUpdateList); this.updateBatchById(eventUpdateList);
eventUpdateList.clear(); eventUpdateList.clear();
} else if (i == listSagEvent.size() - 1) { } else if (i == listSagEvent.size() - 1) {
this.updateBatchById(eventUpdateList); this.updateBatchById(eventUpdateList);
}
} }
}
// 增加策略记录 // 增加策略记录
String describe = "用户" + RequestUtil.getUserNickname() + "进行了关联分析"; String describe = "用户" + RequestUtil.getUserNickname() + "进行了关联分析";
PqsRelevanceLog entityPqsRelevance = new PqsRelevanceLog(); PqsRelevanceLog entityPqsRelevance = new PqsRelevanceLog();
entityPqsRelevance.setContentDes(describe); entityPqsRelevance.setContentDes(describe);
entityPqsRelevance.setState(DataStateEnum.ENABLE.getCode()); entityPqsRelevance.setState(DataStateEnum.ENABLE.getCode());
entityPqsRelevance.setTimeId(date); entityPqsRelevance.setTimeId(date);
relevantLogMapper.insert(entityPqsRelevance); relevantLogMapper.insert(entityPqsRelevance);
log.info("事件关联分析用时:" + timeInterval.interval() / 1000 + ""); log.info("事件关联分析用时:" + timeInterval.interval() / 1000 + "");
@@ -230,224 +223,6 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
// @Override
// @Transactional(rollbackFor = Exception.class)
// public void processEvents(LocalDateTime startTime, LocalDateTime endTime) {
//
// TimeInterval timeInterval = new TimeInterval();
//
//
// Map<String, Map<String, Integer>> nodeSort = new HashMap<>();
// Map<String, EntityMtrans> entityMtransMap = getNodeInfo();
//
//
//
//
//
// for (Map.Entry<String, Map<String, Integer>> m : nodeSort) {
// List<EntityGroupEvtData> list = new ArrayList<EntityGroupEvtData>();
// Set<Map.Entry<String, Integer>> mapValue = m.getValue().entrySet();
// FinalData.NODE_NUM = m.getValue().size();
//
// for (Map.Entry<String, Integer> mm : mapValue) {
// for (int i = 0; i < entityGroupEvtDatas.length; i++) {
// if (entityGroupEvtDatas[i].getNodePhysics() == mm.getKey().intValue() && "短路故障".equals(entityGroupEvtDatas[i].getSagReason())) {
// entityGroupEvtDatas[i].setNode(mm.getValue());
// list.add(entityGroupEvtDatas[i]);
// }
// }
//
// // 筛选不在矩阵中的事件id
// Iterator<EntityGroupEvtData> iterator = list3.iterator();
// while (iterator.hasNext()) {
// EntityGroupEvtData entityGroupEvtData = iterator.next();
//
// if (entityGroupEvtData.getNodePhysics() == mm.getKey().intValue() && "短路故障".equals(entityGroupEvtData.getSagReason())) {
// iterator.remove();
// }
// }
// }
//
// EntityGroupEvtData[] entityGroupEvtData = new EntityGroupEvtData[list.size()];
// Collections.sort(list);
// list.toArray(entityGroupEvtData);
//
// for (Map.Entry<String, JSONObject> mEntry : setMtrans) {
// if (mEntry.getKey().equals(m.getKey())) {
// *//**//********************************************************************
// * 算法最多处理1000条数据超过限制需分批处理 先将数据根据某种方式进行升序/降序排序,然后分段处理 加入循环处理
// *********************************************************************//**//*
// int circulation = entityGroupEvtData.length % FinalData.MAX_EVT_NUM == 0
// ? entityGroupEvtData.length / FinalData.MAX_EVT_NUM
// : entityGroupEvtData.length / FinalData.MAX_EVT_NUM + 1;
//
// for (int i = 0; i < circulation; i++) {
// int to = 0;
//
// if (i == circulation - 1) {
// to = entityGroupEvtData.length % FinalData.MAX_EVT_NUM > 0
// ? entityGroupEvtData.length
// : (i + 1) * FinalData.MAX_EVT_NUM - 1;
// } else {
// to = (i + 1) * FinalData.MAX_EVT_NUM - 1;
// }
//
// EntityGroupEvtData[] arrayObj = Arrays.copyOfRange(entityGroupEvtData,
// i * FinalData.MAX_EVT_NUM, to);
// JSONObject entityMtrans = mEntry.getValue();
// EntityGroupData entityGroupData = handleEvent.translate(arrayObj, (EntityMtrans) JSONObject.toBean(entityMtrans, EntityMtrans.class));
// // 处理分析结果
// handleEvent.show_group_info(entityGroupData, listSagEvent, listEventAssObj, date);
// }
// }
// }
// }
//
//
// DictData dictData = dicDataFeignClient.getDicDataByNameAndTypeName(DicDataTypeEnum.EVENT_REASON.getName(), DicDataEnum.SHORT_TROUBLE.getName()).getData();
// if (Objects.isNull(dictData)) {
// throw new BusinessException(SystemResponseEnum.ADVANCE_REASON);
// }
//
//
// LocalDateTime date = LocalDateTime.now();
// HandleEvent handleEvent = new HandleEvent();
// // 分析的事件进行处理
// List<EntityGroupEvtData> baseList = handleEvent.getData(startTime, endTime);
// if (CollectionUtil.isEmpty(baseList)) {
// throw new BusinessException("当前时间段暂无可分析事件");
// }
//
// // 传入的处理事件根据物理隔绝进行分组
//
// List<EntityLogic> strategyList = relevantLogMapper.getLogic();
//
// if (CollectionUtil.isNotEmpty(strategyList)) {
// List<SagEvent> listSagEvent = new ArrayList<>();
// List<EventAssObj> listEventAssObj = new ArrayList<>();
//
// Map<String, List<String>> strategyToBusBarMap = new HashMap<>(32);
//
// Map<String, EntityMtrans> mapRedis = new HashMap<>(32);
//
// Map<String, List<EntityLogic>> strategyMap = strategyList.stream().collect(Collectors.groupingBy(EntityLogic::getTPIndex));
// strategyMap.forEach((key, list) -> {
// List<String> before = list.stream().map(EntityLogic::getNodeBefore).distinct().collect(Collectors.toList());
// List<String> after = list.stream().map(EntityLogic::getNodeNext).distinct().collect(Collectors.toList());
// before.addAll(after);
// before = before.stream().distinct().collect(Collectors.toList());
// strategyToBusBarMap.put(key, before);
//
// FinalData.NODE_NUM = before.size();
// EntityMtrans entityMtrans = new EntityMtrans();
// handleEvent.create_matrixcata(list, entityMtrans);
//
// mapRedis.put(key, entityMtrans);
// });
//
// strategyToBusBarMap.forEach((lastKey, lastVal) -> {
// int index = 1;
// List<EntityGroupEvtData> list = new ArrayList<>();
// for (EntityGroupEvtData entityGroupEvtData : baseList) {
// if (lastVal.contains(entityGroupEvtData.getNodePhysics()) && dictData.getId().equals(entityGroupEvtData.getSagReason())) {
// entityGroupEvtData.setNode(index++);
// list.add(entityGroupEvtData);
// }
// }
//
// baseList.removeIf(entityGroupEvtData -> lastVal.contains(entityGroupEvtData.getNodePhysics()) && dictData.getId().equals(entityGroupEvtData.getSagReason()));
//
//
// EntityGroupEvtData[] entityGroupEvtData = new EntityGroupEvtData[list.size()];
// Collections.sort(list);
// list.toArray(entityGroupEvtData);
//
// mapRedis.forEach((mKey, mVal) -> {
// if (mKey.equals(lastKey)) {
// //算法最多处理1000条数据超过限制需分批处理 先将数据根据某种方式进行升序/降序排序,然后分段处理 加入循环处理
// int circulation = entityGroupEvtData.length % FinalData.MAX_EVT_NUM == 0
// ? entityGroupEvtData.length / FinalData.MAX_EVT_NUM
// : entityGroupEvtData.length / FinalData.MAX_EVT_NUM + 1;
//
// for (int i = 0; i < circulation; i++) {
// int to;
// if (i == circulation - 1) {
// to = entityGroupEvtData.length % FinalData.MAX_EVT_NUM > 0
// ? entityGroupEvtData.length
// : (i + 1) * FinalData.MAX_EVT_NUM - 1;
// } else {
// to = (i + 1) * FinalData.MAX_EVT_NUM - 1;
// }
//
// EntityGroupEvtData[] arrayObj = Arrays.copyOfRange(entityGroupEvtData,
// i * FinalData.MAX_EVT_NUM, to);
// EntityGroupData entityGroupData = handleEvent.translate(arrayObj, mVal);
// // 处理分析结果
// handleEvent.show_group_info(entityGroupData, listSagEvent, listEventAssObj, date);
// }
// }
// });
//
// });
//
//
//
// //事件ID不在矩阵中结果集为基础以时标为标准进行归集处理 注意:三相与(单相/两相)互斥
//
// disposeNonStandardData(handleEvent, baseList, listEventAssObj, listSagEvent, date);
//
//
// int listSize = listEventAssObj.size();
// int toIndex = 1000;
// for (int i = 0; i < listSize; i += 1000) {
// //作用为toIndex最后没有toIndex条数据则剩余几条newList中就装几条
// if (i + 1000 > listSize) {
// toIndex = listSize - i;
// }
// //分割lst
// List<EventAssObj> newList = listEventAssObj.subList(i, i + toIndex);
// //写入添加方法,需要写你的新增方法把newList分切后的数据新增进入数据库。
// rmpEventDetailAssMapper.insertEventAssData(newList);
// }
//
// List<RmpEventDetailPO> eventUpdateList = new ArrayList<>();
// for (int i = 0; i < listSagEvent.size(); i++) {
// RmpEventDetailPO rmp = new RmpEventDetailPO();
// rmp.setEventId(listSagEvent.get(i).getIndexEventDetail());
// rmp.setEventassIndex(listSagEvent.get(i).getIndexEventAss());
// rmp.setDealTime(listSagEvent.get(i).getDealTime());
// eventUpdateList.add(rmp);
// if ((i + 1) % 1000 == 0) {
// this.updateBatchById(eventUpdateList);
// eventUpdateList.clear();
// } else if (i == listSagEvent.size() - 1) {
// this.updateBatchById(eventUpdateList);
// }
// }
//
// // 增加策略记录
// String describe = "用户" + RequestUtil.getUserNickname() + "进行了关联分析";
// PqsRelevanceLog entityPqsRelevance = new PqsRelevanceLog();
// entityPqsRelevance.setContentDes(describe);
// entityPqsRelevance.setState(DataStateEnum.ENABLE.getCode());
// entityPqsRelevance.setTimeId(date);
// relevantLogMapper.insert(entityPqsRelevance);
//
// } else {
// throw new BusinessException("当前无变压器策略,请先配置策略");
// }
//
// log.info("事件关联分析用时:" + timeInterval.interval() / 1000 + "秒");
// }
@Override @Override
public Page<AdvanceEventDetailVO> querySagEventsPage(BaseParam baseParam) { public Page<AdvanceEventDetailVO> querySagEventsPage(BaseParam baseParam) {
List<String> lineIds = generalDeviceInfoClient.deptGetRunLineEvent(RequestUtil.getDeptIndex()).getData(); List<String> lineIds = generalDeviceInfoClient.deptGetRunLineEvent(RequestUtil.getDeptIndex()).getData();
@@ -473,7 +248,7 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
List<AdvanceEventDetailVO> advanceEventDetailVOList = BeanUtil.copyToList(rmpEventDetailPOList, AdvanceEventDetailVO.class); List<AdvanceEventDetailVO> advanceEventDetailVOList = BeanUtil.copyToList(rmpEventDetailPOList, AdvanceEventDetailVO.class);
advanceEventDetailVOList = advanceEventDetailVOList.stream().peek(item -> { advanceEventDetailVOList = advanceEventDetailVOList.stream().peek(item -> {
item.setFeatureAmplitude(roundHalfUp(item.getFeatureAmplitude()*100)); item.setFeatureAmplitude(roundHalfUp(item.getFeatureAmplitude() * 100));
if (map.containsKey(item.getLineId())) { if (map.containsKey(item.getLineId())) {
AreaLineInfoVO areaLineInfoVO = map.get(item.getLineId()); AreaLineInfoVO areaLineInfoVO = map.get(item.getLineId());
@@ -493,6 +268,7 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
} }
/** /**
* 四舍五入保留两位小数 * 四舍五入保留两位小数
*/ */
@@ -504,6 +280,7 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
//保留2位小数 //保留2位小数
return com.njcn.harmonic.utils.PubUtils.dataLimits(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()); return com.njcn.harmonic.utils.PubUtils.dataLimits(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
} }
@Override @Override
public Page<RmpEventDetailAssPO> queryEventsAssPage(BaseParam baseParam) { public Page<RmpEventDetailAssPO> queryEventsAssPage(BaseParam baseParam) {
List<LocalDateTime> timeV = PubUtils.checkLocalDate(baseParam.getSearchBeginTime(), baseParam.getSearchEndTime()); List<LocalDateTime> timeV = PubUtils.checkLocalDate(baseParam.getSearchBeginTime(), baseParam.getSearchEndTime());
@@ -620,6 +397,7 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
.in(RmpEventDetailPO::getEventId, eventId); .in(RmpEventDetailPO::getEventId, eventId);
RmpEventDetailPO rmpEventDetailPO = new RmpEventDetailPO(); RmpEventDetailPO rmpEventDetailPO = new RmpEventDetailPO();
rmpEventDetailPO.setEventassIndex(assId); rmpEventDetailPO.setEventassIndex(assId);
rmpEventDetailPO.setDealTime(LocalDateTime.now());
eventAdvanceMapper.update(rmpEventDetailPO, lambdaUpdateWrapper); eventAdvanceMapper.update(rmpEventDetailPO, lambdaUpdateWrapper);
return true; return true;
} }
@@ -734,7 +512,7 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
List<AdvanceEventDetailVO> advanceEventDetailVOLsit = querySagEventsAll(startTime, endTime); List<AdvanceEventDetailVO> advanceEventDetailVOLsit = querySagEventsAll(startTime, endTime);
advanceEventDetailVOLsit = advanceEventDetailVOLsit.stream().filter(temp-> StringUtils.isNotEmpty(temp.getAdvanceType())).collect(Collectors.toList()); advanceEventDetailVOLsit = advanceEventDetailVOLsit.stream().filter(temp -> StringUtils.isNotEmpty(temp.getAdvanceType())).collect(Collectors.toList());
for (AdvanceEventDetailVO advanceEventDetailVO : advanceEventDetailVOLsit) { // 获取监测点线路序号 for (AdvanceEventDetailVO advanceEventDetailVO : advanceEventDetailVOLsit) { // 获取监测点线路序号
//母线id //母线id
String nodePhysics = advanceEventDetailVO.getVoltageId(); String nodePhysics = advanceEventDetailVO.getVoltageId();
@@ -868,7 +646,7 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
/************************************************************************************* /*************************************************************************************
* 获取变压器信息并生成矩阵 * 获取变压器信息并生成矩阵
*************************************************************************************/ *************************************************************************************/
public Map<String, Map<String, Integer>> getNodeBefore(){ public Map<String, Map<String, Integer>> getNodeBefore() {
Map<String, EntityMtrans> entityMtranMap = new HashMap<>(32); Map<String, EntityMtrans> entityMtranMap = new HashMap<>(32);
HandleEvent handleEvent = new HandleEvent(); HandleEvent handleEvent = new HandleEvent();
@@ -883,7 +661,7 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
} }
public Map<String, EntityMtrans> getNodeInfo( ) { public Map<String, EntityMtrans> getNodeInfo() {
Map<String, EntityMtrans> entityMtranMap = new HashMap<>(32); Map<String, EntityMtrans> entityMtranMap = new HashMap<>(32);
HandleEvent handleEvent = new HandleEvent(); HandleEvent handleEvent = new HandleEvent();
@@ -893,7 +671,7 @@ public class EventRelevantAnalysisServiceImpl extends ServiceImpl<RmpEventAdvanc
Map<String, List<String>> map = getLogicInfo(list); Map<String, List<String>> map = getLogicInfo(list);
Map<String, Map<String, Integer>> setNodeSort = nodeSort(map); Map<String, Map<String, Integer>> setNodeSort = nodeSort(map);
redisUtil.saveByKeyWithExpire(redisSortKey,setNodeSort,-1L); redisUtil.saveByKeyWithExpire(redisSortKey, setNodeSort, -1L);
setNodeSort.forEach((key, val) -> { setNodeSort.forEach((key, val) -> {
FinalData.NODE_NUM = val.size(); FinalData.NODE_NUM = val.size();

View File

@@ -81,6 +81,8 @@ public class EventWaveAnalysisServiceImpl implements EventWaveAnalysisService {
//获取所有暂态原因 //获取所有暂态原因
List<DictData> dicDataList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.EVENT_TYPE.getCode()).getData(); List<DictData> dicDataList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.EVENT_TYPE.getCode()).getData();
Map<Integer, DictData> eventTypeMap = dicDataList.stream().collect(Collectors.toMap(DictData::getAlgoDescribe, Function.identity())); Map<Integer, DictData> eventTypeMap = dicDataList.stream().collect(Collectors.toMap(DictData::getAlgoDescribe, Function.identity()));
List<DictData> reasonList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.EVENT_REASON.getCode()).getData();
Map<Integer, DictData> eventReasonMap = reasonList.stream().collect(Collectors.toMap(DictData::getAlgoDescribe, Function.identity()));
InputStream inputStreamCfg; InputStream inputStreamCfg;
InputStream inputStreamDat; InputStream inputStreamDat;
try { try {
@@ -176,11 +178,11 @@ public class EventWaveAnalysisServiceImpl implements EventWaveAnalysisService {
causeStruct.smp_len = pitchList.size(); causeStruct.smp_len = pitchList.size();
causeStruct.smp_rate = (int) wavePitchData.getnOneWaveNum(); causeStruct.smp_rate = (int) wavePitchData.getnOneWaveNum();
String hdrStr = waveUtils.getFile(OssPath.WAVE_DIR + lineDetailDataVO.getIp() + StrUtil.SLASH + rmpEventDetailPO.getWavePath() + GeneralConstant.HDR); String hdrStr = waveUtils.getFile(OssPath.WAVE_DIR + lineDetailDataVO.getIp() + StrUtil.SLASH + rmpEventDetailPO.getWavePath() + GeneralConstant.HDR_LOWER);
JSONObject jsonObject = JSONObject.fromObject(hdrStr); JSONObject jsonObject = JSONObject.fromObject(hdrStr);
translateData(jsonObject, rmpEventDetailPO.getStartTime(), entityAdvancedData); translateData(jsonObject, rmpEventDetailPO.getStartTime(), entityAdvancedData);
if (rmpEventDetailPO.getDealFlag() != 1) { if (!Objects.equals(rmpEventDetailPO.getDealFlag(),1) ) {
//如果存在三个文件但是没有调用dll/so计算 //如果存在三个文件但是没有调用dll/so计算
getDataFromDLL(rmpEventDetailPO, waveOriginalData, rect, entityAdvancedData, causeStruct); getDataFromDLL(rmpEventDetailPO, waveOriginalData, rect, entityAdvancedData, causeStruct);
} }
@@ -192,7 +194,7 @@ public class EventWaveAnalysisServiceImpl implements EventWaveAnalysisService {
if (entityAdvancedData.backNumber > 0) { if (entityAdvancedData.backNumber > 0) {
for (int i = 0; i < entityAdvancedData.backNumber; i++) { for (int i = 0; i < entityAdvancedData.backNumber; i++) {
entityAdvancedData.sagType[i] = eventTypeMap.get(entityAdvancedData.evt_buf[i].qvvr_cata_type[0]).getName(); entityAdvancedData.sagType[i] = eventTypeMap.get(entityAdvancedData.evt_buf[i].qvvr_cata_type[0]).getName();
entityAdvancedData.sagReason[i]= eventReasonMap.get(entityAdvancedData.evt_buf[i].qvvr_cata_cause[0]).getName();
switch (entityAdvancedData.evt_buf[i].qvvr_phasetype[0]) { switch (entityAdvancedData.evt_buf[i].qvvr_phasetype[0]) {
case 1: case 1:
entityAdvancedData.sagPhaseType[i] = "单相"; entityAdvancedData.sagPhaseType[i] = "单相";
@@ -628,7 +630,7 @@ public class EventWaveAnalysisServiceImpl implements EventWaveAnalysisService {
entityAdvancedData.backNumber = len; entityAdvancedData.backNumber = len;
//初始化EntityAdvancedData的BackData数据 //初始化EntityAdvancedData的BackData数据
len = (len == 0 ? 1 : len); // len = (len == 0 ? 1 : len);
entityAdvancedData.evt_buf = new BackData[len]; entityAdvancedData.evt_buf = new BackData[len];
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
entityAdvancedData.evt_buf[i] = new BackData(); entityAdvancedData.evt_buf[i] = new BackData();

View File

@@ -1,3 +1,3 @@
spring: spring:
profiles: profiles:
active: sjzx active: @spring.profiles.active@

View File

@@ -66,6 +66,13 @@
<artifactId>common-oss</artifactId> <artifactId>common-oss</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<!--辽宁调度现场单点登录-->
<dependency>
<groupId>com.sgcc.epri.auth</groupId>
<artifactId>sso-client-base</artifactId>
<version>2.1.1 </version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@@ -138,4 +145,4 @@
</project> </project>

View File

@@ -0,0 +1,26 @@
package com.njcn.auth.config;
/**
* pqs
*
* @author cdf
* @date 2026/6/8
*/
import com.sgcc.epri.auth.config.EnableSSOClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
/**
* 仅控制 SSO 客户端开关,不影响任何其他功能
*/
@Configuration
@ConditionalOnProperty(
prefix = "cas.client", // 配置前缀
name = "enabled", // 配置项名称
havingValue = "true", // 值为true才生效
matchIfMissing = false // 不配置默认关闭
)
@EnableSSOClient
public class LnSsoClientConfig {
}

View File

@@ -37,7 +37,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.authorizeRequests() .authorizeRequests()
.antMatchers("/oauth/getPublicKey","/oauth/logout","/auth/getImgCode","/judgeToken/guangZhou","/judgeToken/heBei","/oauth/autoLogin").permitAll() .antMatchers("/oauth/getPublicKey","/oauth/logout","/auth/getImgCode","/judgeToken/guangZhou","/judgeToken/heBei","/oauth/autoLogin","/oauth/lnLogin","/oauth/lnCheck","/oauth/lnRefreshToken").permitAll()
// @link https://gitee.com/xiaoym/knife4j/issues/I1Q5X6 (接口文档knife4j需要放行的规则) // @link https://gitee.com/xiaoym/knife4j/issues/I1Q5X6 (接口文档knife4j需要放行的规则)
.antMatchers("/webjars/**","/doc.html","/swagger-resources/**","/v2/api-docs").permitAll() .antMatchers("/webjars/**","/doc.html","/swagger-resources/**","/v2/api-docs").permitAll()
.anyRequest().authenticated() .anyRequest().authenticated()

View File

@@ -25,13 +25,17 @@ import com.njcn.user.pojo.po.UserStrategy;
import com.njcn.web.controller.BaseController; import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.RequestUtil; import com.njcn.web.utils.RequestUtil;
import com.njcn.web.utils.RestTemplateUtil; import com.njcn.web.utils.RestTemplateUtil;
import com.sgcc.epri.auth.session.HttpSessionManager;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint; import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException;
@@ -39,6 +43,10 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import springfox.documentation.annotations.ApiIgnore; import springfox.documentation.annotations.ApiIgnore;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.Principal; import java.security.Principal;
@@ -55,7 +63,7 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/oauth") @RequestMapping("/oauth")
@AllArgsConstructor @RequiredArgsConstructor
public class AuthController extends BaseController { public class AuthController extends BaseController {
@@ -71,6 +79,11 @@ public class AuthController extends BaseController {
private final UserTokenService userTokenService; private final UserTokenService userTokenService;
@Value("${cas.redirect-url:http://10.21.30.11:8088/#/login?flag=1}")
private String redirectUrl;
private String UsernamePrefix = "CAS_";
@ApiIgnore @ApiIgnore
@OperateInfo(info = LogEnum.SYSTEM_SERIOUS, operateType = OperateType.AUTHENTICATE) @OperateInfo(info = LogEnum.SYSTEM_SERIOUS, operateType = OperateType.AUTHENTICATE)
@@ -91,7 +104,6 @@ public class AuthController extends BaseController {
String methodDescribe = getMethodDescribe("postAccessToken"); String methodDescribe = getMethodDescribe("postAccessToken");
String username = parameters.get(SecurityConstants.USERNAME); String username = parameters.get(SecurityConstants.USERNAME);
String grantType = parameters.get(SecurityConstants.GRANT_TYPE); String grantType = parameters.get(SecurityConstants.GRANT_TYPE);
if (grantType.equalsIgnoreCase(SecurityConstants.GRANT_CAPTCHA) || grantType.equalsIgnoreCase(SecurityConstants.REFRESH_TOKEN_KEY)) { if (grantType.equalsIgnoreCase(SecurityConstants.GRANT_CAPTCHA) || grantType.equalsIgnoreCase(SecurityConstants.REFRESH_TOKEN_KEY)) {
username = DesUtils.aesDecrypt(username); username = DesUtils.aesDecrypt(username);
@@ -104,19 +116,19 @@ public class AuthController extends BaseController {
UserStrategy data = passWordRuleFeugnClient.getUserStrategy().getData(); UserStrategy data = passWordRuleFeugnClient.getUserStrategy().getData();
String onlineUserKey = SecurityConstants.TOKEN_ONLINE_PREFIX; String onlineUserKey = SecurityConstants.TOKEN_ONLINE_PREFIX;
List<UserTokenInfo> onLineUser = (List<UserTokenInfo>) redisUtil.getLikeListAllValues(onlineUserKey); List<UserTokenInfo> onLineUser = (List<UserTokenInfo>) redisUtil.getLikeListAllValues(onlineUserKey);
if(CollectionUtil.isNotEmpty(onLineUser)){ if (CollectionUtil.isNotEmpty(onLineUser)) {
String finalUsername = username; String finalUsername = username;
onLineUser = onLineUser.stream().filter(item->{ onLineUser = onLineUser.stream().filter(item -> {
JSONObject jsonObject = AuthPubUtil.getLoginByToken(item.getRefreshToken()); JSONObject jsonObject = AuthPubUtil.getLoginByToken(item.getRefreshToken());
String login = jsonObject.getStr(SecurityConstants.USER_NAME_KEY); String login = jsonObject.getStr(SecurityConstants.USER_NAME_KEY);
long exp = Long.parseLong(jsonObject.getStr(SecurityConstants.JWT_EXP)); long exp = Long.parseLong(jsonObject.getStr(SecurityConstants.JWT_EXP));
long now = Calendar.getInstance().getTimeInMillis()/1000; long now = Calendar.getInstance().getTimeInMillis() / 1000;
return (exp > now) && !login.equals(finalUsername); return (exp > now) && !login.equals(finalUsername);
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
Integer maxNum = data.getMaxNum(); Integer maxNum = data.getMaxNum();
if((CollectionUtil.isNotEmpty(onLineUser)?onLineUser.size():0)>=maxNum){ if ((CollectionUtil.isNotEmpty(onLineUser) ? onLineUser.size() : 0) >= maxNum) {
throw new BusinessException(UserResponseEnum.LOGIN_USER_OVERLIMIT); throw new BusinessException(UserResponseEnum.LOGIN_USER_OVERLIMIT);
} }
@@ -143,7 +155,7 @@ public class AuthController extends BaseController {
@OperateInfo(info = LogEnum.SYSTEM_SERIOUS, operateType = OperateType.LOGOUT) @OperateInfo(info = LogEnum.SYSTEM_SERIOUS, operateType = OperateType.LOGOUT)
@ApiOperation("用户登出系统") @ApiOperation("用户登出系统")
@DeleteMapping("/logout") @DeleteMapping("/logout")
public HttpResult<Object> logout() { public HttpResult<Object> logout(HttpServletRequest request, HttpServletResponse response) {
String methodDescribe = getMethodDescribe("logout"); String methodDescribe = getMethodDescribe("logout");
String userIndex = RequestUtil.getUserIndex(); String userIndex = RequestUtil.getUserIndex();
String username = RequestUtil.getUsername(); String username = RequestUtil.getUsername();
@@ -165,6 +177,24 @@ public class AuthController extends BaseController {
long lifeTime = Math.abs(refreshTokenExpire.plusMinutes(5L).toEpochSecond(ZoneOffset.of("+8")) - LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"))); long lifeTime = Math.abs(refreshTokenExpire.plusMinutes(5L).toEpochSecond(ZoneOffset.of("+8")) - LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
redisUtil.saveByKeyWithExpire(blackUserKey, blackUsers, lifeTime); redisUtil.saveByKeyWithExpire(blackUserKey, blackUsers, lifeTime);
} }
// 以下代码是辽宁登出代码,关键:使 Session 失效
request.getSession().invalidate();
// 清除 JSESSIONID
Cookie jsessionidCookie = new Cookie("JSESSIONID", null);
jsessionidCookie.setMaxAge(0);
jsessionidCookie.setPath("/");
response.addCookie(jsessionidCookie);
// 清除 loginUser Cookie关键
Cookie loginUserCookie = new Cookie("loginUser", null);
loginUserCookie.setMaxAge(0);
loginUserCookie.setPath("/");
response.addCookie(loginUserCookie);
log.info("登出成功。。。。。。。。。。。。。。。。");
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
} }
@@ -191,7 +221,7 @@ public class AuthController extends BaseController {
@ApiIgnore @ApiIgnore
public HttpResult<Object> autoLogin(@RequestParam String phone) { public HttpResult<Object> autoLogin(@RequestParam String phone) {
String methodDescribe = getMethodDescribe("autoLogin"); String methodDescribe = getMethodDescribe("autoLogin");
String userUrl = "http://127.0.0.1:10214/oauth/token"; String userUrl = "http://127.0.0.1:20214/oauth/token";
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(userUrl) UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(userUrl)
.queryParam("grant_type", "sms_code") .queryParam("grant_type", "sms_code")
.queryParam("client_id", "njcnapp") .queryParam("client_id", "njcnapp")
@@ -202,4 +232,134 @@ public class AuthController extends BaseController {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, Objects.requireNonNull(RestTemplateUtil.post(uri, HttpResult.class).getBody()).getData(), methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, Objects.requireNonNull(RestTemplateUtil.post(uri, HttpResult.class).getBody()).getData(), methodDescribe);
} }
/**
* 【电科院CAS调控云单点登录适配】
* 这个只用来匹配
*/
@ApiIgnore
@GetMapping("/lnLogin")
@ApiOperation("获取ln系统用户token")
public HttpResult<Object> lnLogin(@RequestParam String clientId, @RequestParam String clientSecret, HttpServletRequest request, HttpServletResponse response) throws HttpRequestMethodNotSupportedException {
log.info("进入lnLogin++++++++++++++++++");
String methodDescribe = getMethodDescribe("lnLogin");
// 读取CAS信息
String userName = String.valueOf(HttpSessionManager.getAttribute(request, HttpSessionManager.AUTH_USER_KEY));
String userId = String.valueOf(HttpSessionManager.getAttribute(request, HttpSessionManager.USER_ID_KEY));
String owner = String.valueOf(HttpSessionManager.getAttribute(request, HttpSessionManager.USER_OWNER));
String name = String.valueOf(HttpSessionManager.getAttribute(request, HttpSessionManager.USER_NAME_CHN));
String employeeId = String.valueOf(HttpSessionManager.getAttribute(request, HttpSessionManager.USER_EMPLOYEE_ID));
log.info("userName:{}", userName);
log.info("userId:{}", userId);
log.info("owner:{}", owner);
log.info("name:{}", name);
log.info("employeeId:{}", employeeId);
if ("null".equals(userName)) {
throw new BusinessException(UserResponseEnum.LN_AUTH_ERROR);
}
// 2. 【关键】用户名前面加上"CAS_"前缀让UserDetailsService识别
String casUsername = userName;
// 2. 直接构造 OAuth2 必要参数(跳过所有密码/加密校验)
Map<String, String> parameters = new HashMap<>();
parameters.put("grant_type", "password"); // 固定密码模式
parameters.put("client_id", clientId); // 你的客户端ID
parameters.put("client_secret", clientSecret); // 你的客户端秘钥
parameters.put("username", userName); // 统一认证传过来的用户名
parameters.put("password", "@#001njcnpqs");
// 3. 直接调用 OAuth2 生成 Token跳过所有登录校验
Authentication authentication = new UsernamePasswordAuthenticationToken(
clientId, clientSecret, Collections.emptyList()
);
OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(authentication, parameters).getBody();
// 获取过期时间(秒数)
int expiresIn = oAuth2AccessToken.getExpiresIn();
log.info("token过期时间: {} 秒", expiresIn);
log.info("token过期时间: {} 分钟", expiresIn / 60);
log.info("token过期时间: {} 小时", expiresIn / 3600);
log.info("====== 免密登录成功返回token给前端 ======");
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, oAuth2AccessToken, methodDescribe);
}
/**
* 重点:
* 这个接口 不加 白名单
* 访问它 → 自动跳CAS → 登录成功 → 重定向到登录页
*/
@GetMapping("/lnCheck")
@ApiOperation("检查CAS是否登录")
public void lnToken(HttpServletRequest request, HttpServletResponse response) throws IOException {
log.info("进入lnCheck。。。。");
response.sendRedirect(redirectUrl);
}
/**
*/
@GetMapping("/lnRefreshToken")
@ApiOperation("刷新token")
public HttpResult<Object> lnRefreshToken(
@RequestParam String refreshToken,
@RequestParam String clientId,
@RequestParam String clientSecret,
HttpServletRequest request,
HttpServletResponse response) throws HttpRequestMethodNotSupportedException {
log.info("进入lnRefreshToken开始刷新token");
String methodDescribe = getMethodDescribe("lnRefreshToken");
// ========== 【前置优先校验CAS会话是否过期】 ==========
String userName = String.valueOf(HttpSessionManager.getAttribute(request, HttpSessionManager.AUTH_USER_KEY));
if ("null".equals(userName)) {
log.error("CAS会话已过期跳转登录页");
throw new BusinessException(UserResponseEnum.LN_AUTH_ERROR);
}
// 1. 先尝试用refresh_token正常刷新
Map<String, String> parameters = new HashMap<>();
parameters.put("grant_type", "refresh_token");
parameters.put("refresh_token", refreshToken);
parameters.put("client_id", clientId);
parameters.put("client_secret", clientSecret);
Authentication authentication = new UsernamePasswordAuthenticationToken(
clientId, clientSecret, Collections.emptyList()
);
try {
OAuth2AccessToken newAccessToken = tokenEndpoint.postAccessToken(authentication, parameters).getBody();
log.info("refresh_token刷新成功");
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, newAccessToken, methodDescribe);
} catch (Exception e) {
log.warn("refresh_token刷新失败尝试回退到CAS会话重新签发token", e);
}
// 3. CAS会话有效重新签发token等同于重新登录
log.info("CAS会话有效为用户[{}]重新签发token", userName);
String casUsername = userName;
Map<String, String> reLoginParams = new HashMap<>();
reLoginParams.put("grant_type", "password");
reLoginParams.put("client_id", clientId);
reLoginParams.put("client_secret", clientSecret);
reLoginParams.put("username", userName);
reLoginParams.put("password", "@#001njcnpqs");
Authentication reAuth = new UsernamePasswordAuthenticationToken(
clientId, clientSecret, Collections.emptyList()
);
OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(reAuth, reLoginParams).getBody();
log.info("CAS回退重签token成功userName:{}", userName);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, oAuth2AccessToken, methodDescribe);
}
} }

View File

@@ -55,3 +55,22 @@ mybatis-plus:
mqtt: mqtt:
client-id: @artifactId@${random.value} client-id: @artifactId@${random.value}
cas:
client:
# true 开启 false 关闭
enabled: false
redirect-url: http://PQMonitoring.dcloud.ln.dc.sgcc.com.cn/#/login?flag=1
server-url-prefix: http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas
server-login-url: http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/login
client-host-url: http://PQMonitoring.dcloud.ln.dc.sgcc.com.cn:80
validation-type: CAS
#白名单设置
# /oauth/lnLogin$|/pqs-auth/oauth/lnLogin|/oauth/lnRefreshToken$|/pqs-auth/oauth/lnRefreshToken
sso:
whiteList: .*/oauth/lnLogin.*|.*/pqs-auth/oauth/lnLogin.*|.*/oauth/lnRefreshToken.*|.*/pqs-auth/oauth/lnRefreshToken.*

View File

@@ -21,7 +21,7 @@ public class GenerateCode {
private static final String TARGET_DIR = "D://code"; private static final String TARGET_DIR = "D://code";
private static final String DB_URL = "jdbc:mysql://192.168.1.24:13306/pqsinfo_ln"; private static final String DB_URL = "jdbc:mysql://192.168.1.103:13306/pqsinfo_zl";
// private static final String DB_URL = "jdbc:oracle:thin:@192.168.1.170:1521:pqsbase"; // private static final String DB_URL = "jdbc:oracle:thin:@192.168.1.170:1521:pqsbase";
private static final String USERNAME = "root"; private static final String USERNAME = "root";
@@ -30,8 +30,8 @@ public class GenerateCode {
public static void main(String[] args) { public static void main(String[] args) {
List<Module> modules = Stream.of( List<Module> modules = Stream.of(
new Module("cdf", "com.njcn.device", "", Stream.of( new Module("xy", "com.njcn.csdevice", "", Stream.of(
"pq_icd_path" "cs_alarm_set"
).collect(Collectors.toList()), "") ).collect(Collectors.toList()), "")
).collect(Collectors.toList()); ).collect(Collectors.toList());
generateJavaFile(modules); generateJavaFile(modules);

View File

@@ -1,11 +1,7 @@
package com.njcn.echarts.json; package com.njcn.echarts.json;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import cn.hutool.json.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.njcn.echarts.pojo.bo.TolerateData; import com.njcn.echarts.pojo.bo.TolerateData;
import com.njcn.echarts.pojo.constant.PicCommonData; import com.njcn.echarts.pojo.constant.PicCommonData;
import org.icepear.echarts.Option; import org.icepear.echarts.Option;
@@ -29,7 +25,6 @@ import org.icepear.echarts.render.Engine;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -43,6 +38,17 @@ import java.util.stream.Collectors;
public class LineGenerator { public class LineGenerator {
private final static Engine ENGINE = new Engine(); private final static Engine ENGINE = new Engine();
// null段在图表上的固定视觉宽度数据点数量
private static final int NULL_PLACEHOLDER_COUNT = 90;
// 压缩结果
private static class CompressedResult {
// 压缩后的数据
List<List<Float>> data;
// 每个null段的[起始索引, 结束索引](占位点范围)
List<int[]> nullRegionIndices;
// null段边界处的真实x值entry, exit交替
List<Float> nullBoundaryRealXValues;
}
/*** /***
@@ -529,6 +535,478 @@ public class LineGenerator {
return ENGINE.renderJsonOption(instantOption); return ENGINE.renderJsonOption(instantOption);
} }
public static String generateWaveOption(String title, List<List<Float>> aValue, List<List<Float>> bValue, List<List<Float>> cValue, String unit, Float max, Float min, String a, String b, String c, List<String> colors, Boolean isOpen, Double lastTime, List<Float> sharedNullBoundaryXValues, Integer nPush) {
DecimalFormat df1 = new DecimalFormat("#.00");
// 压缩null数据如果有共享边界则用共享边界否则独立压缩
CompressedResult aCompressed;
CompressedResult bCompressed;
CompressedResult cCompressed;
if (sharedNullBoundaryXValues != null && !sharedNullBoundaryXValues.isEmpty()) {
aCompressed = compressNullDataWithSharedBoundaries(aValue, sharedNullBoundaryXValues);
bCompressed = compressNullDataWithSharedBoundaries(bValue, sharedNullBoundaryXValues);
cCompressed = compressNullDataWithSharedBoundaries(cValue, sharedNullBoundaryXValues);
} else {
aCompressed = compressNullData(aValue);
bCompressed = compressNullData(bValue);
cCompressed = compressNullData(cValue);
}
Option instantOption = new Option();
//取消渲染动画
instantOption.setAnimation(false);
//背景色
instantOption.setBackgroundColor(PicCommonData.PIC_BACK_COLOR);
//标题
instantOption.setTitle(new Title()
.setText(title)
.setLeft(PicCommonData.CENTER)
.setTextStyle(new Label().setFontSize(14))
);
//配置颜色
instantOption.setColor(colors.toArray(new String[colors.size()]));
//配置图例
if (isOpen) {
instantOption.setLegend(new Legend().setData(new String[]{a, b}).setLeft("10px"));
} else {
instantOption.setLegend(new Legend().setData(new String[]{a, b, c}).setLeft("10px"));
}
//上下左右的图内间距
instantOption.setGrid(new Grid().setTop("60px").setLeft("70px").setRight("40px").setBottom("10%"));
//横坐标(使用压缩后的数据)
instantOption.setXAxis(new ValueAxis().setName("ms")
.setSplitLine(new SplitLine().setShow(false))
.setAxisLine(new AxisLine().setOnZero(false))
.setType("category")
.setMinInterval(1)
);
//纵坐标
instantOption.setYAxis(new ValueAxis()
.setName(unit)
.setMax(df1.format(max * 1.1))
.setMin(df1.format(min * 1.1))
.setPosition(PicCommonData.LEFT)
.setAxisLine(new AxisLine().setShow(false).setOnZero(false))
);
//数据信息(使用压缩后的数据)
LineSeries aSeries = new LineSeries()
.setName(a)
.setSmooth(true)
.setSymbol("none")
.setConnectNulls(false)
.setData(aCompressed.data);
LineSeries bSeries = new LineSeries()
.setName(b)
.setSmooth(true)
.setSymbol("none")
.setConnectNulls(false)
.setData(bCompressed.data);
LineSeries cSeries = new LineSeries()
.setName(c)
.setSmooth(true)
.setSymbol("none")
.setConnectNulls(false)
.setData(cCompressed.data);
instantOption.setSeries(new LineSeries[]{aSeries, bSeries, cSeries});
// 渲染基础JSON
String jsonStr = ENGINE.renderJsonOption(instantOption);
cn.hutool.json.JSONObject optionJson = JSONUtil.parseObj(jsonStr);
cn.hutool.json.JSONArray seriesArray = optionJson.getJSONArray("series");
// 隐藏x轴默认标签设置boundaryGap=false只通过markLine显示关键节点
Object xAxisRaw = optionJson.get("xAxis");
cn.hutool.json.JSONObject xAxisJson;
if (xAxisRaw instanceof cn.hutool.json.JSONArray) {
xAxisJson = ((cn.hutool.json.JSONArray) xAxisRaw).getJSONObject(0);
} else {
xAxisJson = (cn.hutool.json.JSONObject) xAxisRaw;
}
cn.hutool.json.JSONObject axisLabelJson = new cn.hutool.json.JSONObject();
axisLabelJson.set("show", false);
xAxisJson.set("axisLabel", axisLabelJson);
xAxisJson.set("boundaryGap", false);
// 添加null markLine/markArea基于压缩后的数据
addNullMarkLinesForCategoryAxis(seriesArray.getJSONObject(0), aCompressed, lastTime);
addNullMarkLinesForCategoryAxis(seriesArray.getJSONObject(1), bCompressed, lastTime);
addNullMarkLinesForCategoryAxis(seriesArray.getJSONObject(2), cCompressed, lastTime);
// 在第一个series追加自定义横坐标标签markLine
addAxisLabelMarkLines(seriesArray.getJSONObject(0), aCompressed, lastTime, nPush);
return optionJson.toString();
}
/** 提取null边界的真实x值供其他数据集共享使用 */
public static List<Float> extractNullBoundaryXValues(List<List<Float>> data) {
List<Integer> boundaries = findNullSegmentBoundaryIndices(data);
List<Float> xValues = new ArrayList<>();
for (int idx : boundaries) {
xValues.add(data.get(idx).get(0));
}
return xValues;
}
/** 使用共享的null边界x值来压缩数据确保不同数据集压缩结果结构一致 */
private static CompressedResult compressNullDataWithSharedBoundaries(List<List<Float>> originalData, List<Float> sharedBoundaryXValues) {
if (sharedBoundaryXValues == null || sharedBoundaryXValues.isEmpty()) {
return compressNullData(originalData);
}
// 用共享的x值找到本数据集中对应的索引
List<Integer> boundaries = new ArrayList<>();
for (Float x : sharedBoundaryXValues) {
boundaries.add(findClosestValidIndex(originalData, x));
}
CompressedResult result = new CompressedResult();
result.data = new ArrayList<>();
result.nullRegionIndices = new ArrayList<>();
result.nullBoundaryRealXValues = new ArrayList<>(sharedBoundaryXValues);
int srcIdx = 0;
for (int b = 0; b < boundaries.size(); b += 2) {
int entryBoundary = boundaries.get(b);
int exitBoundary = boundaries.get(b + 1);
while (srcIdx <= entryBoundary) {
result.data.add(originalData.get(srcIdx));
srcIdx++;
}
int nullStartIdx = result.data.size();
float entryX = sharedBoundaryXValues.get(b);
float exitX = sharedBoundaryXValues.get(b + 1);
for (int p = 0; p < NULL_PLACEHOLDER_COUNT; p++) {
List<Float> point = new ArrayList<>();
point.add(entryX + (exitX - entryX) * p / NULL_PLACEHOLDER_COUNT);
point.add(null);
result.data.add(point);
}
int nullEndIdx = result.data.size() - 1;
result.nullRegionIndices.add(new int[]{nullStartIdx, nullEndIdx});
srcIdx = exitBoundary;
}
while (srcIdx < originalData.size()) {
result.data.add(originalData.get(srcIdx));
srcIdx++;
}
return result;
}
/**
* 压缩null数据删除所有null数据点替换为固定NULL_PLACEHOLDER_COUNT个占位点
* 这样null段在图表上永远只占固定视觉宽度前后有效数据正常展开
*/
private static CompressedResult compressNullData(List<List<Float>> originalData) {
List<Integer> boundaries = findNullSegmentBoundaryIndices(originalData);
CompressedResult result = new CompressedResult();
result.data = new ArrayList<>();
result.nullRegionIndices = new ArrayList<>();
result.nullBoundaryRealXValues = new ArrayList<>();
if (boundaries.isEmpty()) {
result.data.addAll(originalData);
return result;
}
int srcIdx = 0;
for (int b = 0; b < boundaries.size(); b += 2) {
// 最后一个有效点的索引null段入口边界
int entryBoundary = boundaries.get(b);
// 第一个恢复有效点的索引null段出口边界
int exitBoundary = boundaries.get(b + 1);
// 复制有效数据从srcIdx到entryBoundary
while (srcIdx <= entryBoundary) {
result.data.add(originalData.get(srcIdx));
srcIdx++;
}
// 记录边界真实x值
result.nullBoundaryRealXValues.add(originalData.get(entryBoundary).get(0));
result.nullBoundaryRealXValues.add(originalData.get(exitBoundary).get(0));
// 插入固定数量的null占位点
int nullStartIdx = result.data.size();
float entryX = originalData.get(entryBoundary).get(0);
float exitX = originalData.get(exitBoundary).get(0);
for (int p = 0; p < NULL_PLACEHOLDER_COUNT; p++) {
List<Float> point = new ArrayList<>();
point.add(entryX + (exitX - entryX) * p / NULL_PLACEHOLDER_COUNT);
point.add(null);
result.data.add(point);
}
int nullEndIdx = result.data.size() - 1;
result.nullRegionIndices.add(new int[]{nullStartIdx, nullEndIdx});
// 跳过原始null数据点srcIdx跳到exitBoundary
srcIdx = exitBoundary;
}
// 复制最后一个null段之后的剩余有效数据
while (srcIdx < originalData.size()) {
result.data.add(originalData.get(srcIdx));
srcIdx++;
}
return result;
}
/**
* 在压缩数据中查找最接近目标x值的有效数据点索引跳过null点
*/
private static int findClosestValidIndex(List<List<Float>> data, float targetX) {
int closestIdx = -1;
float minDiff = Float.MAX_VALUE;
for (int i = 0; i < data.size(); i++) {
Float y = data.get(i).get(1);
if (y == null) continue;
float diff = Math.abs(data.get(i).get(0) - targetX);
if (diff < minDiff) {
minDiff = diff;
closestIdx = i;
}
}
return closestIdx;
}
private static void addAxisLabelMarkLines(cn.hutool.json.JSONObject seriesObj, CompressedResult compressed, Double lastTime, Integer nPush) {
boolean hasNull = !compressed.nullRegionIndices.isEmpty();
// 收集需要标注的横坐标位置:[数据索引, 显示的时间值]
List<int[]> labelPositions = new ArrayList<>();
// 开头ms始终显示
labelPositions.add(new int[]{findClosestValidIndex(compressed.data, -nPush), -nPush});
// 0ms始终显示
labelPositions.add(new int[]{findClosestValidIndex(compressed.data, 0f), 0});
// npush ms仅在有null时显示
if (hasNull) {
labelPositions.add(new int[]{findClosestValidIndex(compressed.data, nPush), nPush});
}
// null段边界真实时间值仅在有null时显示
if (hasNull) {
for (Float realX : compressed.nullBoundaryRealXValues) {
int idx = findClosestValidIndex(compressed.data, realX);
if (idx >= 0) {
labelPositions.add(new int[]{idx, (int) Math.round(realX)});
}
}
}
// lastTime始终显示
if (lastTime != null) {
labelPositions.add(new int[]{findClosestValidIndex(compressed.data, lastTime.floatValue()), lastTime.intValue()});
}
// 最后一组数据(始终显示,数据结束位置横坐标)
if (lastTime != null) {
float lastTime20 = lastTime.floatValue() + nPush;
int lastTime20Idx = findClosestValidIndex(compressed.data, lastTime20);
if (lastTime20Idx >= 0) {
labelPositions.add(new int[]{(lastTime20Idx-2), (int) Math.round(lastTime20)});
}
}
// 获取或创建markLine
cn.hutool.json.JSONObject existingMarkLine = seriesObj.getJSONObject("markLine");
cn.hutool.json.JSONArray markLineData;
if (existingMarkLine == null) {
// 无null的情况自己创建markLine包含虚线和横坐标标签
markLineData = new cn.hutool.json.JSONArray();
// x=0 虚线
int zeroIdx = findClosestValidIndex(compressed.data, 0f);
if (zeroIdx >= 0) {
cn.hutool.json.JSONObject zeroLine = new cn.hutool.json.JSONObject();
zeroLine.set("xAxis", zeroIdx);
cn.hutool.json.JSONObject zeroLabel = new cn.hutool.json.JSONObject();
zeroLabel.set("show", false);
zeroLine.set("label", zeroLabel);
markLineData.add(zeroLine);
}
// lastTime 虚线
if (lastTime != null) {
int lastTimeIdx = findClosestValidIndex(compressed.data, lastTime.floatValue());
if (lastTimeIdx >= 0) {
cn.hutool.json.JSONObject lastTimeLine = new cn.hutool.json.JSONObject();
lastTimeLine.set("xAxis", lastTimeIdx);
cn.hutool.json.JSONObject lastTimeLabelObj = new cn.hutool.json.JSONObject();
lastTimeLabelObj.set("show", false);
lastTimeLine.set("label", lastTimeLabelObj);
markLineData.add(lastTimeLine);
}
}
// 先收集所有标签到markLineData
for (int[] pos : labelPositions) {
cn.hutool.json.JSONObject line = new cn.hutool.json.JSONObject();
line.set("xAxis", pos[0]);
cn.hutool.json.JSONObject lineLineStyle = new cn.hutool.json.JSONObject();
lineLineStyle.set("width", 0);
line.set("lineStyle", lineLineStyle);
cn.hutool.json.JSONObject lineLabel = new cn.hutool.json.JSONObject();
lineLabel.set("show", true);
lineLabel.set("formatter", String.valueOf(pos[1]));
lineLabel.set("position", "start");
lineLabel.set("color", "#333");
lineLabel.set("fontSize", 10);
line.set("label", lineLabel);
markLineData.add(line);
}
// 最后一次性设置到markLine和series
existingMarkLine = new cn.hutool.json.JSONObject();
existingMarkLine.set("symbol", new String[]{"none", "none"});
cn.hutool.json.JSONObject lineStyle = new cn.hutool.json.JSONObject();
lineStyle.set("type", "dashed");
lineStyle.set("color", "#999");
lineStyle.set("width", 1);
existingMarkLine.set("lineStyle", lineStyle);
cn.hutool.json.JSONObject globalLabel = new cn.hutool.json.JSONObject();
globalLabel.set("show", false);
existingMarkLine.set("label", globalLabel);
existingMarkLine.set("data", markLineData);
seriesObj.set("markLine", existingMarkLine);
} else {
// 有null的情况追加标签到已有的markLine
markLineData = existingMarkLine.getJSONArray("data");
for (int[] pos : labelPositions) {
cn.hutool.json.JSONObject line = new cn.hutool.json.JSONObject();
line.set("xAxis", pos[0]);
cn.hutool.json.JSONObject lineLineStyle = new cn.hutool.json.JSONObject();
lineLineStyle.set("width", 0);
line.set("lineStyle", lineLineStyle);
cn.hutool.json.JSONObject lineLabel = new cn.hutool.json.JSONObject();
lineLabel.set("show", true);
lineLabel.set("formatter", String.valueOf(pos[1]));
lineLabel.set("position", "start");
lineLabel.set("color", "#333");
lineLabel.set("fontSize", 10);
line.set("label", lineLabel);
markLineData.add(line);
}
}
}
private static List<Integer> findNullSegmentBoundaryIndices(List<List<Float>> data) {
List<Integer> indices = new ArrayList<>();
boolean inNullSegment = false;
for (int i = 0; i < data.size(); i++) {
Float y = data.get(i).get(1);
if (y == null) {
if (!inNullSegment) {
indices.add(i > 0 ? i - 1 : i);
inNullSegment = true;
}
} else {
if (inNullSegment) {
indices.add(i);
inNullSegment = false;
}
}
}
if (inNullSegment) {
indices.add(data.size() - 1);
}
return indices;
}
private static void addNullMarkLinesForCategoryAxis(cn.hutool.json.JSONObject seriesObj, CompressedResult compressed, Double lastTime) {
if (compressed.nullRegionIndices.isEmpty()) {
return;
}
cn.hutool.json.JSONArray markLineData = new cn.hutool.json.JSONArray();
// x=0 虚线
int zeroIdx = findClosestValidIndex(compressed.data, 0f);
if (zeroIdx >= 0) {
cn.hutool.json.JSONObject zeroLine = new cn.hutool.json.JSONObject();
zeroLine.set("xAxis", zeroIdx);
cn.hutool.json.JSONObject zeroLabel = new cn.hutool.json.JSONObject();
zeroLabel.set("show", false);
zeroLine.set("label", zeroLabel);
markLineData.add(zeroLine);
}
// null段边界的垂直虚线
for (int r = 0; r < compressed.nullRegionIndices.size(); r++) {
int[] region = compressed.nullRegionIndices.get(r);
int nullStartIdx = region[0]; // 第一个占位点索引
int nullEndIdx = region[1]; // 最后一个占位点索引
// 入口虚线nullStartIdx - 1null前最后一个有效数据点
cn.hutool.json.JSONObject entryLine = new cn.hutool.json.JSONObject();
entryLine.set("xAxis", nullStartIdx - 1);
cn.hutool.json.JSONObject entryLabel = new cn.hutool.json.JSONObject();
entryLabel.set("show", false);
entryLine.set("label", entryLabel);
markLineData.add(entryLine);
// 出口虚线nullEndIdxnull后第一个有效数据点
cn.hutool.json.JSONObject exitLine = new cn.hutool.json.JSONObject();
exitLine.set("xAxis", nullEndIdx);
cn.hutool.json.JSONObject exitLabel = new cn.hutool.json.JSONObject();
exitLabel.set("show", false);
exitLine.set("label", exitLabel);
markLineData.add(exitLine);
}
// 时间持续时间结束的数据点
if (lastTime != null) {
int lastTimeIdx = findClosestValidIndex(compressed.data, lastTime.floatValue());
if (lastTimeIdx >= 0) {
cn.hutool.json.JSONObject lastTimeLine = new cn.hutool.json.JSONObject();
lastTimeLine.set("xAxis", lastTimeIdx);
cn.hutool.json.JSONObject lastTimeLabel = new cn.hutool.json.JSONObject();
lastTimeLabel.set("show", false);
lastTimeLine.set("label", lastTimeLabel);
markLineData.add(lastTimeLine);
}
}
cn.hutool.json.JSONObject markLine = new cn.hutool.json.JSONObject();
markLine.set("symbol", new String[]{"none", "none"});
cn.hutool.json.JSONObject lineStyle = new cn.hutool.json.JSONObject();
lineStyle.set("type", "dashed");
lineStyle.set("color", "#999");
lineStyle.set("width", 1);
markLine.set("lineStyle", lineStyle);
cn.hutool.json.JSONObject globalLabel = new cn.hutool.json.JSONObject();
globalLabel.set("show", false);
markLine.set("label", globalLabel);
markLine.set("data", markLineData);
seriesObj.set("markLine", markLine);
// markArea - 灰色背景覆盖null区域从入口边界到出口边界
cn.hutool.json.JSONArray markAreaData = new cn.hutool.json.JSONArray();
for (int r = 0; r < compressed.nullRegionIndices.size(); r++) {
int[] region = compressed.nullRegionIndices.get(r);
int nullStartIdx = region[0];
int nullEndIdx = region[1];
cn.hutool.json.JSONArray areaPair = new cn.hutool.json.JSONArray();
cn.hutool.json.JSONObject start = new cn.hutool.json.JSONObject();
start.set("xAxis", nullStartIdx - 1); // 从入口边界有效数据点
cn.hutool.json.JSONObject end = new cn.hutool.json.JSONObject();
end.set("xAxis", nullEndIdx); // 到出口边界有效数据点
areaPair.add(start);
areaPair.add(end);
markAreaData.add(areaPair);
}
cn.hutool.json.JSONObject markArea = new cn.hutool.json.JSONObject();
cn.hutool.json.JSONObject itemStyle = new cn.hutool.json.JSONObject();
itemStyle.set("color", "rgba(180, 180, 180, 0.2)");
itemStyle.set("borderWidth", 0);
markArea.set("itemStyle", itemStyle);
markArea.set("data", markAreaData);
seriesObj.set("markArea", markArea);
}
/** /**
* @param title 标题 * @param title 标题
* @param values 数据值 * @param values 数据值

View File

@@ -10,9 +10,10 @@ import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.*; import java.util.List;
import java.util.Map;
import java.util.Objects;
/** /**
* @author hongawen * @author hongawen
@@ -55,7 +56,6 @@ public class DrawPicUtil {
return Objects.requireNonNull(picResult.getBody()).indexOf("image/png") > 0 ? picResult.getBody() : ""; return Objects.requireNonNull(picResult.getBody()).indexOf("image/png") > 0 ? picResult.getBody() : "";
} }
/*** /***
* @author hongawen * @author hongawen
* 绘制波形图 * 绘制波形图
@@ -77,6 +77,11 @@ public class DrawPicUtil {
return drawPic(instantJson, width, height); return drawPic(instantJson, width, height);
} }
public String drawWavePic(String title, List<List<Float>> aValue, List<List<Float>> bValue, List<List<Float>> cValue, String unit, Float max, Float min, String a, String b, String c, List<String> colors, Boolean isOpen, Double lastTime, List<Float> sharedNullBoundaryXValues,Integer nPush) {
String instantJson = LineGenerator.generateWaveOption(title, aValue, bValue, cValue, unit, max, min, a, b, c, colors, isOpen, lastTime, sharedNullBoundaryXValues,nPush);
return drawPic(instantJson, 0, 0);
}
/*** /***
* 绘制itic曲线图 * 绘制itic曲线图

View File

@@ -1,10 +1,9 @@
package com.njcn.event.file.component; package com.njcn.event.file.component;
import cn.hutool.core.img.ImgUtil; import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.FileUtil; import com.njcn.common.utils.FileUtil;
import com.njcn.echarts.json.LineGenerator;
import com.njcn.echarts.pojo.constant.PicCommonData; import com.njcn.echarts.pojo.constant.PicCommonData;
import com.njcn.echarts.util.DrawPicUtil; import com.njcn.echarts.util.DrawPicUtil;
import com.njcn.event.file.pojo.bo.WaveDataDetail; import com.njcn.event.file.pojo.bo.WaveDataDetail;
@@ -12,21 +11,18 @@ import com.njcn.event.file.pojo.dto.WaveDataDTO;
import com.njcn.event.file.pojo.enums.WaveFileResponseEnum; import com.njcn.event.file.pojo.enums.WaveFileResponseEnum;
import com.njcn.oss.constant.OssPath; import com.njcn.oss.constant.OssPath;
import com.njcn.oss.utils.FileStorageUtil; import com.njcn.oss.utils.FileStorageUtil;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import sun.awt.image.BufferedImageGraphicsConfig; import sun.awt.image.BufferedImageGraphicsConfig;
import javax.imageio.ImageIO;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.util.Base64;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects;
/** /**
* @author hongawen * @author hongawen
@@ -49,36 +45,39 @@ public class WavePicComponent {
* @date 2023/9/21 15:32 * @date 2023/9/21 15:32
* @return String 文件地址 * @return String 文件地址
*/ */
public String generateInstantImageZl(List<WaveDataDetail> waveDataDetails) { public String generateInstantImageZl(Integer nPush, List<WaveDataDetail> waveDataDetails, Double lastTime) {
String firstPic = null, secondPic = null, thirdPic = null, forthPic = null; String firstPic = null, secondPic = null, thirdPic = null, forthPic = null;
WaveDataDetail waveDataDetail0 = waveDataDetails.get(0);
// 从instantData提取null边界x值作为共享参考与Shun图保持一致
List<Float> sharedNullBoundaries = LineGenerator.extractNullBoundaryXValues(waveDataDetail0.getInstantData().getAValue());
for (WaveDataDetail waveDataDetail : waveDataDetails) { for (WaveDataDetail waveDataDetail : waveDataDetails) {
if (waveDataDetail.getChannelName().toUpperCase().startsWith("SU")) { if (waveDataDetail.getChannelName().toUpperCase().startsWith("SU")) {
firstPic = drawPicUtil.drawWavePic("电压-电网侧", waveDataDetail.getInstantData().getAValue(), firstPic = drawPicUtil.drawWavePic("电压-电网侧", waveDataDetail.getInstantData().getAValue(),
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(), waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(), waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(), waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen() waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
); );
} else if (waveDataDetail.getChannelName().toUpperCase().startsWith("SI")) { } else if (waveDataDetail.getChannelName().toUpperCase().startsWith("SI")) {
thirdPic = drawPicUtil.drawWavePic("电流-电网侧", waveDataDetail.getInstantData().getAValue(), thirdPic = drawPicUtil.drawWavePic("电流-电网侧", waveDataDetail.getInstantData().getAValue(),
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(), waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(), waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(), waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen() waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
); );
} else if (waveDataDetail.getChannelName().toUpperCase().startsWith("LU")) { } else if (waveDataDetail.getChannelName().toUpperCase().startsWith("LU")) {
secondPic = drawPicUtil.drawWavePic("电压-负载侧", waveDataDetail.getInstantData().getAValue(), secondPic = drawPicUtil.drawWavePic("电压-负载侧", waveDataDetail.getInstantData().getAValue(),
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(), waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(), waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(), waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen() waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
); );
} else { } else {
forthPic = drawPicUtil.drawWavePic("电流-负载侧", waveDataDetail.getInstantData().getAValue(), forthPic = drawPicUtil.drawWavePic("电流-负载侧", waveDataDetail.getInstantData().getAValue(),
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(), waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(), waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(), waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen() waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
); );
} }
} }
@@ -91,36 +90,39 @@ public class WavePicComponent {
* @date 2023/9/21 15:32 * @date 2023/9/21 15:32
* @return String 文件地址 * @return String 文件地址
*/ */
public String generateRmsImageZl(List<WaveDataDetail> waveDataDetails) { public String generateRmsImageZl(Integer nPush, List<WaveDataDetail> waveDataDetails, Double lastTime) {
String firstPic = null, secondPic = null, thirdPic = null, forthPic = null; String firstPic = null, secondPic = null, thirdPic = null, forthPic = null;
WaveDataDetail waveDataDetail0 = waveDataDetails.get(0);
// 从instantData提取null边界x值作为共享参考与Shun图保持一致
List<Float> sharedNullBoundaries = LineGenerator.extractNullBoundaryXValues(waveDataDetail0.getInstantData().getAValue());
for (WaveDataDetail waveDataDetail : waveDataDetails) { for (WaveDataDetail waveDataDetail : waveDataDetails) {
if (waveDataDetail.getChannelName().toUpperCase().startsWith("SU")) { if (waveDataDetail.getChannelName().toUpperCase().startsWith("SU")) {
firstPic = drawPicUtil.drawWavePic("电压-电网侧", waveDataDetail.getRmsData().getAValue(), firstPic = drawPicUtil.drawWavePic("电压-电网侧", waveDataDetail.getRmsData().getAValue(),
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(), waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(), waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(), waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen() waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
); );
} else if (waveDataDetail.getChannelName().toUpperCase().startsWith("SI")) { } else if (waveDataDetail.getChannelName().toUpperCase().startsWith("SI")) {
thirdPic = drawPicUtil.drawWavePic("电流-电网侧", waveDataDetail.getRmsData().getAValue(), thirdPic = drawPicUtil.drawWavePic("电流-电网侧", waveDataDetail.getRmsData().getAValue(),
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(), waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(), waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(), waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen() waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
); );
} else if (waveDataDetail.getChannelName().toUpperCase().startsWith("LU")) { } else if (waveDataDetail.getChannelName().toUpperCase().startsWith("LU")) {
secondPic = drawPicUtil.drawWavePic("电压-负载侧", waveDataDetail.getRmsData().getAValue(), secondPic = drawPicUtil.drawWavePic("电压-负载侧", waveDataDetail.getRmsData().getAValue(),
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(), waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(), waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(), waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen() waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
); );
} else { } else {
forthPic = drawPicUtil.drawWavePic("电流-负载侧", waveDataDetail.getRmsData().getAValue(), forthPic = drawPicUtil.drawWavePic("电流-负载侧", waveDataDetail.getRmsData().getAValue(),
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(), waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(), waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(), waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen() waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
); );
} }
} }
@@ -205,10 +207,82 @@ public class WavePicComponent {
waveDataDetail.getColors(), waveDataDetail.getIsOpen() waveDataDetail.getColors(), waveDataDetail.getIsOpen()
); );
picPath = composeImage(firstPic, secondPic); picPath = composeImage(firstPic, secondPic);
} else if (waveDataDetails.size() == 4) {
WaveDataDetail waveDataDetail1 = waveDataDetails.get(0);
String pic1 = drawPicUtil.drawWavePic(getTitle2(waveDataDetail1.getChannelName(),time), waveDataDetail1.getInstantData().getAValue(),
waveDataDetail1.getInstantData().getBValue(), waveDataDetail1.getInstantData().getCValue(),
waveDataDetail1.getUnit(), waveDataDetail1.getInstantData().getMax(), waveDataDetail1.getInstantData().getMin(),
waveDataDetail1.getA(), waveDataDetail1.getB(), waveDataDetail1.getC(),
waveDataDetail1.getColors(), waveDataDetail1.getIsOpen()
);
WaveDataDetail waveDataDetail2 = waveDataDetails.get(1);
String pic2 = drawPicUtil.drawWavePic(getTitle2(waveDataDetail2.getChannelName(),time), waveDataDetail2.getInstantData().getAValue(),
waveDataDetail2.getInstantData().getBValue(), waveDataDetail2.getInstantData().getCValue(),
waveDataDetail2.getUnit(), waveDataDetail2.getInstantData().getMax(), waveDataDetail2.getInstantData().getMin(),
waveDataDetail2.getA(), waveDataDetail2.getB(), waveDataDetail2.getC(),
waveDataDetail2.getColors(), waveDataDetail2.getIsOpen());
WaveDataDetail waveDataDetail3 = waveDataDetails.get(2);
String pic3 = drawPicUtil.drawWavePic(getTitle2(waveDataDetail3.getChannelName(),time), waveDataDetail3.getInstantData().getAValue(),
waveDataDetail3.getInstantData().getBValue(), waveDataDetail3.getInstantData().getCValue(),
waveDataDetail3.getUnit(), waveDataDetail3.getInstantData().getMax(), waveDataDetail3.getInstantData().getMin(),
waveDataDetail3.getA(), waveDataDetail3.getB(), waveDataDetail3.getC(),
waveDataDetail3.getColors(), waveDataDetail3.getIsOpen());
WaveDataDetail waveDataDetail4 = waveDataDetails.get(3);
String pic4 = drawPicUtil.drawWavePic(getTitle2(waveDataDetail4.getChannelName(),time), waveDataDetail4.getInstantData().getAValue(),
waveDataDetail4.getInstantData().getBValue(), waveDataDetail4.getInstantData().getCValue(),
waveDataDetail4.getUnit(), waveDataDetail4.getInstantData().getMax(), waveDataDetail4.getInstantData().getMin(),
waveDataDetail4.getA(), waveDataDetail4.getB(), waveDataDetail4.getC(),
waveDataDetail4.getColors(), waveDataDetail4.getIsOpen()
);
picPath = composeImageZl(pic1, pic2, pic3, pic4);
} }
return picPath; return picPath;
} }
/***
* 绘制瞬时波形图 App端用来绘制图片会去掉部分数据只保留开始数据 结束数据
* @author xy
* @return String 文件地址
*/
public String generateImageShun(Integer nPush, List<WaveDataDetail> waveDataDetails, Double lastTime) {
String picPath = null;
WaveDataDetail waveDataDetail = waveDataDetails.get(0);
// 从instantData提取null边界x值作为共享参考
List<Float> sharedNullBoundaries = LineGenerator.extractNullBoundaryXValues(waveDataDetail.getInstantData().getAValue());
String firstPic = drawPicUtil.drawWavePic(getTitle(waveDataDetail.getChannelName()), waveDataDetail.getInstantData().getAValue(),
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen(), lastTime, sharedNullBoundaries,nPush
);
String secondPic;
if (waveDataDetails.size() == 1) {
if (firstPic.contains(PicCommonData.PNG_PREFIX)) {
firstPic = firstPic.replace(PicCommonData.PNG_PREFIX, "");
}
byte[] bytes = Base64.getDecoder().decode(firstPic);
picPath = fileStorageUtil.uploadStream(new ByteArrayInputStream(bytes), OssPath.EVENT_WAVE_PIC, FileUtil.generateFileName("png"));
} else if (waveDataDetails.size() == 2) {
waveDataDetail = waveDataDetails.get(1);
secondPic = drawPicUtil.drawWavePic(getTitle(waveDataDetail.getChannelName()), waveDataDetail.getInstantData().getAValue(),
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen(), lastTime, sharedNullBoundaries,nPush
);
picPath = composeImage(firstPic, secondPic);
}
return picPath;
}
public String getTitle(String channelName) {
return channelName.toUpperCase().startsWith("U1") ? "电压" : "电流";
}
/*** /***
* 绘制RMS波形图 * 绘制RMS波形图
* @author hongawen * @author hongawen
@@ -244,6 +318,89 @@ public class WavePicComponent {
waveDataDetail.getColors(), waveDataDetail.getIsOpen() waveDataDetail.getColors(), waveDataDetail.getIsOpen()
); );
picPath = composeImage(firstPic, secondPic); picPath = composeImage(firstPic, secondPic);
} else if (waveDataDetails.size() == 4) {
WaveDataDetail waveDataDetail1 = waveDataDetails.get(0);
String pic1 = drawPicUtil.drawWavePic(getTitle2(waveDataDetail1.getChannelName(),time), waveDataDetail1.getRmsData().getAValue(),
waveDataDetail1.getRmsData().getBValue(), waveDataDetail1.getRmsData().getCValue(),
waveDataDetail1.getUnit(), waveDataDetail1.getRmsData().getMax(), waveDataDetail1.getRmsData().getMin(),
waveDataDetail1.getA(), waveDataDetail1.getB(), waveDataDetail1.getC(),
waveDataDetail1.getColors(), waveDataDetail1.getIsOpen()
);
WaveDataDetail waveDataDetail2 = waveDataDetails.get(1);
String pic2 = drawPicUtil.drawWavePic(getTitle2(waveDataDetail2.getChannelName(),time), waveDataDetail2.getRmsData().getAValue(),
waveDataDetail2.getRmsData().getBValue(), waveDataDetail2.getRmsData().getCValue(),
waveDataDetail2.getUnit(), waveDataDetail2.getRmsData().getMax(), waveDataDetail2.getRmsData().getMin(),
waveDataDetail2.getA(), waveDataDetail2.getB(), waveDataDetail2.getC(),
waveDataDetail2.getColors(), waveDataDetail2.getIsOpen());
WaveDataDetail waveDataDetail3 = waveDataDetails.get(2);
String pic3 = drawPicUtil.drawWavePic(getTitle2(waveDataDetail3.getChannelName(),time), waveDataDetail3.getRmsData().getAValue(),
waveDataDetail3.getRmsData().getBValue(), waveDataDetail3.getRmsData().getCValue(),
waveDataDetail3.getUnit(), waveDataDetail3.getRmsData().getMax(), waveDataDetail3.getRmsData().getMin(),
waveDataDetail3.getA(), waveDataDetail3.getB(), waveDataDetail3.getC(),
waveDataDetail3.getColors(), waveDataDetail3.getIsOpen());
WaveDataDetail waveDataDetail4 = waveDataDetails.get(3);
String pic4 = drawPicUtil.drawWavePic(getTitle2(waveDataDetail4.getChannelName(),time), waveDataDetail4.getRmsData().getAValue(),
waveDataDetail4.getRmsData().getBValue(), waveDataDetail4.getRmsData().getCValue(),
waveDataDetail4.getUnit(), waveDataDetail4.getRmsData().getMax(), waveDataDetail4.getRmsData().getMin(),
waveDataDetail4.getA(), waveDataDetail4.getB(), waveDataDetail4.getC(),
waveDataDetail4.getColors(), waveDataDetail4.getIsOpen()
);
picPath = composeImageZl(pic1, pic2, pic3, pic4);
}
return picPath;
}
public String getTitle2(String channelName, String time) {
String title;
if (channelName.toUpperCase().startsWith("SU")) {
title ="电压-电网侧" + " 发生时刻:" + time;
} else if (channelName.toUpperCase().startsWith("SI")) {
title ="电流-电网侧" + " 发生时刻:" + time;
} else if (channelName.toUpperCase().startsWith("LU")) {
title ="电压-负载侧" + " 发生时刻:" + time;
} else {
title ="电流-负载侧" + " 发生时刻:" + time;
}
return title;
}
/***
* 绘制RMS波形图 App端用来绘制图片会去掉部分数据只保留开始数据 结束数据
* @author xy
* @return String 文件地址
*/
public String generateImageRms(Integer nPush, List<WaveDataDetail> waveDataDetails, Double lastTime) {
String picPath = null;
WaveDataDetail waveDataDetail = waveDataDetails.get(0);
// 从instantData提取null边界x值作为共享参考与Shun图保持一致
List<Float> sharedNullBoundaries = LineGenerator.extractNullBoundaryXValues(waveDataDetail.getInstantData().getAValue());
String firstPic = drawPicUtil.drawWavePic(getTitle(waveDataDetail.getChannelName()), waveDataDetail.getRmsData().getAValue(),
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen(), lastTime, sharedNullBoundaries,nPush
);
String secondPic;
if (waveDataDetails.size() == 1) {
if (firstPic.contains(PicCommonData.PNG_PREFIX)) {
firstPic = firstPic.replace(PicCommonData.PNG_PREFIX, "");
}
byte[] bytes = Base64.getDecoder().decode(firstPic);
picPath = fileStorageUtil.uploadStream(new ByteArrayInputStream(bytes), OssPath.EVENT_WAVE_PIC, FileUtil.generateFileName("png"));
} else if (waveDataDetails.size() == 2) {
waveDataDetail = waveDataDetails.get(1);
secondPic = drawPicUtil.drawWavePic(getTitle(waveDataDetail.getChannelName()), waveDataDetail.getRmsData().getAValue(),
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
waveDataDetail.getColors(), waveDataDetail.getIsOpen(), lastTime, sharedNullBoundaries,nPush
);
picPath = composeImage(firstPic, secondPic);
} }
return picPath; return picPath;
} }
@@ -284,6 +441,59 @@ public class WavePicComponent {
} }
} }
private String composeImage(String firstPic, String secondPic, String thirdPic, String forthPic) {
try {
//第一张图片 base64截取删除前缀data:image/png;base64,
BufferedImage imageOne = ImgUtil.toBufferedImage(ImgUtil.toImage(firstPic.substring(22)), ImgUtil.IMAGE_TYPE_PNG);
int width = imageOne.getWidth();
int height = imageOne.getHeight();
int[] imageArrayOne = new int[width * height];
imageArrayOne = imageOne.getRGB(0, 0, width, height, imageArrayOne, 0, width);
//第二张图片 base64截取删除前缀data:image/png;base64,
BufferedImage imageTwo = ImgUtil.toBufferedImage(ImgUtil.toImage(secondPic.substring(22)), ImgUtil.IMAGE_TYPE_PNG);
int width2 = imageTwo.getWidth();
int height2 = imageTwo.getHeight();
int[] ImageArrayTwo = new int[width2 * height2];
ImageArrayTwo = imageTwo.getRGB(0, 0, width, height, ImageArrayTwo, 0, width);
int[] ImageArrayThree = null;
if (Objects.equals(thirdPic, "")) {
BufferedImage imageThree = ImgUtil.toBufferedImage(ImgUtil.toImage(thirdPic.substring(22)), ImgUtil.IMAGE_TYPE_PNG);
int width3 = imageThree.getWidth();
int height3 = imageThree.getHeight();
ImageArrayThree = new int[width3 * height3];
ImageArrayThree = imageThree.getRGB(0, 0, width, height, ImageArrayThree, 0, width);
}
int[] ImageArrayForth = null;
if (Objects.equals(forthPic, "")) {
BufferedImage imageForth = ImgUtil.toBufferedImage(ImgUtil.toImage(forthPic.substring(22)), ImgUtil.IMAGE_TYPE_PNG);
int width4 = imageForth.getWidth();
int height4 = imageForth.getHeight();
ImageArrayForth = new int[width4 * height4];
ImageArrayForth = imageForth.getRGB(0, 0, width, height, ImageArrayForth, 0, width);
}
//新图片
BufferedImage imageNew = new BufferedImage(width, height * 2, BufferedImage.TYPE_INT_RGB);
BufferedImageGraphicsConfig config = BufferedImageGraphicsConfig.getConfig(imageNew);
imageNew = config.createCompatibleImage(width, height * 2, Transparency.TRANSLUCENT);
imageNew.setRGB(0, 0, width, height, imageArrayOne, 0, width);
imageNew.setRGB(0, height, width, height, ImageArrayTwo, 0, width);
if (!Objects.isNull(ImageArrayThree)) {
imageNew.setRGB(0, height, width, height, ImageArrayThree, 0, width);
}
if (!Objects.isNull(ImageArrayForth)) {
imageNew.setRGB(0, height, width, height, ImageArrayForth, 0, width);
}
String resultImg = ImgUtil.toBase64(imageNew, ImgUtil.IMAGE_TYPE_PNG);
byte[] bytes = Base64.getDecoder().decode(resultImg);
return fileStorageUtil.uploadStream(new ByteArrayInputStream(bytes), OssPath.EVENT_WAVE_PIC, FileUtil.generateFileName("png"));
} catch (Exception e) {
throw new BusinessException(WaveFileResponseEnum.COMPOSE_PIC_ERROR);
}
}
/** /**
* app越限指标图 * app越限指标图
* @param title * @param title

View File

@@ -7,6 +7,7 @@ import com.njcn.event.file.pojo.dto.WaveDataDTO;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* @author hongawen * @author hongawen
@@ -80,28 +81,49 @@ public class WaveUtil {
//根据相别来确认标题的名称 //根据相别来确认标题的名称
for (int m = 0; m < iPhase; m++) { for (int m = 0; m < iPhase; m++) {
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("A")) { if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("A")) {
float tmpShunFirstA = sunData.get(j).get(iPhase * i + m + 1) * xishu; if (Objects.isNull(sunData.get(j).get(iPhase * i + m + 1))) {
shunFirstA = tmpShunFirstA; sAValue.add(new ArrayList<Float>() {{
sAValue.add(new ArrayList<Float>() {{ add(x);
add(x); add(null);
add(tmpShunFirstA); }});
}}); } else {
float tmpShunFirstA = sunData.get(j).get(iPhase * i + m + 1) * xishu;
shunFirstA = tmpShunFirstA;
sAValue.add(new ArrayList<Float>() {{
add(x);
add(tmpShunFirstA);
}});
}
} }
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("B")) { if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("B")) {
float tmpShunFirstB = sunData.get(j).get(iPhase * i + m + 1) * xishu; if (Objects.isNull(sunData.get(j).get(iPhase * i + m + 1))) {
shunFirstB = tmpShunFirstB; sBValue.add(new ArrayList<Float>() {{
sBValue.add(new ArrayList<Float>() {{ add(x);
add(x); add(null);
add(tmpShunFirstB); }});
}}); } else {
float tmpShunFirstB = sunData.get(j).get(iPhase * i + m + 1) * xishu;
shunFirstB = tmpShunFirstB;
sBValue.add(new ArrayList<Float>() {{
add(x);
add(tmpShunFirstB);
}});
}
} }
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("C")) { if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("C")) {
float tmpShunFirstC = sunData.get(j).get(iPhase * i + m + 1) * xishu; if (Objects.isNull(sunData.get(j).get(iPhase * i + m + 1))) {
shunFirstC = tmpShunFirstC; sCValue.add(new ArrayList<Float>() {{
sCValue.add(new ArrayList<Float>() {{ add(x);
add(x); add(null);
add(tmpShunFirstC); }});
}}); } else {
float tmpShunFirstC = sunData.get(j).get(iPhase * i + m + 1) * xishu;
shunFirstC = tmpShunFirstC;
sCValue.add(new ArrayList<Float>() {{
add(x);
add(tmpShunFirstC);
}});
}
} }
} }
sfMax = getMax(sfMax, shunFirstA, shunFirstB, shunFirstC); sfMax = getMax(sfMax, shunFirstA, shunFirstB, shunFirstC);
@@ -124,28 +146,50 @@ public class WaveUtil {
//根据相别来确认标题的名称 //根据相别来确认标题的名称
for (int m = 0; m < iPhase; m++) { for (int m = 0; m < iPhase; m++) {
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("A")) { if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("A")) {
float tmpRmsFirstA = rmsData.get(k).get(iPhase * i + m + 1) * xishu; if (Objects.isNull(rmsData.get(k).get(iPhase * i + m + 1))) {
rmsFirstA = tmpRmsFirstA; rAValue.add(new ArrayList<Float>() {{
rAValue.add(new ArrayList<Float>() {{ add(x);
add(x); add(null);
add(tmpRmsFirstA); }});
}}); } else {
float tmpRmsFirstA = rmsData.get(k).get(iPhase * i + m + 1) * xishu;
rmsFirstA = tmpRmsFirstA;
rAValue.add(new ArrayList<Float>() {{
add(x);
add(tmpRmsFirstA);
}});
}
} }
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("B")) { if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("B")) {
float tmpRmsFirstB = rmsData.get(k).get(iPhase * i + m + 1) * xishu; if (Objects.isNull(rmsData.get(k).get(iPhase * i + m + 1))) {
rmsFirstB = tmpRmsFirstB; rBValue.add(new ArrayList<Float>() {{
rBValue.add(new ArrayList<Float>() {{ add(x);
add(x); add(null);
add(tmpRmsFirstB); }});
}}); } else {
float tmpRmsFirstB = rmsData.get(k).get(iPhase * i + m + 1) * xishu;
rmsFirstB = tmpRmsFirstB;
rBValue.add(new ArrayList<Float>() {{
add(x);
add(tmpRmsFirstB);
}});
}
} }
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("C")) { if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("C")) {
float tmpRmsFirstC = rmsData.get(k).get(iPhase * i + m + 1) * xishu; if (Objects.isNull(rmsData.get(k).get(iPhase * i + m + 1))) {
rmsFirstC = tmpRmsFirstC; rCValue.add(new ArrayList<Float>() {{
rCValue.add(new ArrayList<Float>() {{ add(x);
add(x); add(null);
add(tmpRmsFirstC); }});
}}); } else {
float tmpRmsFirstC = rmsData.get(k).get(iPhase * i + m + 1) * xishu;
rmsFirstC = tmpRmsFirstC;
rCValue.add(new ArrayList<Float>() {{
add(x);
add(tmpRmsFirstC);
}});
}
} }
} }
rfMax = getMax(sfMax, rmsFirstA, rmsFirstB, rmsFirstC); rfMax = getMax(sfMax, rmsFirstA, rmsFirstB, rmsFirstC);

View File

@@ -77,6 +77,12 @@ public interface BusinessTopic {
*/ */
String REPLY_RECALL_TOPIC = "reply_recall_Topic"; String REPLY_RECALL_TOPIC = "reply_recall_Topic";
/**
* 治理心跳过期处理主题
*/
String HEARTBEAT_TIMEOUT_TOPIC = "heartbeat_timeout_topic";
/********************************数据中心*********************************/ /********************************数据中心*********************************/
String RMP_EVENT_DETAIL_TOPIC = "rmpEventDetailTopic"; String RMP_EVENT_DETAIL_TOPIC = "rmpEventDetailTopic";
@@ -104,6 +110,8 @@ public interface BusinessTopic {
String CLOUD_REPLY_TOPIC = "Cloud_Reply_Topic"; String CLOUD_REPLY_TOPIC = "Cloud_Reply_Topic";
String ZL_LOG_TOPIC = "ZL_LOG_Topic";
interface AppDataTag { interface AppDataTag {
@@ -147,4 +155,23 @@ public interface BusinessTopic {
String STREAM_TAG = "streamInfo"; String STREAM_TAG = "streamInfo";
} }
interface HeartTag {
/**
* apf 心跳
*/
String APF_TAG = "apf";
/**
* cld 心跳
*/
String CLD_TAG = "cld";
}
interface LogTag {
//日志
String LOG_TAG = "log";
}
} }

View File

@@ -0,0 +1,27 @@
package com.njcn.mq.message;
import com.njcn.middle.rocket.domain.BaseMessage;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author xy
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
public class HeartbeatTimeoutMessage extends BaseMessage implements Serializable {
private static final long serialVersionUID = 1L;
private String nDid;
private Long timestamp;
private Integer delayLevel;
}

View File

@@ -0,0 +1,43 @@
package com.njcn.mq.message;
import com.njcn.middle.rocket.domain.BaseMessage;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2025/9/29 15:06
*/
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LogMessage extends BaseMessage {
@ApiModelProperty("唯一标识")
private String guid;
@ApiModelProperty("日志类型 0:设备接入日志")
private String dataType;
@ApiModelProperty("操作人员")
private String userIndex;
@ApiModelProperty("用户登录名")
private String loginName;
@ApiModelProperty("当前操作")
private String operate;
@ApiModelProperty("结果")
private Integer result;
@ApiModelProperty("失败原因")
private String failReason;
}

View File

@@ -0,0 +1,29 @@
package com.njcn.mq.template;
import com.njcn.middle.rocket.template.RocketMQEnhanceTemplate;
import com.njcn.mq.constant.BusinessResource;
import com.njcn.mq.constant.BusinessTopic;
import com.njcn.mq.message.HeartbeatTimeoutMessage;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.stereotype.Component;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2023/8/11 15:28
*/
@Component
public class HeartbeatTimeoutMessageTemplate extends RocketMQEnhanceTemplate {
public HeartbeatTimeoutMessageTemplate(RocketMQTemplate template) {
super(template);
}
public SendResult sendMember(HeartbeatTimeoutMessage heartbeatTimeoutMessage) {
heartbeatTimeoutMessage.setSource(BusinessResource.WEB_RESOURCE);
return send(BusinessTopic.HEARTBEAT_TIMEOUT_TOPIC, BusinessTopic.HeartTag.APF_TAG, heartbeatTimeoutMessage, heartbeatTimeoutMessage.getDelayLevel());
}
}

View File

@@ -0,0 +1,28 @@
package com.njcn.mq.template;
import com.njcn.middle.rocket.template.RocketMQEnhanceTemplate;
import com.njcn.mq.constant.BusinessResource;
import com.njcn.mq.constant.BusinessTopic;
import com.njcn.mq.message.LogMessage;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.stereotype.Component;
/**
* 类的介绍:记录日志
*
* @author xuyang
* @version 1.0.0
*/
@Component
public class LogMessageTemplate extends RocketMQEnhanceTemplate {
public LogMessageTemplate(RocketMQTemplate template) {
super(template);
}
public SendResult sendMember(LogMessage logMessage) {
logMessage.setSource(BusinessResource.APP_RESOURCE);
return send(BusinessTopic.ZL_LOG_TOPIC, BusinessTopic.LogTag.LOG_TAG, logMessage);
}
}

View File

@@ -102,8 +102,11 @@ public class FileStorageUtil {
throw new BusinessException(OssResponseEnum.UPLOAD_FILE_ERROR); throw new BusinessException(OssResponseEnum.UPLOAD_FILE_ERROR);
} }
} else if (generalInfo.getBusinessFileStorage() == GeneralConstant.AliYUN_OSS) { } else if (generalInfo.getBusinessFileStorage() == GeneralConstant.AliYUN_OSS) {
filePath = dir; filePath = dir.endsWith("/")?dir+getFileNameWithoutPath(multipartFile):dir+"/"+getFileNameWithoutPath(multipartFile);
aliYunOssUtils.uploadFile(dir, multipartFile); if (filePath.charAt(0) == '/') {
filePath= filePath.substring(1);
}
aliYunOssUtils.uploadFile(filePath, multipartFile);
} else { } else {
try { try {
// 构建完整目录:基准目录 + dir子目录 // 构建完整目录:基准目录 + dir子目录
@@ -154,8 +157,11 @@ public class FileStorageUtil {
filePath = dir + minIoUtils.minFileName(multipartFile.getOriginalFilename()); filePath = dir + minIoUtils.minFileName(multipartFile.getOriginalFilename());
obsUtil.uploadMultipart(multipartFile, filePath); obsUtil.uploadMultipart(multipartFile, filePath);
} else if (generalInfo.getBusinessFileStorage() == GeneralConstant.AliYUN_OSS) { } else if (generalInfo.getBusinessFileStorage() == GeneralConstant.AliYUN_OSS) {
filePath = dir; filePath = dir.endsWith("/")?dir+getFileNameWithoutPath(multipartFile):dir+"/"+getFileNameWithoutPath(multipartFile);
aliYunOssUtils.uploadFile(dir, multipartFile); if (filePath.charAt(0) == '/') {
filePath= filePath.substring(1);
}
aliYunOssUtils.uploadFile(filePath, multipartFile);
} else { } else {
try { try {
//把名称存入数据 //把名称存入数据
@@ -167,6 +173,15 @@ public class FileStorageUtil {
} }
return filePath; return filePath;
} }
public static String getFileNameWithoutPath(MultipartFile file) {
String originalFilename = file.getOriginalFilename();
if (originalFilename == null) {
return null;
}
// 统一分隔符为 '/',再取最后一部分
String normalized = originalFilename.replace('\\', '/');
return normalized.substring(normalized.lastIndexOf('/') + 1);
}
/*** /***
* 上传InputStream流 * 上传InputStream流

View File

@@ -239,18 +239,47 @@ public class ExcelUtil {
* @param strings 下拉内容 * @param strings 下拉内容
*/ */
public static void selectList(Workbook workbook, int firstCol, int lastCol, String[] strings) { public static void selectList(Workbook workbook, int firstCol, int lastCol, String[] strings) {
Sheet sheet = workbook.getSheetAt(0); // Sheet sheet = workbook.getSheetAt(0);
// 生成下拉列表 // // 生成下拉列表
// 只对(xx)单元格有效 // // 只对(xx)单元格有效
CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(2, 65535, firstCol, lastCol); // CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(2, 65535, firstCol, lastCol);
// 生成下拉框内容 // // 生成下拉框内容
DataValidationHelper dvHelper = sheet.getDataValidationHelper(); // DataValidationHelper dvHelper = sheet.getDataValidationHelper();
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) // XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
dvHelper.createExplicitListConstraint(strings); // dvHelper.createExplicitListConstraint(strings);
XSSFDataValidation validation = (XSSFDataValidation) dvHelper.createValidation( // XSSFDataValidation validation = (XSSFDataValidation) dvHelper.createValidation(
dvConstraint, cellRangeAddressList); // dvConstraint, cellRangeAddressList);
// 对sheet页生效 // // 对sheet页生效
sheet.addValidationData(validation); // sheet.addValidationData(validation);
Sheet targetSheet = workbook.getSheetAt(0);
// ===================== 关键每个下拉用唯一名称的隐藏Sheet =====================
String uniqueHiddenName = "dropdown_" + firstCol + "_" + lastCol + "_" + System.currentTimeMillis();
Sheet hiddenSheet = workbook.createSheet(uniqueHiddenName);
// 隐藏数据源Sheet
workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true);
// 写入选项到隐藏Sheet
for (int i = 0; i < strings.length; i++) {
Row row = hiddenSheet.createRow(i);
Cell cell = row.createCell(0);
cell.setCellValue(strings[i]);
}
// 构造引用公式(无长度限制)
String formula = uniqueHiddenName + "!$A$1:$A$" + strings.length;
// 下拉作用范围第3行 ~ 65536行
CellRangeAddressList range = new CellRangeAddressList(2, 65535, firstCol, lastCol);
DataValidationHelper helper = targetSheet.getDataValidationHelper();
DataValidationConstraint constraint = helper.createFormulaListConstraint(formula);
DataValidation validation = helper.createValidation(constraint, range);
// 必加:防止下拉冲突、不显示
validation.setShowErrorBox(true);
validation.setShowPromptBox(true);
targetSheet.addValidationData(validation);
} }
/** /**

View File

@@ -4,13 +4,15 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.CharsetUtil;
import com.njcn.common.pojo.enums.response.CommonResponseEnum; import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import javax.servlet.ServletOutputStream; import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Objects;
/** /**
* @author hongawen * @author hongawen
@@ -76,6 +78,59 @@ public class PoiUtil {
fileName = URLEncoder.encode(fileName, CharsetUtil.UTF_8); fileName = URLEncoder.encode(fileName, CharsetUtil.UTF_8);
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
response.setContentType("application/octet-stream;charset=" + CharsetUtil.UTF_8); response.setContentType("application/octet-stream;charset=" + CharsetUtil.UTF_8);
//将带*号的列变成红色
Sheet sheetAt = workbook.getSheetAt(0);
//获取列数
int physicalNumberOfCells = sheetAt.getRow(0).getPhysicalNumberOfCells();
//没有表格标题,只有表格头
for (int i = 0; i < 2; i++) {
//获取行
Row row = sheetAt.getRow(i);
if (Objects.isNull(row)) {
continue;
}
for (int j = 0; j < physicalNumberOfCells; j++) {
//获取单元格对象
Cell cell = row.getCell(j);
//获取单元格样式对象
CellStyle cellStyle = workbook.createCellStyle();
//获取单元格内容对象
Font font = workbook.createFont();
font.setFontHeightInPoints((short) 12);
//一定要装入 样式中才会生效
cellStyle.setFont(font);
//设置居中对齐
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
//设置单元格字体颜色
cell.setCellStyle(cellStyle);
//获取当前值
String stringCellValue = cell.getStringCellValue();
if (stringCellValue.contains("*")) {
// 创建一个富文本
XSSFRichTextString xssfRichTextString = new XSSFRichTextString(stringCellValue);
int startIndex = stringCellValue.indexOf("*");
int entIndex = stringCellValue.lastIndexOf("*");
if (entIndex != 0) {
Font font3 = workbook.createFont();
font3.setFontHeightInPoints((short) 12);
font3.setColor(Font.COLOR_NORMAL);
xssfRichTextString.applyFont(0, entIndex, font3);
}
//设置带*样式
Font font1 = workbook.createFont();
font1.setFontHeightInPoints((short) 12);
font1.setColor(Font.COLOR_RED);
xssfRichTextString.applyFont(startIndex, entIndex + 1, font1);
//其他样式
Font font2 = workbook.createFont();
font2.setFontHeightInPoints((short) 12);
font2.setColor(Font.COLOR_NORMAL);
xssfRichTextString.applyFont(entIndex + 1, stringCellValue.length(), font2);
cell.setCellValue(xssfRichTextString);
}
}
}
workbook.write(outputStream); workbook.write(outputStream);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -13,7 +13,7 @@ public interface AppRedisKey {
/** /**
* 设备模板前缀 * 设备模板前缀
*/ */
String MODEL = "MODEL"; String MODEL = "MODEL:";
/** /**
@@ -39,7 +39,7 @@ public interface AppRedisKey {
/** /**
* 监测点位置数据 * 监测点位置数据
*/ */
String LINE_POSITION = "LINEPOSITION"; String LINE_POSITION = "LINEPOSITION:";
/** /**
* rocketMQ消费key * rocketMQ消费key

View File

@@ -347,6 +347,30 @@ public class RedisUtil {
return info; return info;
} }
/**
* 根据key模糊查询,并取出所有符合条件的key集合
* @return
*/
public Set<String> scanKeysByPattern(String pattern, int count) {
Set<String> keys = new HashSet<>();
ScanOptions options = ScanOptions.scanOptions()
.match(pattern)
.count(count)
.build();
try (Cursor<byte[]> cursor = redisTemplate.getConnectionFactory()
.getConnection()
.scan(options)) {
while (cursor.hasNext()) {
keys.add(new String(cursor.next()));
}
} catch (Exception e) {
throw new RuntimeException("扫描Redis keys失败", e);
}
return keys;
}
/** /**
* 数据切库 * 数据切库
* @param dbIndex * @param dbIndex

View File

@@ -1,5 +1,8 @@
package com.njcn.web.utils; package com.njcn.web.utils;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.http.*; import org.springframework.http.*;
@@ -149,7 +152,8 @@ public class RestTemplateUtil {
* @return ResponseEntity 响应对象封装类 * @return ResponseEntity 响应对象封装类
*/ */
public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType) { public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType) {
return restTemplate.postForEntity(url, requestBody, responseType); Object actualBody = convertHutoolJsonToStandard(requestBody);
return restTemplate.postForEntity(url, actualBody, responseType);
} }
/** /**
@@ -162,7 +166,8 @@ public class RestTemplateUtil {
* @return ResponseEntity 响应对象封装类 * @return ResponseEntity 响应对象封装类
*/ */
public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType, Object... uriVariables) { public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType, Object... uriVariables) {
return restTemplate.postForEntity(url, requestBody, responseType, uriVariables); Object actualBody = convertHutoolJsonToStandard(requestBody);
return restTemplate.postForEntity(url, actualBody, responseType, uriVariables);
} }
/** /**
@@ -175,7 +180,21 @@ public class RestTemplateUtil {
* @return ResponseEntity 响应对象封装类 * @return ResponseEntity 响应对象封装类
*/ */
public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) { public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
return restTemplate.postForEntity(url, requestBody, responseType, uriVariables); Object actualBody = convertHutoolJsonToStandard(requestBody);
return restTemplate.postForEntity(url, actualBody, responseType, uriVariables);
}
private static Object convertHutoolJsonToStandard(Object requestBody) {
if (requestBody instanceof JSONObject || requestBody instanceof JSONArray) {
try {
com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
return objectMapper.readValue(JSONUtil.toJsonStr(requestBody), Object.class);
} catch (Exception e) {
log.warn("Hutool JSON转标准结构失败尝试直接使用字符串", e);
return requestBody;
}
}
return requestBody;
} }
/** /**

View File

@@ -19,14 +19,16 @@ public enum RunFlagEnum {
QUIT(4, "退运"), QUIT(4, "退运"),
POWER_FLAG(0,"电网侧"),
NO_POWER_FLAG(1,"非电网侧"),
GW_FLAG(0,"主网"), GW_FLAG(0,"主网"),
PW_FLAG(1,"配网"), PW_FLAG(1,"配网"),
I_SORT(1,"I类测点"),
II_SORT(2,"II类测点"),
III_SORT(3,"III类测点"),
; ;

View File

@@ -41,6 +41,11 @@ public class LineALLInfoDTO {
private Integer num; private Integer num;
@ApiModelProperty(name = "objName",value = "监测点对象名称") @ApiModelProperty(name = "objName",value = "监测点对象名称")
private String objName; private String objName;
@ApiModelProperty(name = "objName",value = "电网侧监测点对象名称Id")
private String objId;
@ApiModelProperty(name = "objName",value = "电网侧监测点对象名称")
private String objName2;
@ApiModelProperty(name = "loadType",value = "监测对象类型") @ApiModelProperty(name = "loadType",value = "监测对象类型")
private String loadType; private String loadType;
@ApiModelProperty(name = "voltageLevel",value = "电压等级") @ApiModelProperty(name = "voltageLevel",value = "电压等级")

View File

@@ -25,6 +25,9 @@ public class MonitorCommLedgerInfoDTO implements Serializable {
private String busBarName; private String busBarName;
private String objName;
private String voltageLevel; private String voltageLevel;
private String shortCapacity; private String shortCapacity;

View File

@@ -104,4 +104,9 @@ public class PollutionLineInfoDTO {
* 实际安装位置 * 实际安装位置
*/ */
private String actualArea; private String actualArea;
/**
* 监测点运行状态
*/
private String runFlag;
} }

View File

@@ -2,7 +2,6 @@ package com.njcn.device.biz.pojo.po;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.device.biz.utils.COverlimit;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;

View File

@@ -18,7 +18,8 @@ import java.util.Objects;
*/ */
public class COverlimitUtil { public class COverlimitUtil {
/** 配网占位默认值 */
private static final float PLACEHOLDER = -3.14159f;
/** /**
* 谐波电流系数 * 谐波电流系数
*/ */
@@ -34,38 +35,74 @@ public class COverlimitUtil {
/** /**
* 计算监测点限值 * 计算监测点限值
* @param voltageLevel 电压等级10kV = 10 220kV = 220 * @param voltageLevel 电压等级(kV)
* @param protocolCapacity 协议容量 * @param protocolCapacity 协议容量(MVA)
* @param devCapacity 设备容量 * @param devCapacity 供电设备容量(MVA),为空/0自动取对应电压默认值
* @param shortCapacity 短路容量 * @param shortCapacity 实际最小短路容量(MVA)
* @param powerFlag 0.用户侧 1.电网侧 * @param powerFlag 0=电网侧(不执行两步计算) 1=非电网侧/用户侧(执行两步计算)
* @param lineType 0.主网 1.配网 需要注意配网目前没有四种容量,谐波电流幅值限值,负序电流限值无法计算默认-3.14159 * @param pointClass 配网点类型 0=Ⅱ类 1=Ⅲ类光伏主网该字段传0即可
*/ */
public static Overlimit globalAssemble(Float voltageLevel, Float protocolCapacity, Float devCapacity, public static Overlimit globalAssemble(Float voltageLevel, Float protocolCapacity, Float devCapacity,
Float shortCapacity, Integer powerFlag, Integer lineType) { Float shortCapacity, Integer powerFlag,Integer pointClass) {
Overlimit overlimit = new Overlimit(); Overlimit overlimit = new Overlimit();
voltageDeviation(overlimit,voltageLevel); voltageDeviation(overlimit, voltageLevel);
frequency(overlimit); frequency(overlimit);
voltageFluctuation(overlimit,voltageLevel); voltageFluctuation(overlimit, voltageLevel);
voltageFlicker(overlimit,voltageLevel); voltageFlicker(overlimit, voltageLevel);
totalHarmonicDistortion(overlimit,voltageLevel); totalHarmonicDistortion(overlimit, voltageLevel);
uHarm(overlimit,voltageLevel); uHarm(overlimit, voltageLevel);
threeVoltageUnbalance(overlimit); threeVoltageUnbalance(overlimit);
interharmonicCurrent(overlimit,voltageLevel); interharmonicCurrent(overlimit, voltageLevel);
negativeSequenceCurrent(overlimit, voltageLevel, shortCapacity);
//谐波电流限值
int lineType;
if (voltageLevel >= DicDataEnum.KV220.getValue()) {
lineType = 0; // 主网
} else {
lineType = 1; // 配网110、66、35、10kV
}
float sc = Objects.isNull(shortCapacity) ? 0f : shortCapacity;
float pc = Objects.isNull(protocolCapacity) ? 0f : protocolCapacity;
if(Objects.equals(lineType, RunFlagEnum.PW_FLAG.getStatus())) { float dc;
//配网 if (Objects.isNull(devCapacity) || devCapacity <= 0) {
dc = getDefaultDevCapacity(voltageLevel);
} else {
dc = devCapacity;
}
// 1. 配网 lineType = 1
if (Objects.equals(lineType, RunFlagEnum.PW_FLAG.getStatus())) {
Float[] iHarmTem = new Float[49]; Float[] iHarmTem = new Float[49];
for (int i = 0; i <= 48; i++) {
//目前只处理了配网II类测点III类测点暂未处理III类测点参考主网 // 配网-电网侧(powerFlag=0) / 配网Ⅱ类:直接基准限值,不折算
iHarmTem[i] = getHarmTag(i+2,voltageLevel).floatValue(); if (Objects.equals(powerFlag,RunFlagEnum.POWER_FLAG.getStatus()) || Objects.equals(pointClass, 0)) {
for (int i = 0; i <= 48; i++) {
iHarmTem[i] = getHarmTag(i + 2, voltageLevel).floatValue();
}
}
// 配网-非电网侧 且 Ⅲ类光伏两步计算折算系数固定为1
else {
float calCap = 1.0f;
for (int i = 0; i <= 48; i++) {
float inHarm = iHarmCalculate(i + 2, voltageLevel, pc, dc, calCap);
iHarmTem[i] = inHarm;
}
} }
overlimit.buildIHarm(iHarmTem); overlimit.buildIHarm(iHarmTem);
overlimit.setINeg(-3.14159f); } else {
}else { // 主网-电网侧(powerFlag=0):直接基准限值
//主网 if (Objects.equals(powerFlag, RunFlagEnum.POWER_FLAG.getStatus())) {
iHarm(overlimit, voltageLevel, protocolCapacity, devCapacity, shortCapacity); Float[] iHarmTem = new Float[49];
negativeSequenceCurrent(overlimit, voltageLevel, shortCapacity); for (int i = 0; i <= 48; i++) {
iHarmTem[i] = getHarmTag(i + 2, voltageLevel).floatValue();
}
overlimit.buildIHarm(iHarmTem);
}
// 主网-非电网侧/用户侧(风光场站):完整两步计算
else {
iHarm(overlimit, voltageLevel, pc, dc, sc);
}
} }
return overlimit; return overlimit;
} }
@@ -304,6 +341,30 @@ public class COverlimitUtil {
} }
/**
* 根据电压等级获取【默认公共连接点供电设备容量】St(MVA)
* 无实际台账容量时兜底使用
*/
public static float getDefaultDevCapacity(Float voltageLevel) {
if (voltageLevel < 0.4f) {
return 1.0f;
} else if (voltageLevel < 6f) {
return 100f;
} else if (voltageLevel < 20f) {
return 200f;
} else if (voltageLevel < 35f) {
return 500f;
} else if (voltageLevel < 66f) {
return 800f;
} else if (voltageLevel < 110f) {
return 1000f;
} else if (voltageLevel < 220f) {
return 2000f;
} else {
return 3000f;
}
}
/*---------------------------------谐波电流限值end-----------------------------------*/ /*---------------------------------谐波电流限值end-----------------------------------*/
@@ -376,8 +437,9 @@ public class COverlimitUtil {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("sss"); System.out.println("sss");
float aa = iHarmCalculate(9,500f,10,10,0.002222222222f); Overlimit overlimit = new Overlimit();
iHarm(overlimit, 220f, 100f, 100f, 2000f);
System.out.println(aa); System.out.println(overlimit);
} }
} }

View File

@@ -22,65 +22,65 @@ import java.math.BigDecimal;
public class TerminalBaseExcel implements Serializable { public class TerminalBaseExcel implements Serializable {
@Excel(name = "项目", width = 15) @Excel(name = "*项目", width = 15)
@NotBlank(message = DeviceValidMessage.PROJECT_NAME_NOT) @NotBlank(message = DeviceValidMessage.PROJECT_NAME_NOT)
@Pattern(regexp = PatternRegex.DEPT_NAME_REGEX, message = DeviceValidMessage.PROJECT_NAME_RULE) @Pattern(regexp = PatternRegex.DEPT_NAME_REGEX, message = DeviceValidMessage.PROJECT_NAME_RULE)
private String projectName; private String projectName;
@Excel(name = "工程", width = 15) @Excel(name = "*省份", width = 15)
@NotBlank(message = DeviceValidMessage.PROVINCE_NAME_NOT) @NotBlank(message = DeviceValidMessage.PROVINCE_NAME_NOT)
private String provinceName; private String provinceName;
@Excel(name = "单位", width = 15) @Excel(name = "*供电公司", width = 15)
@NotBlank(message = "供电公司名称") @NotBlank(message = "供电公司名称")
@Pattern(regexp = PatternRegex.DEV_NAME_REGEX, message = "供电公司名称违规") @Pattern(regexp = PatternRegex.DEV_NAME_REGEX, message = "供电公司名称违规")
private String gdName; private String gdName;
@Excel(name = "部门", width = 15) @Excel(name = "*变电站", width = 15)
@NotBlank(message = "变电站名称不可为空") @NotBlank(message = "变电站名称不可为空")
@Pattern(regexp = PatternRegex.DEV_NAME_REGEX, message = "变电站名称违规") @Pattern(regexp = PatternRegex.DEV_NAME_REGEX, message = "变电站名称违规")
private String substationName; private String substationName;
@Excel(name = "部门电压等级", width = 15) @Excel(name = "*变电站电压等级", width = 15)
@NotBlank(message = "电压等级不可为空") @NotBlank(message = "变电站电压等级不可为空")
private String subStationScale; private String subStationScale;
@Excel(name = "经度", width = 15) @Excel(name = "*经度", width = 15)
private BigDecimal lng; private BigDecimal lng;
@Excel(name = "纬度", width = 15) @Excel(name = "*纬度", width = 15)
private BigDecimal lat; private BigDecimal lat;
@Excel(name = "终端", width = 15) @Excel(name = "*装置名称", width = 15)
@Pattern(regexp = PatternRegex.DEV_NAME_REGEX, message = "设备名称违规") @Pattern(regexp = PatternRegex.DEV_NAME_REGEX, message = "装置名称违规")
private String deviceName; private String deviceName;
@Excel(name = "终端模型", replace = {"虚拟设备_0", "实际设备_1", "离线设备_2"}, width = 15) @Excel(name = "*终端模型", replace = {"虚拟设备_0", "实际设备_1", "离线设备_2"}, width = 15)
@NotNull(message = "设备模型不能为空") @NotNull(message = "设备模型不能为空")
private Integer devModel; private Integer devModel;
@Excel(name = "数据类型", replace = {"暂态系统_0", "稳态系统_1", "双系统_2"}, width = 15) @Excel(name = "*数据类型", replace = {"暂态系统_0", "稳态系统_1", "双系统_2"}, width = 15)
@NotNull(message = "数据类型不能为空") @NotNull(message = "数据类型不能为空")
private Integer devDataType; private Integer devDataType;
@Excel(name = "运行状态", replace = {"投运_0", "热备用_1", "停运_2"}, width = 15) @Excel(name = "*运行状态", replace = {"投运_0", "热备用_1", "停运_2"}, width = 15)
@NotNull(message = "运行状态不能为空") @NotNull(message = "运行状态不能为空")
private Integer runFlag; private Integer runFlag;
@Excel(name = "终端厂家", width = 15) @Excel(name = "*终端厂家", width = 15)
@NotBlank(message = "终端厂家不能为空") @NotBlank(message = "终端厂家不能为空")
private String manufacturer; private String manufacturer;
@Excel(name = "设备型号", width = 15) @Excel(name = "*设备型号", width = 15)
@NotBlank(message = "设备型号不能为空") @NotBlank(message = "设备型号不能为空")
private String devType; private String devType;
@Excel(name = "网络参数", width = 15) @Excel(name = "*网络参数", width = 15)
@NotBlank(message = "设备网络参数不能为空") @NotBlank(message = "设备网络参数不能为空")
private String ip; private String ip;
@Excel(name = "端口", width = 15) @Excel(name = "*端口", width = 15)
@Range(min = 1, max = 100000, message = "端口号违规") @Range(min = 1, max = 100000, message = "端口号违规")
@NotNull(message = "设备端口号不能为空") @NotNull(message = "设备端口号不能为空")
private Integer port; private Integer port;
@@ -91,15 +91,15 @@ public class TerminalBaseExcel implements Serializable {
@Excel(name = "终端秘钥", width = 15) @Excel(name = "终端秘钥", width = 15)
private String devKey; private String devKey;
@Excel(name = "召唤标志",replace = {"周期触发_0", "变为触发_1"}, width = 15) @Excel(name = "*召唤标志",replace = {"周期触发_0", "变为触发_1"}, width = 15)
@NotNull(message = "召唤标志不为空") @NotNull(message = "召唤标志不为空")
private Integer callFlag; private Integer callFlag;
@Excel(name = "前置名称", width = 15) @Excel(name = "*前置名称", width = 15)
@NotBlank(message = "前置名称不能为空") @NotBlank(message = "前置名称不能为空")
private String nodeName; private String nodeName;
@Excel(name = "前置类型", width = 15) @Excel(name = "*前置类型", width = 15)
@NotBlank(message = "前置类型不能为空") @NotBlank(message = "前置类型不能为空")
private String frontType; private String frontType;
@@ -109,71 +109,71 @@ public class TerminalBaseExcel implements Serializable {
@Excel(name = "SIM卡号", width = 15) @Excel(name = "SIM卡号", width = 15)
private String sim; private String sim;
@Excel(name = "母线", width = 15) @Excel(name = "*母线", width = 15)
@NotBlank(message = "母线名称不能为空") @NotBlank(message = "母线名称不能为空")
private String subvName; private String subvName;
@Excel(name = "母线号", width = 15) @Excel(name = "*母线号", width = 15)
@NotNull(message = "母线号不为空") @NotNull(message = "母线号不为空")
private Integer subvNum; private Integer subvNum;
@Excel(name = "母线电压等级", width = 15) @Excel(name = "*母线电压等级", width = 15)
@NotBlank(message = "母线电压等级不能为空") @NotBlank(message = "母线电压等级不能为空")
private String subvScale; private String subvScale;
@Excel(name = "母线模型", replace = {"虚拟母线_0", "实际母线_1"}, width = 15) @Excel(name = "*母线模型", replace = {"虚拟母线_0", "实际母线_1"}, width = 15)
@NotNull(message = "母线模型不为空") @NotNull(message = "母线模型不为空")
private Integer subvModel; private Integer subvModel;
@Excel(name = "监测点名称", width = 15) @Excel(name = "*监测点名称", width = 15)
@NotBlank(message = "监测点名称不能为空") @NotBlank(message = "监测点名称不能为空")
private String lineName; private String lineName;
@Excel(name = "监测点线路号", width = 15) @Excel(name = "*监测点线路号", width = 15)
@NotNull(message = "监测点线路号不为空") @NotNull(message = "监测点线路号不为空")
private Integer lineNum; private Integer lineNum;
@Excel(name = "监测点等级", width = 15) @Excel(name = "*监测点等级", width = 15)
private String lineGrade; private String lineGrade;
@Excel(name = "pt", width = 20) @Excel(name = "*pt(格式pt1/pt2)", width = 20)
@NotBlank(message = "pt不能为空") @NotBlank(message = "pt不能为空")
private String pt; private String pt;
@Excel(name = "ct", width = 20) @Excel(name = "*ct(格式ct1/ct2)", width = 20)
@NotBlank(message = "ct不能为空") @NotBlank(message = "ct不能为空")
private String ct; private String ct;
@Excel(name = "设备容量", width = 15) @Excel(name = "*设备容量", width = 15)
@NotNull(message = "设备容量不为空") @NotNull(message = "设备容量不为空")
private Float devCapacity; private Float devCapacity;
@Excel(name = "短路容量", width = 15) @Excel(name = "*短路容量", width = 15)
@NotNull(message = "短路容量不为空") @NotNull(message = "短路容量不为空")
private Float shortCapacity; private Float shortCapacity;
@Excel(name = "基准容量", width = 15) @Excel(name = "*基准容量", width = 15)
@NotNull(message = "基准容量不为空") @NotNull(message = "基准容量不为空")
private Float standardCapacity; private Float standardCapacity;
@Excel(name = "协议容量", width = 15) @Excel(name = "*协议容量", width = 15)
@NotNull(message = "协议容量不为空") @NotNull(message = "协议容量不为空")
private Float dealCapacity; private Float dealCapacity;
@Excel(name = "接线方式", replace = {"星型接法_0", "三角型接法_1", "开口三角型接法_2"}, width = 15) @Excel(name = "*接线方式", replace = {"星型接法_0", "三角型接法_1", "开口三角型接法_2"}, width = 15)
@NotNull(message = "接线方式不为空") @NotNull(message = "接线方式不为空")
private Integer ptType; private Integer ptType;
@Excel(name = "测量间隔", width = 15) @Excel(name = "*测量间隔", width = 15)
@NotNull(message = "测量间隔不为空") @NotNull(message = "测量间隔不为空")
private Integer timeInterval; private Integer timeInterval;
@Excel(name = "干扰源类型", width = 15) @Excel(name = "*干扰源类型", width = 15)
@NotBlank(message = "干扰源类型不为空") @NotBlank(message = "干扰源类型不为空")
private String loadType; private String loadType;
@Excel(name = "行业类型", width = 15) @Excel(name = "*行业类型", width = 15)
@NotBlank(message = "行业类型不为空") @NotBlank(message = "行业类型不为空")
private String businessType; private String businessType;
@@ -183,11 +183,11 @@ public class TerminalBaseExcel implements Serializable {
@Excel(name = "监测点对象名称", width = 15) @Excel(name = "监测点对象名称", width = 15)
private String objName; private String objName;
@Excel(name = "电网侧标志", replace = {"电网侧_0", "非电网侧_1"}, width = 15) @Excel(name = "*电网侧标志", replace = {"电网侧_0", "非电网侧_1"}, width = 15)
@NotNull(message = "电网侧标志不为空") @NotNull(message = "电网侧标志不为空")
private Integer powerFlag; private Integer powerFlag;
@Excel(name = "人为干预统计", replace = {"不参与统计_0", "参与统计_1"}, width = 15) @Excel(name = "*人为干预统计", replace = {"不参与统计_0", "参与统计_1"}, width = 15)
@NotNull(message = "统计标志不为空") @NotNull(message = "统计标志不为空")
private Integer statFlag; private Integer statFlag;

View File

@@ -20,6 +20,8 @@ public class DeviceInfo {
private String ip; private String ip;
//终端型号 //终端型号
private String devType; private String devType;
//前置类型
private String comType;
//挂载单位 //挂载单位
private String org_name; private String org_name;
//组织名称 //组织名称

View File

@@ -0,0 +1,19 @@
package com.njcn.device.pq.pojo.param;
import lombok.Data;
/**
* Description:请求装置文件系统参数
* Date: 2026/04/30 上午 10:51【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
public class AskFileSysParam {
private String devId;
private String path;
private String remotePath;
}

View File

@@ -0,0 +1,38 @@
package com.njcn.device.pq.pojo.param;
import com.njcn.web.pojo.param.BaseParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
/**
* @Author: cdf
* @CreateTime: 2026-07-06
* @Description:
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class TerminalCheckParam extends BaseParam {
private String devId;
private String objId;
private String objName;
private String city;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate thisCheckTime;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate nextCheckTime;
/**
* 检测报告
*/
private String checkUrl;
}

View File

@@ -1,10 +1,13 @@
package com.njcn.device.pq.pojo.po; package com.njcn.device.pq.pojo.po;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.bo.BaseEntity; import com.njcn.db.bo.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.util.List;
/** /**
* <p> * <p>
* *
@@ -61,6 +64,8 @@ public class Line extends BaseEntity {
private Integer state; private Integer state;
@TableField(exist = false)
private List<Line> children;
} }

View File

@@ -1,6 +1,7 @@
package com.njcn.device.pq.pojo.po; package com.njcn.device.pq.pojo.po;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
@@ -22,6 +23,7 @@ public class LineDetail{
/** /**
* 监测点序号 * 监测点序号
*/ */
@TableId
private String id; private String id;
@@ -111,7 +113,6 @@ public class LineDetail{
/** /**
* 监测点对象名称 * 监测点对象名称
*/ */
@Deprecated
private String objName; private String objName;
/** /**
@@ -171,19 +172,16 @@ public class LineDetail{
/** /**
* 监测点拥有者 * 监测点拥有者
*/ */
@Deprecated
private String owner; private String owner;
/** /**
* 拥有者职务 * 拥有者职务
*/ */
@Deprecated
private String ownerDuty; private String ownerDuty;
/** /**
* 拥有者联系方式 * 拥有者联系方式
*/ */
@Deprecated
private String ownerTel; private String ownerTel;
/** /**

View File

@@ -0,0 +1,45 @@
package com.njcn.device.pq.pojo.po;
/**
* @Author: cdf
* @CreateTime: 2026-07-07
* @Description:
*/
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 监测对象附件
*/
@Data
@TableName("SUPERVISION_USER_REPORT_FILE")
public class SupervisionUserReportFile {
/**
* 主键ID
*/
@TableId
private String id;
/**
* 检测报告
*/
private String checkUrl;
/**
* 历史检测报告
*/
private String checkHistoryUrl;
/**
* 评估报告
*/
private String assessUrl;
/**
* 其他附件
*/
private String otherUrl;
}

View File

@@ -1,34 +0,0 @@
//package com.njcn.device.pq.pojo.po;
//
//import com.baomidou.mybatisplus.annotation.TableId;
//import lombok.Data;
//import org.influxdb.annotation.Column;
//import org.influxdb.annotation.Measurement;
//
//import java.time.Instant;
//
///**
// * @version 1.0.0
// * @author: chenchao
// * @date: 2022/06/22 19:03
// */
//@Data
//@Measurement(name = "pqs_terminal_logs")
//public class TerminalLogs {
//
// @Column(name = "time")
// private Instant timeId;
//
// @Column(name = "line_id")
// private String lineId;
//
// @Column(name = "terminal_type")
// private String terminalType;
//
// @Column(name = "update_by")
// private String updateBy;
//
// @Column(name = "terminal_describe")
// private String terminalDescribe;
//
//}

View File

@@ -53,4 +53,12 @@ public class DevDetail {
@JsonFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate nextTimeCheck; private LocalDate nextTimeCheck;
@Data
public static class DevPowerFlag{
@ApiModelProperty("终端id")
private String devIndex;
@ApiModelProperty(name = "powerFlag",value = "用户性质")
private String powerFlag;
}
} }

View File

@@ -46,6 +46,9 @@ public class LineDetailDataVO {
@ApiModelProperty(name = "devName",value = "终端名称") @ApiModelProperty(name = "devName",value = "终端名称")
private String devName; private String devName;
@ApiModelProperty("装置型号")
private String devType;
@ApiModelProperty(name = "ip",value = "网络参数") @ApiModelProperty(name = "ip",value = "网络参数")
private String ip; private String ip;

View File

@@ -105,9 +105,12 @@ public class LineDetailVO implements Serializable {
@ApiModelProperty(name = "终端厂家") @ApiModelProperty(name = "终端厂家")
private String manufacturer; private String manufacturer;
@ApiModelProperty(name = "终端厂家") @ApiModelProperty(name = "监测对象ID")
private String objId; private String objId;
@ApiModelProperty(name = "监测对象名称")
private String objName;
} }
@Data @Data

View File

@@ -125,6 +125,8 @@ public class LineIntegrityDataVO implements Serializable {
private Integer algoDescribe; private Integer algoDescribe;
@ApiModelProperty(name = "devType",value = "终端型号")
private String devType;
@ApiModelProperty(name = "loadType",value = "干扰源类型") @ApiModelProperty(name = "loadType",value = "干扰源类型")
private String loadType; private String loadType;

View File

@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
/** /**
* @version 1.0.0 * @version 1.0.0
@@ -26,4 +27,7 @@ public class LoadTypeVO implements Serializable {
*/ */
@ApiModelProperty("干扰源暂降次数") @ApiModelProperty("干扰源暂降次数")
private Integer count; private Integer count;
private List<String> loadTypeList;
} }

View File

@@ -18,7 +18,7 @@ public class RunManageVO {
private Integer runNo; private Integer runNo;
@ApiModelProperty(name = "id",value = "监测点序号") @ApiModelProperty(name = "id",value = "监测点序号")
private Integer id; private String id;
@ApiModelProperty(name = "lineName",value = "监测点名称") @ApiModelProperty(name = "lineName",value = "监测点名称")
private String lineName; private String lineName;
@@ -44,6 +44,9 @@ public class RunManageVO {
@ApiModelProperty(name = "ip",value = "网络参数") @ApiModelProperty(name = "ip",value = "网络参数")
private String ip; private String ip;
@ApiModelProperty(name = "powerFlag",value = "用户性质")
private String powerFlag;
@ApiModelProperty(name = "runFlag",value = "终端运行状态") @ApiModelProperty(name = "runFlag",value = "终端运行状态")
private String runFlag; private String runFlag;

View File

@@ -36,6 +36,9 @@ public class RunTimeVO implements Serializable {
@ApiModelProperty(name = "devName",value = "终端名称") @ApiModelProperty(name = "devName",value = "终端名称")
private String devName; private String devName;
@ApiModelProperty(name = "powerFlag",value = "用户性质")
private String powerFlag;
@ApiModelProperty(name = "ip",value = "网络参数") @ApiModelProperty(name = "ip",value = "网络参数")
private String ip; private String ip;

View File

@@ -0,0 +1,51 @@
package com.njcn.device.pq.pojo.vo;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* @Author: cdf
* @CreateTime: 2026-07-06
* @Description: 终端检测
*/
@Data
public class TerminalCheckVO {
private String devId;
private String areaName;
private String bdName;
private String devName;
private String objId;
private String objName;
private LocalDate thisCheckTime;
private LocalDate nextCheckTime;
private LocalDate loginDate;
/**
* 0.未逾期
* 1.逾期
*/
private Integer checkStatus;
/**
* 逾期时间
*/
private Integer overdueDay;
/**
* 检测报告
*/
private String checkUrl;
}

View File

@@ -48,4 +48,6 @@ public class TerminalMaintainVO implements Serializable {
private Integer strategyFlag; private Integer strategyFlag;
@ApiModelProperty(name = "子级") @ApiModelProperty(name = "子级")
List<TerminalMaintainVO> children; List<TerminalMaintainVO> children;
private String objName;
} }

View File

@@ -80,6 +80,7 @@ public class DeviceOnlineRate {
private String comFlag; private String comFlag;
@ApiModelProperty("最新数据时间") @ApiModelProperty("最新数据时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime timeID; private LocalDateTime timeID;
@ApiModelProperty("在线率") @ApiModelProperty("在线率")

View File

@@ -49,6 +49,6 @@ public class LineDataExcel implements Serializable {
private BigDecimal integrity; private BigDecimal integrity;
@ExcelProperty(value = "国网ID") @ExcelProperty(value = "国网ID")
private BigDecimal monitorId; private String monitorId;
} }

View File

@@ -11,6 +11,7 @@ import com.njcn.device.pq.pojo.po.RStatIntegrityD;
import com.njcn.device.pq.pojo.po.RStatOnlinerateD; import com.njcn.device.pq.pojo.po.RStatOnlinerateD;
import com.njcn.device.pq.pojo.vo.GridDiagramProVO; import com.njcn.device.pq.pojo.vo.GridDiagramProVO;
import com.njcn.device.pq.pojo.vo.GridDiagramVO; import com.njcn.device.pq.pojo.vo.GridDiagramVO;
import com.njcn.device.pq.pojo.vo.LoadTypeVO;
import com.njcn.device.pq.service.GridDiagramService; import com.njcn.device.pq.service.GridDiagramService;
import com.njcn.web.controller.BaseController; import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@@ -135,4 +136,13 @@ public class GridDiagramController extends BaseController {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, gridDiagramOnLineRateD, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, gridDiagramOnLineRateD, methodDescribe);
} }
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/loadTypeVOList")
@ApiOperation("干扰源类型统计")
public HttpResult<List<LoadTypeVO>> loadTypeVOList(@RequestBody GridDiagramParam param){
String methodDescribe = getMethodDescribe("loadTypeVOList");
List<LoadTypeVO> loadTypeVOList = gridDiagramService.loadTypeVOList(param);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, loadTypeVOList, methodDescribe);
}
} }

View File

@@ -90,7 +90,7 @@ public class LineIntegrityDataController extends BaseController {
String methodDescribe = getMethodDescribe("getIntegrityByLineIds"); String methodDescribe = getMethodDescribe("getIntegrityByLineIds");
if(CollUtil.isNotEmpty(lineIds)){ if(CollUtil.isNotEmpty(lineIds)){
QueryWrapper<RStatIntegrityD> queryWrapper = new QueryWrapper<>(); QueryWrapper<RStatIntegrityD> queryWrapper = new QueryWrapper<>();
queryWrapper.select("sum(real_time) as realTime,sum(due_time) as dueTime,sum(real_time)/sum(due_time) as integrityData","line_index").in("line_index",lineIds).between("time_id",startTime,endTime).groupBy("line_index"); queryWrapper.select("sum(real_time) as realTime,sum(due_time) as dueTime,avg(real_time*1.0/due_time) as integrityData","line_index").in("line_index",lineIds).between("time_id",startTime,endTime).groupBy("line_index");
List<RStatIntegrityD> rStatIntegrityDList = irStatIntegrityDService.list(queryWrapper); List<RStatIntegrityD> rStatIntegrityDList = irStatIntegrityDService.list(queryWrapper);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, rStatIntegrityDList, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, rStatIntegrityDList, methodDescribe);
} }
@@ -154,7 +154,6 @@ public class LineIntegrityDataController extends BaseController {
@ApiOperation("监测点数据完整性(冀北)") @ApiOperation("监测点数据完整性(冀北)")
@ApiImplicitParam(name = "param", value = "参数实体", required = true) @ApiImplicitParam(name = "param", value = "参数实体", required = true)
public HttpResult<DeviceOnlineRate> getData(@RequestBody DeviceInfoParam.BusinessParam param) { public HttpResult<DeviceOnlineRate> getData(@RequestBody DeviceInfoParam.BusinessParam param) {
param.setLineOrDevice(0);
String methodDescribe = getMethodDescribe("getData"); String methodDescribe = getMethodDescribe("getData");
DeviceOnlineRate rate = irStatIntegrityDService.getData(param); DeviceOnlineRate rate = irStatIntegrityDService.getData(param);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, rate, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, rate, methodDescribe);

View File

@@ -6,14 +6,14 @@ package com.njcn.device.pq.controller;
* @Description: 异常告警数据指标范围 * @Description: 异常告警数据指标范围
*/ */
import com.njcn.algorithm.pojo.dto.PqReasonableRangeDto;
import com.njcn.algorithm.pojo.param.DataCleanParam;
import com.njcn.common.pojo.annotation.OperateInfo; import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.constant.OperateType; import com.njcn.common.pojo.constant.OperateType;
import com.njcn.common.pojo.enums.common.LogEnum; import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum; import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult; import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil; import com.njcn.common.utils.HttpResultUtil;
import com.njcn.dataProcess.param.DataCleanParam;
import com.njcn.dataProcess.pojo.dto.PqReasonableRangeDto;
import com.njcn.device.pq.service.ReasonableRangeService; import com.njcn.device.pq.service.ReasonableRangeService;
import com.njcn.web.controller.BaseController; import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;

View File

@@ -8,7 +8,9 @@ import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult; import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil; import com.njcn.common.utils.HttpResultUtil;
import com.njcn.device.pq.pojo.param.AlarmParam; import com.njcn.device.pq.pojo.param.AlarmParam;
import com.njcn.device.pq.pojo.param.TerminalCheckParam;
import com.njcn.device.pq.pojo.vo.TerminalAlarmVO; import com.njcn.device.pq.pojo.vo.TerminalAlarmVO;
import com.njcn.device.pq.pojo.vo.TerminalCheckVO;
import com.njcn.device.pq.service.TerminalAlarmService; import com.njcn.device.pq.service.TerminalAlarmService;
import com.njcn.web.controller.BaseController; import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@@ -87,4 +89,19 @@ public class TerminalAlarmController extends BaseController {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
} }
/**
* 终端周期检测告警
* @author cdf
* @date 2022/5/23
*/
@PostMapping("/terminalCheckPage")
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@ApiOperation("终端检测告警")
@ApiImplicitParam(name = "terminalCheckParam", value = "告警类型")
public HttpResult<Page<TerminalCheckVO>> terminalCheckPage(@RequestBody @Validated TerminalCheckParam terminalCheckParam){
String methodDescribe = getMethodDescribe("terminalCheckPage");
Page<TerminalCheckVO> res = terminalAlarmService.terminalCheckPage(terminalCheckParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, res, methodDescribe);
}
} }

View File

@@ -0,0 +1,181 @@
package com.njcn.device.pq.controller.file;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.IdUtil;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.device.device.service.DeviceProcessService;
import com.njcn.device.device.service.IDeviceService;
import com.njcn.device.pq.pojo.param.AskFileSysParam;
import com.njcn.device.pq.pojo.po.Device;
import com.njcn.device.pq.pojo.po.DeviceProcess;
import com.njcn.message.api.ProduceFeignClient;
import com.njcn.message.message.AskFileSysMessage;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;
/**
* Description:
* Date: 2026/04/29 上午 11:41【需求编号】
*
* @author clam
* @version V1.0.0
*/
@RestController
@RequestMapping("/dir")
@RequiredArgsConstructor
@Slf4j
@Api(tags = "装置文件系统")
public class DirectoryController extends BaseController {
private final ProduceFeignClient produceFeignClient;
private final PendingRequestManager pendingRequestManager;
private final IDeviceService iDeviceService;
private final DeviceProcessService deviceProcessService;
@PostMapping("/list")
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@ApiOperation("获取装置文件目录")
public DeferredResult<Object> listDirectory(@RequestBody AskFileSysParam askFileSysParam) {
String methodDescribe = getMethodDescribe("listDirectory");
long timeoutMs = 15000L; // 15 秒超时
// 构造指令 body
Device device = iDeviceService.getById(askFileSysParam.getDevId());
DeviceProcess deviceProcess = deviceProcessService.getById(askFileSysParam.getDevId());
// 发送 MQ 指令,获取 msgId
AskFileSysMessage askFileSysMessage = new AskFileSysMessage();
askFileSysMessage.setGuid(IdUtil.simpleUUID());
askFileSysMessage.setNodeId(device.getNodeId());
askFileSysMessage.setProcessNo(deviceProcess.getProcessNo());
askFileSysMessage.setDevId(askFileSysParam.getDevId());
askFileSysMessage.setType(0);
askFileSysMessage.setPath(askFileSysParam.getPath());
produceFeignClient.askFileSys(askFileSysMessage);
// 创建挂起请求
DeferredResult<Object> deferredResult = pendingRequestManager.createPendingRequest(askFileSysMessage.getGuid(), timeoutMs);
// 可额外在 Redis 中记录初始状态(可选)
// 返回 DeferredResultSpring 将挂起此请求
return deferredResult;
}
@PostMapping("/downLoadFile")
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@ApiOperation("获取装置文件文件")
public DeferredResult<Object> downLoadFile(@RequestBody AskFileSysParam askFileSysParam) {
String methodDescribe = getMethodDescribe("downLoadFile");
long timeoutMs = 15000L; // 15 秒超时
// 构造指令 body
Device device = iDeviceService.getById(askFileSysParam.getDevId());
DeviceProcess deviceProcess = deviceProcessService.getById(askFileSysParam.getDevId());
// 发送 MQ 指令,获取 msgId
AskFileSysMessage askFileSysMessage = new AskFileSysMessage();
askFileSysMessage.setGuid(IdUtil.simpleUUID());
askFileSysMessage.setNodeId(device.getNodeId());
askFileSysMessage.setProcessNo(deviceProcess.getProcessNo());
askFileSysMessage.setDevId(askFileSysParam.getDevId());
askFileSysMessage.setType(1);
askFileSysMessage.setPath(askFileSysParam.getPath());
produceFeignClient.askFileSys(askFileSysMessage);
// 创建挂起请求
DeferredResult<Object> deferredResult = pendingRequestManager.createPendingRequest(askFileSysMessage.getGuid(), timeoutMs);
// 可额外在 Redis 中记录初始状态(可选)
// 返回 DeferredResultSpring 将挂起此请求
return deferredResult;
}
@PostMapping("/upLoadFile")
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@ApiOperation("上传装置文件文件")
public DeferredResult<Object> upLoadFile(@RequestBody AskFileSysParam askFileSysParam) {
String methodDescribe = getMethodDescribe("upLoadFile");
long timeoutMs = 15000L; // 15 秒超时
// 构造指令 body
Device device = iDeviceService.getById(askFileSysParam.getDevId());
DeviceProcess deviceProcess = deviceProcessService.getById(askFileSysParam.getDevId());
// 发送 MQ 指令,获取 msgId
AskFileSysMessage askFileSysMessage = new AskFileSysMessage();
askFileSysMessage.setGuid(IdUtil.simpleUUID());
askFileSysMessage.setNodeId(device.getNodeId());
askFileSysMessage.setProcessNo(deviceProcess.getProcessNo());
askFileSysMessage.setDevId(askFileSysParam.getDevId());
askFileSysMessage.setType(2);
askFileSysMessage.setPath(askFileSysParam.getPath());
askFileSysMessage.setRemotePath(askFileSysParam.getRemotePath());
produceFeignClient.askFileSys(askFileSysMessage);
// 创建挂起请求
DeferredResult<Object> deferredResult = pendingRequestManager.createPendingRequest(askFileSysMessage.getGuid(), timeoutMs);
// 可额外在 Redis 中记录初始状态(可选)
// 返回 DeferredResultSpring 将挂起此请求
return deferredResult;
}
@PostMapping("/delete")
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@ApiOperation("装置目录,文件删除")
public DeferredResult<Object> delete(@RequestBody AskFileSysParam askFileSysParam) {
String methodDescribe = getMethodDescribe("delete");
long timeoutMs = 15000L; // 15 秒超时
// 构造指令 body
Device device = iDeviceService.getById(askFileSysParam.getDevId());
DeviceProcess deviceProcess = deviceProcessService.getById(askFileSysParam.getDevId());
// 发送 MQ 指令,获取 msgId
AskFileSysMessage askFileSysMessage = new AskFileSysMessage();
askFileSysMessage.setGuid(IdUtil.simpleUUID());
askFileSysMessage.setNodeId(device.getNodeId());
askFileSysMessage.setProcessNo(deviceProcess.getProcessNo());
askFileSysMessage.setDevId(askFileSysParam.getDevId());
askFileSysMessage.setType(3);
askFileSysMessage.setPath(askFileSysParam.getPath());
askFileSysMessage.setRemotePath(askFileSysParam.getRemotePath());
produceFeignClient.askFileSys(askFileSysMessage);
// 创建挂起请求
DeferredResult<Object> deferredResult = pendingRequestManager.createPendingRequest(askFileSysMessage.getGuid(), timeoutMs);
// 可额外在 Redis 中记录初始状态(可选)
// 返回 DeferredResultSpring 将挂起此请求
return deferredResult;
}
@PostMapping("/restart")
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@ApiOperation("装置重启")
public DeferredResult<Object> restart(@RequestBody AskFileSysParam askFileSysParam) {
String methodDescribe = getMethodDescribe("restart");
long timeoutMs = 15000L; // 15 秒超时
// 构造指令 body
Device device = iDeviceService.getById(askFileSysParam.getDevId());
DeviceProcess deviceProcess = deviceProcessService.getById(askFileSysParam.getDevId());
// 发送 MQ 指令,获取 msgId
AskFileSysMessage askFileSysMessage = new AskFileSysMessage();
askFileSysMessage.setGuid(IdUtil.simpleUUID());
askFileSysMessage.setNodeId(device.getNodeId());
askFileSysMessage.setProcessNo(deviceProcess.getProcessNo());
askFileSysMessage.setDevId(askFileSysParam.getDevId());
askFileSysMessage.setPath("reboot");
askFileSysMessage.setType(4);
produceFeignClient.askFileSys(askFileSysMessage);
// 创建挂起请求
DeferredResult<Object> deferredResult = pendingRequestManager.createPendingRequest(askFileSysMessage.getGuid(), timeoutMs);
// 可额外在 Redis 中记录初始状态(可选)
// 返回 DeferredResultSpring 将挂起此请求
return deferredResult;
}
}

View File

@@ -0,0 +1,61 @@
package com.njcn.device.pq.controller.file;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.HttpResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.async.DeferredResult;
import java.util.concurrent.ConcurrentHashMap;
@Component
@Slf4j
public class PendingRequestManager {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 本地映射msgId -> DeferredResult主要用于超时清理和主动完成
private final ConcurrentHashMap<String, DeferredResult<Object>> deferredResultMap = new ConcurrentHashMap<>();
// 创建挂起请求
public DeferredResult<Object> createPendingRequest(String msgId, long timeoutMs) {
DeferredResult<Object> deferredResult = new DeferredResult<>(timeoutMs);
// 超时回调
deferredResult.onTimeout(() -> {
// 清理 Redis 中的等待记录
redisTemplate.delete("pending:" + msgId);
deferredResultMap.remove(msgId);
deferredResult.setErrorResult(new BusinessException("前置超时...."));
});
// 完成回调(正常或异常后移出本地映射)
deferredResult.onCompletion(() -> deferredResultMap.remove(msgId));
deferredResultMap.put(msgId, deferredResult);
return deferredResult;
}
// 收到 Redis 通知后,根据 msgId 完成请求
public void completeRequest(String msgId) {
if (deferredResultMap.containsKey(msgId)) {
DeferredResult<Object> deferredResult = deferredResultMap.get(msgId);
// 从 Redis 中获取结果内容
String key = "pending:" + msgId;
Object result = redisTemplate.opsForValue().get(key);
if (result != null) {
deferredResult.setResult( HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result,""));
} else {
log.info("Receive notification for unknown msgId: " + msgId);
deferredResult.setErrorResult(new BusinessException("前置未返回结果"));
}
// 清理 Redis 中的记录(可选,利用过期时间自动删除也可)
redisTemplate.delete(key);
} else {
// 可能请求已超时被移除了,仅记录日志即可
log.info("Receive notification for unknown msgId: " + msgId);
}
}
}

View File

@@ -0,0 +1,20 @@
package com.njcn.device.pq.controller.file;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
@Component
public class RedisMessageSubscriber implements MessageListener {
@Autowired
private PendingRequestManager pendingRequestManager;
@Override
public void onMessage(Message message, byte[] pattern) {
String msgId = new String(message.getBody(), StandardCharsets.UTF_8);
pendingRequestManager.completeRequest(msgId);
}
}

View File

@@ -0,0 +1,44 @@
package com.njcn.device.pq.controller.file;
import com.njcn.redis.config.RedisConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.stereotype.Component;
import org.springframework.data.redis.connection.MessageListener;
import java.nio.charset.StandardCharsets;
/**
* Description:
* Date: 2026/04/29 下午 3:37【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Configuration
@Import(RedisConfig.class) // 引入公共配置
public class RedisSubscriptionConfig {
@Bean
public RedisMessageListenerContainer redisContainer(
RedisConnectionFactory connectionFactory,
MessageListenerAdapter resultListenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(resultListenerAdapter, new ChannelTopic("result_ready_channel"));
return container;
}
@Bean
public MessageListenerAdapter resultListenerAdapter(RedisMessageSubscriber subscriber) {
return new MessageListenerAdapter(subscriber, "onMessage");
}
}

View File

@@ -14,6 +14,7 @@ import com.njcn.message.constant.RedisKeyPrefix;
import com.njcn.redis.utils.RedisUtil; import com.njcn.redis.utils.RedisUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -35,6 +36,7 @@ import java.util.stream.Collectors;
@Component @Component
@EnableScheduling @EnableScheduling
@RequiredArgsConstructor @RequiredArgsConstructor
@ConditionalOnProperty(name = "business.task-enabled", havingValue = "true", matchIfMissing = true)
public class DeviceComflagTasks { public class DeviceComflagTasks {
private final NodeMapper nodeMapper; private final NodeMapper nodeMapper;
private final IDeviceService iDeviceService; private final IDeviceService iDeviceService;

View File

@@ -3,8 +3,10 @@ package com.njcn.device.pq.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.device.pq.pojo.param.TerminalCheckParam;
import com.njcn.device.pq.pojo.po.Alarm; import com.njcn.device.pq.pojo.po.Alarm;
import com.njcn.device.pq.pojo.vo.TerminalAlarmVO; import com.njcn.device.pq.pojo.vo.TerminalAlarmVO;
import com.njcn.device.pq.pojo.vo.TerminalCheckVO;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@@ -41,4 +43,8 @@ public interface AlarmMapper extends BaseMapper<Alarm> {
* @date 2022/5/23 * @date 2022/5/23
*/ */
boolean updateAlarmInfo(@Param("type")String type,@Param("devLineId")String devLineId,@Param("processTime")LocalDateTime processTime,@Param("userIndex")String userIndex); boolean updateAlarmInfo(@Param("type")String type,@Param("devLineId")String devLineId,@Param("processTime")LocalDateTime processTime,@Param("userIndex")String userIndex);
Page<TerminalCheckVO> terminalCheckPage(Page<TerminalCheckVO> page, @Param("terminalCheckParam")TerminalCheckParam terminalCheckParam);
} }

View File

@@ -1,7 +1,7 @@
package com.njcn.device.pq.mapper; package com.njcn.device.pq.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.dataProcess.pojo.po.PqReasonableRange; import com.njcn.algorithm.pojo.po.PqReasonableRange;
/** /**
* <p> * <p>

View File

@@ -158,5 +158,51 @@ ORDER BY
</update> </update>
<select id="terminalCheckPage" resultType="TerminalCheckVO">
SELECT
dev.id AS devId,
dev.NAME AS devName,
users.city AS areaName,
bd.name AS bdName,
detail.obj_id AS objId,
users.project_name AS objName,
dev_detail.this_time_check AS thisCheckTime,
dev_detail.next_time_check AS nextCheckTime,
dev_detail.login_time AS loginDate,
files.CHECK_URL as checkUrl,
DATEDIFF(
day,
COALESCE(CAST(dev_detail.next_time_check AS DATE), CURRENT_DATE + INTERVAL '365' DAY),
CURRENT_DATE
) AS overdueDay,
CASE
WHEN DATEDIFF(
day,
COALESCE(CAST(dev_detail.next_time_check AS DATE), CURRENT_DATE + INTERVAL '365' DAY),
CURRENT_DATE
) > 0 THEN 1
ELSE 0
END AS checkStatus
FROM
pq_line line
INNER JOIN pq_line_detail detail ON line.id = detail.id
INNER JOIN pq_line bus ON line.pid = bus.id
INNER JOIN pq_line dev ON bus.pid = dev.id
INNER JOIN pq_device dev_detail ON dev.id = dev_detail.id
INNER JOIN pq_line bd ON dev.pid = bd.id
LEFT JOIN SUPERVISION_USER_REPORT users ON users.id = detail.obj_id
LEFT JOIN SUPERVISION_USER_REPORT_FILE files on users.id = files.id
<where>
<if test="terminalCheckParam.city!=null and terminalCheckParam.city !=''">
users.city = #{terminalCheckParam.city}
</if>
<if test="terminalCheckParam.searchValue!=null and terminalCheckParam.searchValue !=''">
and users.project_name like concat('%',#{terminalCheckParam.searchValue},'%')
</if>
</where>
order by checkStatus desc,loginDate desc
</select>
</mapper> </mapper>

View File

@@ -84,6 +84,7 @@
pldsdd.id AS lineGrade, pldsdd.id AS lineGrade,
pldsdd.Algo_Describe AS algoDescribe, pldsdd.Algo_Describe AS algoDescribe,
pld.Load_Type AS loadType, pld.Load_Type AS loadType,
pd.Dev_Type AS devType,
pld.obj_id as objId pld.obj_id as objId
FROM FROM
pq_line AS line pq_line AS line

View File

@@ -7,6 +7,7 @@ import com.njcn.device.pq.pojo.po.RStatIntegrityD;
import com.njcn.device.pq.pojo.po.RStatOnlinerateD; import com.njcn.device.pq.pojo.po.RStatOnlinerateD;
import com.njcn.device.pq.pojo.vo.GridDiagramProVO; import com.njcn.device.pq.pojo.vo.GridDiagramProVO;
import com.njcn.device.pq.pojo.vo.GridDiagramVO; import com.njcn.device.pq.pojo.vo.GridDiagramVO;
import com.njcn.device.pq.pojo.vo.LoadTypeVO;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -90,4 +91,12 @@ public interface GridDiagramService {
* @Date: 2024/5/4 18:35 * @Date: 2024/5/4 18:35
*/ */
List<RStatOnlinerateD> getGridDiagramOnLineRateD(StatisticsBizBaseParam param); List<RStatOnlinerateD> getGridDiagramOnLineRateD(StatisticsBizBaseParam param);
/**
* @Description: 根据干扰源进行分组
* @param param
* @return
*/
List<LoadTypeVO> loadTypeVOList(GridDiagramParam param);
} }

View File

@@ -1,9 +1,10 @@
package com.njcn.device.pq.service; package com.njcn.device.pq.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.dataProcess.param.DataCleanParam; import com.njcn.algorithm.pojo.dto.PqReasonableRangeDto;
import com.njcn.dataProcess.pojo.dto.PqReasonableRangeDto; import com.njcn.algorithm.pojo.param.DataCleanParam;
import com.njcn.dataProcess.pojo.po.PqReasonableRange; import com.njcn.algorithm.pojo.po.PqReasonableRange;
import java.util.List; import java.util.List;

View File

@@ -2,7 +2,9 @@ package com.njcn.device.pq.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.device.pq.pojo.param.AlarmParam; import com.njcn.device.pq.pojo.param.AlarmParam;
import com.njcn.device.pq.pojo.param.TerminalCheckParam;
import com.njcn.device.pq.pojo.vo.TerminalAlarmVO; import com.njcn.device.pq.pojo.vo.TerminalAlarmVO;
import com.njcn.device.pq.pojo.vo.TerminalCheckVO;
import java.util.List; import java.util.List;
@@ -35,4 +37,7 @@ public interface TerminalAlarmService {
* @date 2022/5/23 * @date 2022/5/23
*/ */
boolean updateAlarmInfo(String type,String devLineId); boolean updateAlarmInfo(String type,String devLineId);
Page<TerminalCheckVO> terminalCheckPage(TerminalCheckParam terminalCheckParam);
} }

View File

@@ -9,20 +9,17 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray; import cn.hutool.json.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.algorithm.pojo.api.PqReasonableRangeFeignClient;
import com.njcn.algorithm.pojo.dto.PqReasonableRangeDto;
import com.njcn.algorithm.pojo.param.DataCleanParam;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.dataProcess.api.DataLimitRateDetailFeignClient; import com.njcn.dataProcess.api.DataLimitRateDetailFeignClient;
import com.njcn.dataProcess.api.DataLimitRateFeignClient; import com.njcn.dataProcess.api.DataLimitRateFeignClient;
import com.njcn.dataProcess.api.DataLimitTargetFeignClient; import com.njcn.dataProcess.api.DataLimitTargetFeignClient;
import com.njcn.dataProcess.api.PqReasonableRangeFeignClient;
import com.njcn.dataProcess.enums.DataCleanEnum; import com.njcn.dataProcess.enums.DataCleanEnum;
import com.njcn.dataProcess.param.DataCleanParam;
import com.njcn.dataProcess.param.LineCountEvaluateParam; import com.njcn.dataProcess.param.LineCountEvaluateParam;
import com.njcn.dataProcess.pojo.dto.DataLimitRateDetailDto; import com.njcn.dataProcess.pojo.dto.DataLimitRateDetailDto;
import com.njcn.dataProcess.pojo.dto.DataLimitRateDto;
import com.njcn.dataProcess.pojo.dto.DataLimitTargetDto; import com.njcn.dataProcess.pojo.dto.DataLimitTargetDto;
import com.njcn.dataProcess.pojo.dto.PqReasonableRangeDto;
import com.njcn.device.biz.enums.DeviceResponseEnum;
import com.njcn.device.biz.pojo.dto.LineDevGetDTO;
import com.njcn.device.biz.pojo.po.Overlimit; import com.njcn.device.biz.pojo.po.Overlimit;
import com.njcn.device.line.mapper.LineMapper; import com.njcn.device.line.mapper.LineMapper;
import com.njcn.device.line.service.DeptLineService; import com.njcn.device.line.service.DeptLineService;

View File

@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.njcn.common.pojo.enums.common.DataStateEnum; import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.param.StatisticsBizBaseParam; import com.njcn.common.pojo.param.StatisticsBizBaseParam;
import com.njcn.device.biz.enums.RunFlagEnum;
import com.njcn.device.biz.pojo.dto.DeptGetChildrenMoreDTO; import com.njcn.device.biz.pojo.dto.DeptGetChildrenMoreDTO;
import com.njcn.device.biz.pojo.dto.LineDevGetDTO; import com.njcn.device.biz.pojo.dto.LineDevGetDTO;
import com.njcn.device.biz.pojo.param.DeptGetLineParam; import com.njcn.device.biz.pojo.param.DeptGetLineParam;
@@ -24,9 +25,11 @@ import com.njcn.device.pq.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pq.pojo.param.GridDiagramParam; import com.njcn.device.pq.pojo.param.GridDiagramParam;
import com.njcn.device.pq.pojo.param.LineBaseQueryParam; import com.njcn.device.pq.pojo.param.LineBaseQueryParam;
import com.njcn.device.pq.pojo.param.OnlineRateParam; import com.njcn.device.pq.pojo.param.OnlineRateParam;
import com.njcn.device.pq.pojo.param.dataClean.MonitorBaseParam;
import com.njcn.device.pq.pojo.po.*; import com.njcn.device.pq.pojo.po.*;
import com.njcn.device.pq.pojo.vo.GridDiagramProVO; import com.njcn.device.pq.pojo.vo.GridDiagramProVO;
import com.njcn.device.pq.pojo.vo.GridDiagramVO; import com.njcn.device.pq.pojo.vo.GridDiagramVO;
import com.njcn.device.pq.pojo.vo.LoadTypeVO;
import com.njcn.device.pq.pojo.vo.RStatOnlineRateVO; import com.njcn.device.pq.pojo.vo.RStatOnlineRateVO;
import com.njcn.device.pq.service.*; import com.njcn.device.pq.service.*;
import com.njcn.device.rstatintegrity.mapper.RStatIntegrityDMapper; import com.njcn.device.rstatintegrity.mapper.RStatIntegrityDMapper;
@@ -45,6 +48,7 @@ import java.util.stream.Stream;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -569,6 +573,27 @@ public class GridDiagramServiceImpl implements GridDiagramService {
); );
} }
@Override
public List<LoadTypeVO> loadTypeVOList(@NotNull GridDiagramParam param) {
List<LoadTypeVO> returnList = new ArrayList<>();
MonitorBaseParam monitorBaseParam = new MonitorBaseParam();
monitorBaseParam.setDeptId(param.getOrgId());
monitorBaseParam.setLineRunFlag(RunFlagEnum.RUNNING.getStatus());
List<String> list = commTerminalService.getRunMonitorByDept(monitorBaseParam);
if(CollUtil.isNotEmpty(list)) {
List<LineDetail> lineDetailList =lineDetailMapper.selectList(new LambdaQueryWrapper<LineDetail>().select(LineDetail::getLoadType, LineDetail::getId).in(LineDetail::getId, list));
Map<String,List<String>> map = lineDetailList.stream().collect(Collectors.groupingBy(LineDetail::getLoadType,Collectors.mapping(LineDetail::getId, Collectors.toList())));
map.forEach((k,v)->{
LoadTypeVO loadTypeVO = new LoadTypeVO();
loadTypeVO.setName(k);
loadTypeVO.setCount(v.size());
loadTypeVO.setLoadTypeList(v);
returnList.add(loadTypeVO);
});
}
return returnList;
}
private void getDevStatisticsData(List<GridDiagramVO.StatisticsData> statisticsData, List<GridDiagramVO.StatisticsData> gwStatisticsData, List<LineDevGetDTO> lineBaseList, List<String> voltageIds) { private void getDevStatisticsData(List<GridDiagramVO.StatisticsData> statisticsData, List<GridDiagramVO.StatisticsData> gwStatisticsData, List<LineDevGetDTO> lineBaseList, List<String> voltageIds) {
GridDiagramVO.StatisticsData data; GridDiagramVO.StatisticsData data;

View File

@@ -19,12 +19,12 @@ import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.algorithm.pojo.api.PqReasonableRangeFeignClient;
import com.njcn.algorithm.pojo.dto.PqReasonableRangeDto;
import com.njcn.algorithm.pojo.param.DataCleanParam;
import com.njcn.common.pojo.dto.SimpleDTO; import com.njcn.common.pojo.dto.SimpleDTO;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.dataProcess.api.PqReasonableRangeFeignClient;
import com.njcn.dataProcess.enums.DataCleanEnum; import com.njcn.dataProcess.enums.DataCleanEnum;
import com.njcn.dataProcess.param.DataCleanParam;
import com.njcn.dataProcess.pojo.dto.PqReasonableRangeDto;
import com.njcn.device.common.mapper.onlinerate.OnLineRateMapper; import com.njcn.device.common.mapper.onlinerate.OnLineRateMapper;
import com.njcn.device.common.service.GeneralDeviceService; import com.njcn.device.common.service.GeneralDeviceService;
import com.njcn.device.line.mapper.LineMapper; import com.njcn.device.line.mapper.LineMapper;
@@ -487,7 +487,7 @@ public class PqDataVerifyBakServiceImpl extends ServiceImpl<PqDataVerifyBakMappe
lineDataExcel.setOnlineRate(onLineRate(onlineRateByDev, Arrays.asList(dto.getDeviceId()))); lineDataExcel.setOnlineRate(onLineRate(onlineRateByDev, Arrays.asList(dto.getDeviceId())));
lineDataExcel.setIntegrity(integrity(integrityList, Arrays.asList(dto.getLineId()))); lineDataExcel.setIntegrity(integrity(integrityList, Arrays.asList(dto.getLineId())));
if (num == 1) { if (num == 1) {
lineDataExcel.setMonitorId(new BigDecimal(dto.getMonitorId())); lineDataExcel.setMonitorId(dto.getMonitorId());
} }
lineDataExcels1.add(lineDataExcel); lineDataExcels1.add(lineDataExcel);
} }

View File

@@ -2,12 +2,15 @@ package com.njcn.device.pq.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl; import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.device.biz.commApi.CommLineClient;
import com.njcn.device.biz.pojo.dto.LineALLInfoDTO;
import com.njcn.device.common.service.GeneralDeviceService; import com.njcn.device.common.service.GeneralDeviceService;
import com.njcn.device.line.mapper.LineDetailMapper; import com.njcn.device.line.mapper.LineDetailMapper;
import com.njcn.device.line.mapper.LineMapper; import com.njcn.device.line.mapper.LineMapper;
@@ -65,7 +68,6 @@ public class RStatIntegrityDServiceImpl extends MppServiceImpl<RStatIntegrityDMa
private final LineDetailMapper lineDetailMapper; private final LineDetailMapper lineDetailMapper;
private final GeneralDeviceService deviceService; private final GeneralDeviceService deviceService;
private final LineService lineService; private final LineService lineService;
private final UserLedgerService userLedgerService;
@Override @Override
public Float getTotalIntegrityByLineIds(LineBaseQueryParam param) { public Float getTotalIntegrityByLineIds(LineBaseQueryParam param) {
@@ -154,32 +156,29 @@ public class RStatIntegrityDServiceImpl extends MppServiceImpl<RStatIntegrityDMa
.stream() .stream()
.distinct() .distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
rate.setTotalNum(lineIds.size());
//获取所有监测点的数据完整性 //获取所有监测点的数据完整性
List<RStatIntegrityVO> lineIntegrityRateInfo = rStatIntegrityDMapper.getLineIntegrityRateInfo(lineIds, param.getSearchBeginTime(), param.getSearchEndTime()); List<RStatIntegrityVO> lineIntegrityRateInfo = rStatIntegrityDMapper.getLineIntegrityRateInfo(lineIds, param.getSearchBeginTime(), param.getSearchEndTime());
//获取所有监测点信息信息 //获取所有监测点信息信息
List<LineDetailVO.Detail> LineInfoByIds = lineService.getLineDetailByIds(lineIds); List<LineDetailVO.Detail> LineInfoByIds = lineService.getLineDetailByIds(lineIds);
rate.setTotalNum(lineIds.size());
rate.setBelowNum(CollUtil.isNotEmpty(lineIntegrityRateInfo) ? calculateIntegrityRate(lineIntegrityRateInfo, 90, lineIds.size()) : lineIds.size()); rate.setBelowNum(CollUtil.isNotEmpty(lineIntegrityRateInfo) ? calculateIntegrityRate(lineIntegrityRateInfo, 90, lineIds.size()) : lineIds.size());
rate.setTotalOnlineRate(calculateIntegrityRate(lineIntegrityRateInfo, lineIds).doubleValue()>100.0?BigDecimal.valueOf(100.0) : calculateIntegrityRate(lineIntegrityRateInfo, lineIds)); rate.setTotalOnlineRate(calculateIntegrityRate(lineIntegrityRateInfo, lineIds).doubleValue() > 100.0 ? BigDecimal.valueOf(100.0) : calculateIntegrityRate(lineIntegrityRateInfo, lineIds));
List<DeviceOnlineRate.CitDetail> citDetailList = new ArrayList<>(); List<DeviceOnlineRate.CitDetail> citDetailList = new ArrayList<>();
DeviceOnlineRate.CitDetail citDetail; DeviceOnlineRate.CitDetail citDetail;
DeviceOnlineRate.LineDetail detail; DeviceOnlineRate.LineDetail detail;
//用户侧监测点 监测对象
List<UserLedgerVO> userLedgerVOS = userLedgerService.selectUserList(new UserReportParam());
Map<String, String> objMap = userLedgerVOS.stream().collect(Collectors.toMap(UserLedgerVO::getId, UserLedgerVO::getProjectName));
for (GeneralDeviceDTO dto : deviceInfo) { for (GeneralDeviceDTO dto : deviceInfo) {
//获取部门终端集合 //获取部门终端集合
List<RStatIntegrityVO> citDevOnRate = lineIntegrityRateInfo.stream().filter(x -> dto.getLineIndexes().contains(x.getLineIndex())).collect(Collectors.toList()); List<RStatIntegrityVO> citDevOnRate = lineIntegrityRateInfo.stream().filter(x -> dto.getLineIndexes().contains(x.getLineIndex())).collect(Collectors.toList());
Map<String, BigDecimal> onlineRateByDevMap = citDevOnRate.stream() Map<String, BigDecimal> onlineRateByDevMap = citDevOnRate.stream()
.collect(Collectors.toMap(RStatIntegrityVO::getLineIndex, RStatIntegrityVO::getIntegrityRate)); .collect(Collectors.toMap(RStatIntegrityVO::getLineIndex, RStatIntegrityVO::getIntegrityRate));
citDetail = new DeviceOnlineRate.CitDetail(); citDetail = new DeviceOnlineRate.CitDetail();
List<LineDetailVO.Detail> lineDetail = LineInfoByIds.stream().filter(x -> dto.getLineIndexes().contains(x.getLineId())).collect(Collectors.toList());
citDetail.setCitName(dto.getName()); citDetail.setCitName(dto.getName());
citDetail.setCitTotalNum(dto.getLineIndexes().size()); citDetail.setCitTotalNum(dto.getLineIndexes().size());
citDetail.setCitBelowNum(CollUtil.isNotEmpty(citDevOnRate) ? calculateIntegrityRate(citDevOnRate, 90, dto.getLineIndexes().size()) : dto.getLineIndexes().size()); citDetail.setCitBelowNum(CollUtil.isNotEmpty(citDevOnRate) ? calculateIntegrityRate(citDevOnRate, 90, dto.getLineIndexes().size()) : dto.getLineIndexes().size());
citDetail.setCitTotalOnlineRate(calculateIntegrityRate(lineIntegrityRateInfo, dto.getLineIndexes()).doubleValue()>100.0?BigDecimal.valueOf(100.0):calculateIntegrityRate(lineIntegrityRateInfo, dto.getLineIndexes())); citDetail.setCitTotalOnlineRate(calculateIntegrityRate(lineIntegrityRateInfo, dto.getLineIndexes()).doubleValue() > 100.0 ? BigDecimal.valueOf(100.0) : calculateIntegrityRate(lineIntegrityRateInfo, dto.getLineIndexes()));
List<DeviceOnlineRate.LineDetail> detailList = new ArrayList<>(); List<DeviceOnlineRate.LineDetail> detailList = new ArrayList<>();
List<LineDetailVO.Detail> lineDetail = LineInfoByIds.stream().filter(x -> dto.getLineIndexes().contains(x.getLineId())).collect(Collectors.toList());
for (LineDetailVO.Detail line : lineDetail) { for (LineDetailVO.Detail line : lineDetail) {
detail = new DeviceOnlineRate.LineDetail(); detail = new DeviceOnlineRate.LineDetail();
detail.setCit(line.getDeptName()); detail.setCit(line.getDeptName());
@@ -193,9 +192,9 @@ public class RStatIntegrityDServiceImpl extends MppServiceImpl<RStatIntegrityDMa
detail.setLineId(line.getLineId()); detail.setLineId(line.getLineId());
detail.setLineName(line.getLineName()); detail.setLineName(line.getLineName());
//用户侧监测点 监测对象 //用户侧监测点 监测对象
detail.setObjName(StringUtils.isBlank(line.getObjId())?"/":objMap.get(line.getObjId())); detail.setObjName(StringUtils.isBlank(line.getObjName()) ? "/" : line.getObjName());
detail.setLatestTime(line.getTimeID()); detail.setLatestTime(line.getTimeID());
detail.setIntegrity(onlineRateByDevMap.getOrDefault(line.getLineId(), BigDecimal.valueOf(0)).doubleValue()>100.0?BigDecimal.valueOf(100.0):onlineRateByDevMap.getOrDefault(line.getLineId(), BigDecimal.valueOf(0))); detail.setIntegrity(onlineRateByDevMap.getOrDefault(line.getLineId(), BigDecimal.valueOf(0)).doubleValue() > 100.0 ? BigDecimal.valueOf(100.0) : onlineRateByDevMap.getOrDefault(line.getLineId(), BigDecimal.valueOf(0)));
detailList.add(detail); detailList.add(detail);
} }
citDetail.setDetailList(detailList); citDetail.setDetailList(detailList);

View File

@@ -3,10 +3,11 @@ package com.njcn.device.pq.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.dataProcess.param.DataCleanParam; import com.njcn.algorithm.pojo.dto.PqReasonableRangeDto;
import com.njcn.dataProcess.pojo.dto.PqReasonableRangeDto; import com.njcn.algorithm.pojo.param.DataCleanParam;
import com.njcn.dataProcess.pojo.po.PqReasonableRange; import com.njcn.algorithm.pojo.po.PqReasonableRange;
import com.njcn.device.pq.mapper.ReasonableRangeMapper; import com.njcn.device.pq.mapper.ReasonableRangeMapper;
import com.njcn.device.pq.service.ReasonableRangeService; import com.njcn.device.pq.service.ReasonableRangeService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;

View File

@@ -20,10 +20,7 @@ import com.njcn.device.pq.pojo.param.DeviceInfoParam;
import com.njcn.device.pq.pojo.param.RunManageParam; import com.njcn.device.pq.pojo.param.RunManageParam;
import com.njcn.device.pq.pojo.po.Line; import com.njcn.device.pq.pojo.po.Line;
import com.njcn.device.pq.pojo.po.LineDetail; import com.njcn.device.pq.pojo.po.LineDetail;
import com.njcn.device.pq.pojo.vo.LineInfluxDbOnlineVO; import com.njcn.device.pq.pojo.vo.*;
import com.njcn.device.pq.pojo.vo.RunManageVO;
import com.njcn.device.pq.pojo.vo.RunTimeVO;
import com.njcn.device.pq.pojo.vo.TerminalLedgerVO;
import com.njcn.device.pq.service.RunManageService; import com.njcn.device.pq.service.RunManageService;
import com.njcn.device.userledger.service.UserLedgerService; import com.njcn.device.userledger.service.UserLedgerService;
import com.njcn.supervision.pojo.vo.user.NewUserReportVO; import com.njcn.supervision.pojo.vo.user.NewUserReportVO;
@@ -31,6 +28,7 @@ import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataTypeEnum; import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.enums.StatisticsEnum; import com.njcn.system.pojo.enums.StatisticsEnum;
import com.njcn.system.pojo.po.DictData; import com.njcn.system.pojo.po.DictData;
import com.njcn.user.pojo.dto.DeptDTO;
import com.njcn.web.factory.PageFactory; import com.njcn.web.factory.PageFactory;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -39,10 +37,7 @@ import org.springframework.util.CollectionUtils;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -157,7 +152,28 @@ public class RunManageServiceImpl implements RunManageService {
if(CollUtil.isEmpty(devIndexes)){ if(CollUtil.isEmpty(devIndexes)){
return new Page<>(); return new Page<>();
} }
return deviceMapper.getDeviceLedger(new Page<>(PageFactory.getPageNum(runManageParam), PageFactory.getPageSize(runManageParam)), devIndexes, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), runManageParam.getSearchValue()); Page<RunTimeVO> deviceLedger = deviceMapper.getDeviceLedger(new Page<>(PageFactory.getPageNum(runManageParam), PageFactory.getPageSize(runManageParam)), devIndexes, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), runManageParam.getSearchValue());
List<String> devID = deviceLedger.getRecords().stream().map(RunTimeVO::getId).collect(Collectors.toList());
if(CollUtil.isNotEmpty(devID)){
//添加装置用户性质
List<DevDetail.DevPowerFlag> devPowerFlags = deviceMapper.selectDevPowerFlagByIds(devID);
Map<String, List<DevDetail.DevPowerFlag>> devPowerFlag =
devPowerFlags.stream().collect(Collectors.groupingBy(DevDetail.DevPowerFlag::getDevIndex));
deviceLedger.getRecords().stream().forEach(
vo -> {
if (devPowerFlag.containsKey(vo.getId())) {
String powerFlagStr = Optional.ofNullable(devPowerFlag.get(vo.getId()))
.orElse(Collections.emptyList())
.stream()
.map(DevDetail.DevPowerFlag::getPowerFlag)
.distinct()
.collect(Collectors.joining("/"));
vo.setPowerFlag(powerFlagStr);
}
}
);
}
return deviceLedger;
} }
/** /**

View File

@@ -1,18 +1,24 @@
package com.njcn.device.pq.service.impl; package com.njcn.device.pq.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.utils.PubUtils; import com.njcn.common.utils.PubUtils;
import com.njcn.device.pq.mapper.AlarmMapper; import com.njcn.device.pq.mapper.AlarmMapper;
import com.njcn.device.pq.pojo.param.AlarmParam; import com.njcn.device.pq.pojo.param.AlarmParam;
import com.njcn.device.pq.pojo.param.TerminalCheckParam;
import com.njcn.device.pq.pojo.vo.TerminalAlarmVO; import com.njcn.device.pq.pojo.vo.TerminalAlarmVO;
import com.njcn.device.pq.pojo.vo.TerminalCheckVO;
import com.njcn.device.pq.service.TerminalAlarmService; import com.njcn.device.pq.service.TerminalAlarmService;
import com.njcn.web.factory.PageFactory; import com.njcn.web.factory.PageFactory;
import com.njcn.web.utils.RequestUtil; import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
@@ -47,4 +53,11 @@ public class TerminalAlarmServiceImpl implements TerminalAlarmService {
public boolean updateAlarmInfo(String type, String devLineId) { public boolean updateAlarmInfo(String type, String devLineId) {
return alarmMapper.updateAlarmInfo(type,devLineId,LocalDateTime.now(),RequestUtil.getUserIndex()); return alarmMapper.updateAlarmInfo(type,devLineId,LocalDateTime.now(),RequestUtil.getUserIndex());
} }
@Override
public Page<TerminalCheckVO> terminalCheckPage(TerminalCheckParam terminalCheckParam) {
Page<TerminalCheckVO> page = new Page<>(PageFactory.getPageNum(terminalCheckParam),PageFactory.getPageSize(terminalCheckParam));
Page<TerminalCheckVO> pageResult = alarmMapper.terminalCheckPage(page,terminalCheckParam);
return pageResult;
}
} }

View File

@@ -32,6 +32,8 @@ import com.njcn.system.pojo.po.Area;
import com.njcn.user.api.DeptFeignClient; import com.njcn.user.api.DeptFeignClient;
import com.njcn.web.utils.RequestUtil; import com.njcn.web.utils.RequestUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -48,7 +50,7 @@ import java.util.stream.Stream;
* @date 2021/7/19 * @date 2021/7/19
*/ */
@Service @Service
@AllArgsConstructor @RequiredArgsConstructor
public class TerminalTreeServiceImpl implements TerminalTreeService { public class TerminalTreeServiceImpl implements TerminalTreeService {
private final LineMapper lineMapper; private final LineMapper lineMapper;
@@ -67,6 +69,8 @@ public class TerminalTreeServiceImpl implements TerminalTreeService {
private final UserLedgerService userLedgerService; private final UserLedgerService userLedgerService;
@Value("${version.used:master}")
private String versionUsed;
/** /**
* 台账页面终端树 * 台账页面终端树
* *
@@ -126,16 +130,7 @@ public class TerminalTreeServiceImpl implements TerminalTreeService {
provinceList.forEach(province -> province.setChildren(getChildren(province, gdList))); provinceList.forEach(province -> province.setChildren(getChildren(province, gdList)));
projectList.forEach(project -> project.setChildren(getChildren(project, provinceList))); projectList.forEach(project -> project.setChildren(getChildren(project, provinceList)));
/* if (CollectionUtil.isNotEmpty(allList)) {
TerminalTree terminalTree = new TerminalTree();
terminalTree.setId("9999999");
terminalTree.setLevel(0);
terminalTree.setName("台账管理");
if (CollectionUtil.isNotEmpty(projectList)) {
terminalTree.setChildren(projectList);
}
taiZhang.add(terminalTree);
}*/
return projectList; return projectList;
} }
@@ -323,8 +318,6 @@ public class TerminalTreeServiceImpl implements TerminalTreeService {
}); });
temMap = temList.stream().collect(Collectors.groupingBy(TerminalTree::getPid)); temMap = temList.stream().collect(Collectors.groupingBy(TerminalTree::getPid));
} }
//处理变电站 //处理变电站
dealChildrenData(subList, otherLineList, temMap, true); dealChildrenData(subList, otherLineList, temMap, true);
@@ -332,11 +325,18 @@ public class TerminalTreeServiceImpl implements TerminalTreeService {
//Integer[] arr = {1}; //Integer[] arr = {1};
//subList.forEach(item->item.getChildren().forEach(it->it.setName((arr[0]++ +"_"+it.getName())))); //subList.forEach(item->item.getChildren().forEach(it->it.setName((arr[0]++ +"_"+it.getName()))));
//处理供电公司 //处理供电公司
dealChildrenData(gdList, subList, null, false);
if (deviceInfoParam.getStatisticalType().getCode().equalsIgnoreCase(StatisticsEnum.POWER_NETWORK.getCode())) { if (deviceInfoParam.getStatisticalType().getCode().equalsIgnoreCase(StatisticsEnum.POWER_NETWORK.getCode())) {
terminalTree.setChildren(gdList); if("liaoning".equals(versionUsed)){
terminalTree.setChildren(subList);
}else {
dealChildrenData(gdList, subList, null, false);
terminalTree.setChildren(gdList);
}
} else { } else {
dealChildrenData(gdList, subList, null, false);
//还需要额外处理省会 //还需要额外处理省会
dealChildrenData(proList, gdList, null, false); dealChildrenData(proList, gdList, null, false);
terminalTree.setChildren(proList); terminalTree.setChildren(proList);

View File

@@ -497,13 +497,13 @@ public class GeneralDeviceService {
} }
List<Line> lines = terminalBaseService.getLineById(lineIds); List<Line> lines = terminalBaseService.getLineById(lineIds);
for (SimpleDTO simpleDTO : scales) { for (SimpleDTO simpleDTO : scales) {
if(ObjectUtil.isNull(type)){ /* if(ObjectUtil.isNull(type)){
List<String> voltageScaleIds = terminalBaseService.getSubIdByScale(subIds, simpleDTO.getId()); List<String> voltageScaleIds = terminalBaseService.getSubIdByScale(subIds, simpleDTO.getId());
generalDeviceDTOS.add(assembleDataByLine(simpleDTO, lines, voltageScaleIds, LineBaseEnum.SUB_LEVEL.getCode())); generalDeviceDTOS.add(assembleDataByLine(simpleDTO, lines, voltageScaleIds, LineBaseEnum.SUB_LEVEL.getCode()));
}else{ }else{*/
List<String> voltageScaleIds = terminalBaseService.getVoltageIdByScale(subVIds, simpleDTO.getId()); List<String> voltageScaleIds = terminalBaseService.getVoltageIdByScale(subVIds, simpleDTO.getId());
generalDeviceDTOS.add(assembleDataByLine(simpleDTO, lines, voltageScaleIds, LineBaseEnum.SUB_V_LEVEL.getCode())); generalDeviceDTOS.add(assembleDataByLine(simpleDTO, lines, voltageScaleIds, LineBaseEnum.SUB_V_LEVEL.getCode()));
} // }
} }
return generalDeviceDTOS; return generalDeviceDTOS;
} }

View File

@@ -37,6 +37,7 @@ import com.njcn.device.device.mapper.DeviceMapper;
import com.njcn.device.device.service.DeviceBakService; import com.njcn.device.device.service.DeviceBakService;
import com.njcn.device.device.service.DeviceProcessService; import com.njcn.device.device.service.DeviceProcessService;
import com.njcn.device.device.service.NodeDeviceService; import com.njcn.device.device.service.NodeDeviceService;
import com.njcn.device.device.service.PqDevTypeService;
import com.njcn.device.line.mapper.DeptLineMapper; import com.njcn.device.line.mapper.DeptLineMapper;
import com.njcn.device.line.mapper.LineDetailMapper; import com.njcn.device.line.mapper.LineDetailMapper;
import com.njcn.device.line.mapper.LineMapper; import com.njcn.device.line.mapper.LineMapper;
@@ -63,6 +64,7 @@ import com.njcn.device.subvoltage.mapper.VoltageMapper;
import com.njcn.device.terminal.mapper.PqsTerminalLogsMapper; import com.njcn.device.terminal.mapper.PqsTerminalLogsMapper;
import com.njcn.device.userledger.service.UserLedgerService; import com.njcn.device.userledger.service.UserLedgerService;
import com.njcn.device.utils.ExcelStyleUtil; import com.njcn.device.utils.ExcelStyleUtil;
import com.njcn.device.utils.LineSortHelper;
import com.njcn.message.api.ProduceFeignClient; import com.njcn.message.api.ProduceFeignClient;
import com.njcn.message.constant.DeviceRebootType; import com.njcn.message.constant.DeviceRebootType;
import com.njcn.message.constant.RedisKeyPrefix; import com.njcn.message.constant.RedisKeyPrefix;
@@ -74,6 +76,8 @@ import com.njcn.oss.utils.FileStorageUtil;
import com.njcn.poi.excel.ExcelUtil; import com.njcn.poi.excel.ExcelUtil;
import com.njcn.poi.util.PoiUtil; import com.njcn.poi.util.PoiUtil;
import com.njcn.redis.utils.RedisUtil; import com.njcn.redis.utils.RedisUtil;
import com.njcn.supervision.pojo.param.user.UserReportParam;
import com.njcn.supervision.pojo.po.user.UserReportPO;
import com.njcn.supervision.pojo.vo.user.UserLedgerVO; import com.njcn.supervision.pojo.vo.user.UserLedgerVO;
import com.njcn.system.api.AreaFeignClient; import com.njcn.system.api.AreaFeignClient;
import com.njcn.system.api.DicDataFeignClient; import com.njcn.system.api.DicDataFeignClient;
@@ -140,6 +144,8 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
private final DeviceProcessService deviceProcessService; private final DeviceProcessService deviceProcessService;
private final ProduceFeignClient produceFeignClient; private final ProduceFeignClient produceFeignClient;
private final UserLedgerService userLedgerService; private final UserLedgerService userLedgerService;
private final PqDevTypeService pqDevTypeService;
private final LineSortHelper lineSortHelper;
@Value("${oracle.isSync}") @Value("${oracle.isSync}")
private Boolean isSync; private Boolean isSync;
@@ -201,6 +207,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
if (StrUtil.isBlank(projectIndex)) { if (StrUtil.isBlank(projectIndex)) {
checkName(addTerminalParam, PROJECT_LEVEL.getCode(), null); checkName(addTerminalParam, PROJECT_LEVEL.getCode(), null);
Line line = assembleLine(addTerminalParam.getProjectParam().getName(), PROJECT_LEVEL.getCode(), "0", "0", addTerminalParam.getProjectParam().getSort()); Line line = assembleLine(addTerminalParam.getProjectParam().getName(), PROJECT_LEVEL.getCode(), "0", "0", addTerminalParam.getProjectParam().getSort());
lineSortHelper.handleSort(PROJECT_LEVEL.getCode(),addTerminalParam.getProjectParam().getSort(),line);
this.baseMapper.insert(line); this.baseMapper.insert(line);
projectIndex = line.getId(); projectIndex = line.getId();
} }
@@ -215,6 +222,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
LogUtil.njcnDebug(log, "获取区域信息:{}", result.toString()); LogUtil.njcnDebug(log, "获取区域信息:{}", result.toString());
checkName(addTerminalParam, PROVINCE_LEVEL.getCode(), projectIndex); checkName(addTerminalParam, PROVINCE_LEVEL.getCode(), projectIndex);
Line province = assembleLine(result.getId(), PROVINCE_LEVEL.getCode(), projectIndex, projectIndex, addTerminalParam.getProvinceParam().getSort()); Line province = assembleLine(result.getId(), PROVINCE_LEVEL.getCode(), projectIndex, projectIndex, addTerminalParam.getProvinceParam().getSort());
lineSortHelper.handleSort(PROVINCE_LEVEL.getCode(),addTerminalParam.getProvinceParam().getSort(),province);
this.baseMapper.insert(province); this.baseMapper.insert(province);
provinceIndex = province.getId(); provinceIndex = province.getId();
} }
@@ -225,6 +233,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
if (StrUtil.isBlank(gdIndex) && StrUtil.isNotBlank(provinceIndex)) { if (StrUtil.isBlank(gdIndex) && StrUtil.isNotBlank(provinceIndex)) {
checkName(addTerminalParam, GD_LEVEL.getCode(), provinceIndex); checkName(addTerminalParam, GD_LEVEL.getCode(), provinceIndex);
Line gdInformation = assembleLine(addTerminalParam.getGdInformationParam().getName(), GD_LEVEL.getCode(), provinceIndex, projectIndex + StrUtil.COMMA + provinceIndex, addTerminalParam.getGdInformationParam().getSort()); Line gdInformation = assembleLine(addTerminalParam.getGdInformationParam().getName(), GD_LEVEL.getCode(), provinceIndex, projectIndex + StrUtil.COMMA + provinceIndex, addTerminalParam.getGdInformationParam().getSort());
lineSortHelper.handleSort(GD_LEVEL.getCode(),addTerminalParam.getGdInformationParam().getSort(),gdInformation);
this.baseMapper.insert(gdInformation); this.baseMapper.insert(gdInformation);
gdIndex = gdInformation.getId(); gdIndex = gdInformation.getId();
} }
@@ -235,6 +244,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
if (StrUtil.isBlank(subIndex) && StrUtil.isNotBlank(gdIndex)) { if (StrUtil.isBlank(subIndex) && StrUtil.isNotBlank(gdIndex)) {
checkName(addTerminalParam, LineBaseEnum.SUB_LEVEL.getCode(), gdIndex); checkName(addTerminalParam, LineBaseEnum.SUB_LEVEL.getCode(), gdIndex);
Line subStation = assembleLine(addTerminalParam.getSubStationParam().getName(), LineBaseEnum.SUB_LEVEL.getCode(), gdIndex, projectIndex + StrUtil.COMMA + provinceIndex + StrUtil.COMMA + gdIndex, addTerminalParam.getSubStationParam().getSort()); Line subStation = assembleLine(addTerminalParam.getSubStationParam().getName(), LineBaseEnum.SUB_LEVEL.getCode(), gdIndex, projectIndex + StrUtil.COMMA + provinceIndex + StrUtil.COMMA + gdIndex, addTerminalParam.getSubStationParam().getSort());
lineSortHelper.handleSort(SUB_LEVEL.getCode(),addTerminalParam.getSubStationParam().getSort(),subStation);
this.baseMapper.insert(subStation); this.baseMapper.insert(subStation);
subIndex = subStation.getId(); subIndex = subStation.getId();
@@ -255,6 +265,8 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
if (CollectionUtil.isNotEmpty(addTerminalParam.getDeviceParam()) && StrUtil.isNotBlank(subIndex)) { if (CollectionUtil.isNotEmpty(addTerminalParam.getDeviceParam()) && StrUtil.isNotBlank(subIndex)) {
//校验变电站下的装置名称ip是否重复 //校验变电站下的装置名称ip是否重复
checkDevNameAndIp(addTerminalParam, subIndex, lineLambdaQueryWrapper); checkDevNameAndIp(addTerminalParam, subIndex, lineLambdaQueryWrapper);
Integer devSort = lineSortHelper.getNextSort(DEVICE_LEVEL.getCode());
for (DeviceParam deviceParam : addTerminalParam.getDeviceParam()) { for (DeviceParam deviceParam : addTerminalParam.getDeviceParam()) {
//用于记录装置id //用于记录装置id
String devIdIndex; String devIdIndex;
@@ -282,9 +294,16 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
} }
} }
if (StrUtil.isBlank(deviceParam.getDevIndex())) { if (StrUtil.isBlank(deviceParam.getDevIndex())) {
Line device = assembleLine(deviceParam.getName(), LineBaseEnum.DEVICE_LEVEL.getCode(), subIndex, projectIndex + StrUtil.COMMA + provinceIndex + StrUtil.COMMA + gdIndex + StrUtil.COMMA + subIndex, deviceParam.getSort()); Line device = assembleLine(deviceParam.getName(), LineBaseEnum.DEVICE_LEVEL.getCode(), subIndex, projectIndex + StrUtil.COMMA + provinceIndex + StrUtil.COMMA + gdIndex + StrUtil.COMMA + subIndex, deviceParam.getSort());
if(Objects.isNull(deviceParam.getSort()) || deviceParam.getSort() == 0){
device.setSort(devSort);
}
this.baseMapper.insert(device); this.baseMapper.insert(device);
if(Objects.isNull(deviceParam.getSort()) || deviceParam.getSort() == 0){
devSort++;
}
devIdIndex = device.getId(); devIdIndex = device.getId();
//装置详情 //装置详情
@@ -364,32 +383,32 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
.eq(Line::getState, DataStateEnum.ENABLE.getCode()) .eq(Line::getState, DataStateEnum.ENABLE.getCode())
.in(Line::getName, subvNameList); .in(Line::getName, subvNameList);
List<Line> subvRes = this.list(lineLambdaQueryWrapper); List<Line> subvRes = this.list(lineLambdaQueryWrapper);
if (!subvRes.isEmpty()) { /* if (!subvRes.isEmpty()) {
List<String> subvList = subvRes.stream().map(Line::getName).collect(Collectors.toList()); List<String> subvList = subvRes.stream().map(Line::getName).collect(Collectors.toList());
throw new BusinessException(DeviceResponseEnum.SUBV_NAME_SAME, String.join(";", subvList)); throw new BusinessException(DeviceResponseEnum.SUBV_NAME_SAME, String.join(";", subvList));
} }*/
} }
//母线 //母线
List<String> voltageName = deviceParam.getSubVoltageParam().stream().filter(item -> StrUtil.isBlank(item.getSubvIndex())).map(SubVoltageParam::getName).collect(Collectors.toList()); List<String> voltageName = deviceParam.getSubVoltageParam().stream().filter(item -> StrUtil.isBlank(item.getSubvIndex())).map(SubVoltageParam::getName).collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(voltageName)) { /* if (CollectionUtil.isNotEmpty(voltageName)) {
List<Line> voltageList = this.baseMapper.getVoltageListBySubId(subIndex, voltageName); List<Line> voltageList = this.baseMapper.getVoltageListBySubId(subIndex, voltageName);
if (CollectionUtil.isNotEmpty(voltageList)) { if (CollectionUtil.isNotEmpty(voltageList)) {
throw new BusinessException(DeviceResponseEnum.SUBV_NAME_SAME, voltageList.stream().map(Line::getName).collect(Collectors.joining(";"))); throw new BusinessException(DeviceResponseEnum.SUBV_NAME_SAME, voltageList.stream().map(Line::getName).collect(Collectors.joining(";")));
} }
} }*/
//校验同一变电站下只能有唯一母线名称 //校验同一变电站下只能有唯一母线名称
List<String> addVoltage = deviceParam.getSubVoltageParam().stream().filter(item -> StrUtil.isBlank(item.getSubvIndex())).map(SubVoltageParam::getName).collect(Collectors.toList()); List<String> addVoltage = deviceParam.getSubVoltageParam().stream().filter(item -> StrUtil.isBlank(item.getSubvIndex())).map(SubVoltageParam::getName).collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(addVoltage)) { /* if (CollectionUtil.isNotEmpty(addVoltage)) {
List<Line> voltageListBySubId = this.baseMapper.getVoltageListBySubId(subIndex, addVoltage); List<Line> voltageListBySubId = this.baseMapper.getVoltageListBySubId(subIndex, addVoltage);
if (CollectionUtil.isNotEmpty(voltageListBySubId)) { if (CollectionUtil.isNotEmpty(voltageListBySubId)) {
throw new BusinessException(DeviceResponseEnum.SUBV_NAME_SAME, voltageListBySubId.stream().map(Line::getName).collect(Collectors.joining(";"))); throw new BusinessException(DeviceResponseEnum.SUBV_NAME_SAME, voltageListBySubId.stream().map(Line::getName).collect(Collectors.joining(";")));
} }
} }*/
Integer subvSort = lineSortHelper.getNextSort(SUB_V_LEVEL.getCode());
for (SubVoltageParam subVoltageParam : deviceParam.getSubVoltageParam()) { for (SubVoltageParam subVoltageParam : deviceParam.getSubVoltageParam()) {
//母线id //母线id
String subvIndex; String subvIndex;
@@ -409,7 +428,13 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
} }
Line subVoltage = assembleLine(subVoltageParam.getName(), LineBaseEnum.SUB_V_LEVEL.getCode(), devIdIndex, projectIndex + StrUtil.COMMA + provinceIndex + StrUtil.COMMA + gdIndex + StrUtil.COMMA + subIndex + StrUtil.COMMA + devIdIndex, subVoltageParam.getSort()); Line subVoltage = assembleLine(subVoltageParam.getName(), LineBaseEnum.SUB_V_LEVEL.getCode(), devIdIndex, projectIndex + StrUtil.COMMA + provinceIndex + StrUtil.COMMA + gdIndex + StrUtil.COMMA + subIndex + StrUtil.COMMA + devIdIndex, subVoltageParam.getSort());
if(Objects.isNull(subVoltageParam.getSort()) || subVoltageParam.getSort() == 0) {
subVoltage.setSort(subvSort);
}
this.baseMapper.insert(subVoltage); this.baseMapper.insert(subVoltage);
if(Objects.isNull(subVoltageParam.getSort()) || subVoltageParam.getSort() == 0) {
subvSort++;
}
subvIndex = subVoltage.getId(); subvIndex = subVoltage.getId();
Voltage voltage = new Voltage(); Voltage voltage = new Voltage();
voltage.setId(subVoltage.getId()); voltage.setId(subVoltage.getId());
@@ -437,6 +462,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
} }
} }
//通用新增监测点 //通用新增监测点
Integer lineSort = lineSortHelper.getNextSort(LineBaseEnum.LINE_LEVEL.getCode());
for (LineParam lineParam : subVoltageParam.getLineParam()) { for (LineParam lineParam : subVoltageParam.getLineParam()) {
if (StrUtil.isBlank(lineParam.getLineIndex()) && StrUtil.isNotBlank(subvIndex)) { if (StrUtil.isBlank(lineParam.getLineIndex()) && StrUtil.isNotBlank(subvIndex)) {
//判断监测点序号是否重复 //判断监测点序号是否重复
@@ -450,7 +476,13 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
//删除与当前线路号重复的项 //删除与当前线路号重复的项
listLineNum.removeIf(lineNo -> lineNo.equals(lineParam.getNum())); listLineNum.removeIf(lineNo -> lineNo.equals(lineParam.getNum()));
Line line = assembleLine(lineParam.getName(), LineBaseEnum.LINE_LEVEL.getCode(), subvIndex, projectIndex + StrUtil.COMMA + provinceIndex + StrUtil.COMMA + gdIndex + StrUtil.COMMA + subIndex + StrUtil.COMMA + devIdIndex + StrUtil.COMMA + subvIndex, lineParam.getSort()); Line line = assembleLine(lineParam.getName(), LineBaseEnum.LINE_LEVEL.getCode(), subvIndex, projectIndex + StrUtil.COMMA + provinceIndex + StrUtil.COMMA + gdIndex + StrUtil.COMMA + subIndex + StrUtil.COMMA + devIdIndex + StrUtil.COMMA + subvIndex, lineParam.getSort());
if(Objects.isNull(lineParam.getSort()) || lineParam.getSort() == 0) {
line.setSort(lineSort);
}
this.baseMapper.insert(line); this.baseMapper.insert(line);
if(Objects.isNull(lineParam.getSort()) || lineParam.getSort() == 0) {
lineSort++;
}
LineDetail lineDetail = new LineDetail(); LineDetail lineDetail = new LineDetail();
BeanUtils.copyProperties(lineParam, lineDetail); BeanUtils.copyProperties(lineParam, lineDetail);
lineDetail.setId(line.getId()); lineDetail.setId(line.getId());
@@ -477,7 +509,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
//监测点限值 //监测点限值
DictData scaleResult = dicDataFeignClient.getDicDataById(voltage.getScale()).getData(); DictData scaleResult = dicDataFeignClient.getDicDataById(voltage.getScale()).getData();
float scaTmp = Float.parseFloat(scaleResult.getValue()); float scaTmp = Float.parseFloat(scaleResult.getValue());
Overlimit overlimit = COverlimitUtil.globalAssemble(scaTmp, lineDetail.getDealCapacity(), lineDetail.getDevCapacity(), lineDetail.getShortCapacity(), 1, 0); Overlimit overlimit = COverlimitUtil.globalAssemble(scaTmp, lineDetail.getDealCapacity(), lineDetail.getDevCapacity(), lineDetail.getShortCapacity(), lineDetail.getPowerFlag(), 0);
if (Objects.isNull(lineParam.getVoltageDev())) { if (Objects.isNull(lineParam.getVoltageDev())) {
overlimit.setVoltageDev(overlimit.getVoltageDev()); overlimit.setVoltageDev(overlimit.getVoltageDev());
@@ -719,10 +751,10 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
.notIn(Line::getId, subVIndexList) .notIn(Line::getId, subVIndexList)
.eq(Line::getPid, voltage.getPid()); .eq(Line::getPid, voltage.getPid());
List<Line> subVoltageList = this.list(lambdaQueryWrapper); List<Line> subVoltageList = this.list(lambdaQueryWrapper);
if (CollectionUtil.isNotEmpty(subVoltageList)) { /* if (CollectionUtil.isNotEmpty(subVoltageList)) {
List<String> repeatSubVNames = subVoltageList.stream().map(Line::getName).collect(Collectors.toList()); List<String> repeatSubVNames = subVoltageList.stream().map(Line::getName).collect(Collectors.toList());
throw new BusinessException(DeviceResponseEnum.SUBV_NAME_SAME, "已存在母线名称:" + String.join(";", repeatSubVNames)); throw new BusinessException(DeviceResponseEnum.SUBV_NAME_SAME, "已存在母线名称:" + String.join(";", repeatSubVNames));
} }*/
} }
} }
@@ -748,7 +780,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
float voltageLevel = Float.parseFloat(dictData.getValue()); float voltageLevel = Float.parseFloat(dictData.getValue());
if (CollectionUtil.isNotEmpty(lineList)) { if (CollectionUtil.isNotEmpty(lineList)) {
for (LineDetail lineDetail : lineList) { for (LineDetail lineDetail : lineList) {
Overlimit overlimit = COverlimitUtil.globalAssemble(voltageLevel, lineDetail.getDealCapacity(), lineDetail.getDevCapacity(), lineDetail.getShortCapacity(), 1, 0); Overlimit overlimit = COverlimitUtil.globalAssemble(voltageLevel, lineDetail.getDealCapacity(), lineDetail.getDevCapacity(), lineDetail.getShortCapacity(), lineDetail.getPowerFlag(), 0);
overlimit.setId(lineDetail.getId()); overlimit.setId(lineDetail.getId());
overlimitMapper.deleteById(lineDetail.getId()); overlimitMapper.deleteById(lineDetail.getId());
overlimitMapper.insert(overlimit); overlimitMapper.insert(overlimit);
@@ -835,7 +867,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
float scaTmp = Float.parseFloat(scaleResult.getValue()); float scaTmp = Float.parseFloat(scaleResult.getValue());
//监测点限值 //监测点限值
Overlimit overlimit = COverlimitUtil.globalAssemble(scaTmp, lineDetail.getDealCapacity(), lineDetail.getDevCapacity(), lineDetail.getShortCapacity(), 1, 0); Overlimit overlimit = COverlimitUtil.globalAssemble(scaTmp, lineDetail.getDealCapacity(), lineDetail.getDevCapacity(), lineDetail.getShortCapacity(), lineDetail.getPowerFlag(), 0);
if (Objects.isNull(updateLineBO.getVoltageDev())) { if (Objects.isNull(updateLineBO.getVoltageDev())) {
overlimit.setVoltageDev(overlimit.getVoltageDev()); overlimit.setVoltageDev(overlimit.getVoltageDev());
} else { } else {
@@ -1631,6 +1663,9 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
@Override @Override
public List<Line> getLineByCondition(List<String> ids, DeviceInfoParam deviceInfoParam) { public List<Line> getLineByCondition(List<String> ids, DeviceInfoParam deviceInfoParam) {
if(StrUtil.isNotBlank(deviceInfoParam.getSearchValue())){
return this.baseMapper.getLineByConditionBySearchValue(ids, deviceInfoParam);
}
return this.baseMapper.getLineByCondition(ids, deviceInfoParam); return this.baseMapper.getLineByCondition(ids, deviceInfoParam);
} }
@@ -1731,18 +1766,24 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
List<DictData> businessList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.BUSINESS_TYPE.getName()).getData(); List<DictData> businessList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.BUSINESS_TYPE.getName()).getData();
List<DictData> loadTypeList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.INTERFERENCE_SOURCE_TYPE.getName()).getData(); List<DictData> loadTypeList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.INTERFERENCE_SOURCE_TYPE.getName()).getData();
List<DictData> manufacturerList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_MANUFACTURER.getName()).getData(); List<DictData> manufacturerList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_MANUFACTURER.getName()).getData();
List<DictData> devTypeList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_TYPE.getName()).getData(); // List<DictData> devTypeList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_TYPE.getName()).getData();
List<PqDevType> devTypeList = pqDevTypeService.list(new LambdaQueryWrapper<PqDevType>()
.eq(PqDevType::getState, DataStateEnum.ENABLE.getCode())
.orderByDesc(PqDevType::getCreateTime));
List<DictData> frontList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.FRONT_TYPE.getName()).getData(); List<DictData> frontList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.FRONT_TYPE.getName()).getData();
List<DictData> scaleList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_VOLTAGE_STAND.getName()).getData(); List<DictData> scaleList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_VOLTAGE_STAND.getName()).getData();
List<UserLedgerVO> userLedgerVOS = userLedgerService.selectUserList(new UserReportParam());
List<Node> nodeList = nodeService.nodeAllList(); List<Node> nodeList = nodeService.nodeAllList();
ExcelUtil.selectList(workbook, 4, 4, scaleList.stream().map(DictData::getName).collect(Collectors.toList()).toArray(new String[]{}));
ExcelUtil.selectList(workbook, 40, 40, userLedgerVOS.stream().map(UserLedgerVO::getProjectName).collect(Collectors.toList()).toArray(new String[]{}));
//这里是自己加的 带下拉框的代码 //这里是自己加的 带下拉框的代码
ExcelUtil.selectList(workbook, 8, 8, new String[]{"虚拟设备", "实际设备", "离线设备"}); ExcelUtil.selectList(workbook, 8, 8, new String[]{"虚拟设备", "实际设备", "离线设备"});
ExcelUtil.selectList(workbook, 9, 9, new String[]{"暂态系统", "稳态系统", "双系统"}); ExcelUtil.selectList(workbook, 9, 9, new String[]{"暂态系统", "稳态系统", "双系统"});
ExcelUtil.selectList(workbook, 10, 10, new String[]{"投运", "热备用", "停运"}); ExcelUtil.selectList(workbook, 10, 10, new String[]{"投运", "热备用", "停运"});
ExcelUtil.selectList(workbook, 11, 11, manufacturerList.stream().map(DictData::getName).collect(Collectors.toList()).toArray(new String[]{})); ExcelUtil.selectList(workbook, 11, 11, manufacturerList.stream().map(DictData::getName).collect(Collectors.toList()).toArray(new String[]{}));
ExcelUtil.selectList(workbook, 12, 12, devTypeList.stream().map(DictData::getName).collect(Collectors.toList()).toArray(new String[]{})); ExcelUtil.selectList(workbook, 12, 12, devTypeList.stream().map(PqDevType::getName).collect(Collectors.toList()).toArray(new String[]{}));
ExcelUtil.selectList(workbook, 17, 17, new String[]{"周期触发", "变为触发"}); ExcelUtil.selectList(workbook, 17, 17, new String[]{"周期触发", "变为触发"});
ExcelUtil.selectList(workbook, 18, 18, nodeList.stream().map(Node::getName).collect(Collectors.toList()).toArray(new String[]{})); ExcelUtil.selectList(workbook, 18, 18, nodeList.stream().map(Node::getName).collect(Collectors.toList()).toArray(new String[]{}));
ExcelUtil.selectList(workbook, 19, 19, frontList.stream().map(DictData::getName).collect(Collectors.toList()).toArray(new String[]{})); ExcelUtil.selectList(workbook, 19, 19, frontList.stream().map(DictData::getName).collect(Collectors.toList()).toArray(new String[]{}));
@@ -1760,6 +1801,8 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
ExcelUtil.selectList(workbook, 41, 41, new String[]{"电网侧", "非电网侧"}); ExcelUtil.selectList(workbook, 41, 41, new String[]{"电网侧", "非电网侧"});
ExcelUtil.selectList(workbook, 42, 42, new String[]{"不参与统计", "参与统计"}); ExcelUtil.selectList(workbook, 42, 42, new String[]{"不参与统计", "参与统计"});
PoiUtil.exportFileByWorkbook(workbook, "台账导入模板.xlsx", response); PoiUtil.exportFileByWorkbook(workbook, "台账导入模板.xlsx", response);
} }
@Override @Override
@@ -1848,7 +1891,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
} }
float voltageLevel = Float.parseFloat(scaleResult.getValue()); float voltageLevel = Float.parseFloat(scaleResult.getValue());
Overlimit overlimit = COverlimitUtil.globalAssemble(voltageLevel, lineDetail.getDealCapacity(), lineDetail.getDevCapacity(), lineDetail.getShortCapacity(), 1, 0); Overlimit overlimit = COverlimitUtil.globalAssemble(voltageLevel, lineDetail.getDealCapacity(), lineDetail.getDevCapacity(), lineDetail.getShortCapacity(), lineDetail.getPowerFlag(), 0);
overlimit.setId(lineDetail.getId()); overlimit.setId(lineDetail.getId());
overlimitMapper.insert(overlimit); overlimitMapper.insert(overlimit);
count++; count++;
@@ -2181,7 +2224,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
//监测点限值 //监测点限值
DictData scaleResult = dicDataFeignClient.getDicDataById(voltage.getScale()).getData(); DictData scaleResult = dicDataFeignClient.getDicDataById(voltage.getScale()).getData();
float scaTmp = Float.parseFloat(scaleResult.getValue()); float scaTmp = Float.parseFloat(scaleResult.getValue());
Overlimit overlimit = COverlimitUtil.globalAssemble(scaTmp, lineDetail.getDealCapacity(), lineDetail.getDevCapacity(), lineDetail.getShortCapacity(), 1, 0); Overlimit overlimit = COverlimitUtil.globalAssemble(scaTmp, lineDetail.getDealCapacity(), lineDetail.getDevCapacity(), lineDetail.getShortCapacity(), lineDetail.getPowerFlag(), 0);
if (Objects.isNull(lineParam.getVoltageDev())) { if (Objects.isNull(lineParam.getVoltageDev())) {
overlimit.setVoltageDev(overlimit.getVoltageDev()); overlimit.setVoltageDev(overlimit.getVoltageDev());
@@ -2729,7 +2772,8 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
* @author cdf * @author cdf
* @date 2022/5/18 * @date 2022/5/18
*/ */
private void saveTerminalBase(List<TerminalBaseExcel> terminalBaseExcels) { @Transactional(rollbackFor = Exception.class)
public void saveTerminalBase(List<TerminalBaseExcel> terminalBaseExcels) {
List<TerminalBaseExcel.TerminalBaseExcelMsg> terminalBaseExcelMsgs = new ArrayList<>(); List<TerminalBaseExcel.TerminalBaseExcelMsg> terminalBaseExcelMsgs = new ArrayList<>();
//任意集合数据为空,不处理 //任意集合数据为空,不处理
if (CollectionUtil.isNotEmpty(terminalBaseExcels)) { if (CollectionUtil.isNotEmpty(terminalBaseExcels)) {
@@ -2844,9 +2888,15 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
} }
//处理终端类型 //处理终端类型
DictData devTypeDicData = dicDataFeignClient.getDicDataByName(terminalBaseExcel.getDevType()).getData(); DictData devTypeDicData = dicDataFeignClient.getDicDataByName(terminalBaseExcel.getDevType()).getData();
PqDevType one = new PqDevType();
if (Objects.isNull(devTypeDicData)) { if (Objects.isNull(devTypeDicData)) {
terminalBaseExcelMsgs.add(assembleBaseMsg(terminalBaseExcel, "字典装置型号不存在")); //上边逻辑不删兼容旧版本新版本查询pq_dev_type
continue; one = pqDevTypeService.lambdaQuery().eq(PqDevType::getName, terminalBaseExcel.getDevType()).eq(PqDevType::getState, DataStateEnum.ENABLE.getCode()).one();
if(Objects.isNull(one)){
terminalBaseExcelMsgs.add(assembleBaseMsg(terminalBaseExcel, "字典装置型号不存在"));
continue;
}
} }
this.baseMapper.insert(temp); this.baseMapper.insert(temp);
Device device = new Device(); Device device = new Device();
@@ -2856,7 +2906,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
device.setIp(terminalBaseExcel.getIp()); device.setIp(terminalBaseExcel.getIp());
device.setNodeId(node.getId()); device.setNodeId(node.getId());
device.setFrontType(frontTypeDicData.getId()); device.setFrontType(frontTypeDicData.getId());
device.setDevType(devTypeDicData.getId()); device.setDevType(Objects.isNull(devTypeDicData)?one.getId():devTypeDicData.getId());
device.setComFlag(0); device.setComFlag(0);
device.setCheckFlag(1); device.setCheckFlag(1);
device.setLoginTime(LocalDate.now()); device.setLoginTime(LocalDate.now());
@@ -2865,7 +2915,11 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
device.setUpdateTime(LocalDateTime.now()); device.setUpdateTime(LocalDateTime.now());
device.setElectroplate(0); device.setElectroplate(0);
device.setOnTime(1); device.setOnTime(1);
//处理装置识别码秘钥
coderM3d(device, false);
deviceMapper.insert(device); deviceMapper.insert(device);
//分配前置进程
nodeDeviceService.oneKeyDistribution(node.getId());
} }
//添加终端索引 //添加终端索引
pids.add(temp.getId()); pids.add(temp.getId());
@@ -2892,6 +2946,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
} }
//处理电压等级字典表 //处理电压等级字典表
DictData subvScale = dicDataFeignClient.getDicDataByNameAndType(terminalBaseExcel.getSubvScale(), DicDataTypeEnum.DEV_VOLTAGE_STAND.getName()).getData(); DictData subvScale = dicDataFeignClient.getDicDataByNameAndType(terminalBaseExcel.getSubvScale(), DicDataTypeEnum.DEV_VOLTAGE_STAND.getName()).getData();
if (Objects.isNull(subvScale)) { if (Objects.isNull(subvScale)) {
terminalBaseExcelMsgs.add(assembleBaseMsg(terminalBaseExcel, "字典电压等级:" + terminalBaseExcel.getSubStationScale() + "不存在")); terminalBaseExcelMsgs.add(assembleBaseMsg(terminalBaseExcel, "字典电压等级:" + terminalBaseExcel.getSubStationScale() + "不存在"));
continue; continue;
@@ -2969,11 +3024,20 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
lineDetail.setPt2(Float.valueOf(pt[1])); lineDetail.setPt2(Float.valueOf(pt[1]));
lineDetail.setCt1(Float.valueOf(ct[0])); lineDetail.setCt1(Float.valueOf(ct[0]));
lineDetail.setCt2(Float.valueOf(ct[1])); lineDetail.setCt2(Float.valueOf(ct[1]));
if(StringUtils.isNoneBlank(terminalBaseExcel.getObjName())){
UserReportPO one = userLedgerService.lambdaQuery().eq(UserReportPO::getProjectName, terminalBaseExcel.getObjName())
.eq(UserReportPO::getState, DataStateEnum.ENABLE.getCode()).one();
if(Objects.nonNull(one)){
lineDetail.setObjId(one.getId());
DictData dictData = dicDataFeignClient.getDicDataByNameAndTypeName(terminalBaseExcel.getSubvScale(), DicDataTypeEnum.DEV_VOLTAGE_STAND.getName()).getData(); }
}
DictData dictData = dicDataFeignClient.getDicDataByNameAndType(terminalBaseExcel.getSubvScale(), DicDataTypeEnum.DEV_VOLTAGE_STAND.getName()).getData();
lineDetailMapper.insert(lineDetail); lineDetailMapper.insert(lineDetail);
Overlimit overlimit = COverlimitUtil.globalAssemble(Float.parseFloat(dictData.getValue()), terminalBaseExcel.getDealCapacity(), terminalBaseExcel.getDevCapacity(), terminalBaseExcel.getShortCapacity(), null, null); Overlimit overlimit = COverlimitUtil.globalAssemble(Float.parseFloat(dictData.getValue()), terminalBaseExcel.getDealCapacity(), terminalBaseExcel.getDevCapacity(), terminalBaseExcel.getShortCapacity(), terminalBaseExcel.getPowerFlag(), 0);
overlimit.setId(temp.getId()); overlimit.setId(temp.getId());
overlimitMapper.insert(overlimit); overlimitMapper.insert(overlimit);
} }
@@ -4043,6 +4107,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
}); });
}); });
} catch (Exception e) { } catch (Exception e) {
log.info("台账同步推送异常:" + e);
//出现异常,直接重启整个前置 //出现异常,直接重启整个前置
exFlag=true; exFlag=true;
for (Node node : nodes) { for (Node node : nodes) {
@@ -4301,6 +4366,10 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
// 比较装置 所属前置 // 比较装置 所属前置
flag |= compareAndAppend(stringBuilder, devDetail.getNodeId(), updateDeviceParam.getNodeId(), "终端所属前置机"); flag |= compareAndAppend(stringBuilder, devDetail.getNodeId(), updateDeviceParam.getNodeId(), "终端所属前置机");
//如果前置机切换可能装置在进程2上但是切换后前置机只有一个进程因此修改装置进程表设为默认进程1
if(!Objects.equals(updateDeviceParam.getNodeId(), devDetail.getNodeId())){
deviceProcessService.lambdaUpdate().eq(DeviceProcess::getId,devDetail.getId()).set(DeviceProcess::getProcessNo,1).update();
}
// 比较装置端口号 // 比较装置端口号
flag |= compareAndAppend(stringBuilder, devDetail.getPort(), updateDeviceParam.getPort(), "终端端口号"); flag |= compareAndAppend(stringBuilder, devDetail.getPort(), updateDeviceParam.getPort(), "终端端口号");

View File

@@ -102,4 +102,6 @@ public interface DeviceMapper extends BaseMapper<Device> {
void updateDeviceRunFlag(@Param("id")String deviceId, @Param("runFlag")Integer status); void updateDeviceRunFlag(@Param("id")String deviceId, @Param("runFlag")Integer status);
List<PollutionLineInfoDTO> getPollutionDeviceInfo(@Param("id")List<String> devId); List<PollutionLineInfoDTO> getPollutionDeviceInfo(@Param("id")List<String> devId);
List<DevDetail.DevPowerFlag> selectDevPowerFlagByIds(@Param("ids") List<String> ids);
} }

View File

@@ -19,7 +19,8 @@
<select id="getRunManageCommList" resultType="com.njcn.device.pq.pojo.vo.RunManageVO"> <select id="getRunManageCommList" resultType="com.njcn.device.pq.pojo.vo.RunManageVO">
SELECT SELECT
linedetail.Num AS id, linedetail.id AS id,
linedetail.Num AS runNo,
line.NAME AS lineName, line.NAME AS lineName,
area.NAME AS areaName, area.NAME AS areaName,
gd.NAME AS gdName, gd.NAME AS gdName,
@@ -28,6 +29,10 @@
manufacturerId.name as manufacturer, manufacturerId.name as manufacturer,
dev.name as devName, dev.name as devName,
device.IP as ip, device.IP as ip,
CASE linedetail.Power_Flag
WHEN 0 THEN '电网侧'
WHEN 1 THEN '非电网侧'
END AS powerFlag,
case linedetail.Run_Flag case linedetail.Run_Flag
when 0 then '投运' when 0 then '投运'
when 1 then '检修' when 1 then '检修'
@@ -140,7 +145,8 @@
<select id="getRunManageList" resultType="com.njcn.device.pq.pojo.vo.RunManageVO"> <select id="getRunManageList" resultType="com.njcn.device.pq.pojo.vo.RunManageVO">
SELECT SELECT
linedetail.Num AS id, linedetail.id AS id,
linedetail.Num AS runNo,
line.NAME AS lineName, line.NAME AS lineName,
area.NAME AS areaName, area.NAME AS areaName,
gd.NAME AS gdName, gd.NAME AS gdName,
@@ -149,6 +155,10 @@
manufacturerId.name as manufacturer, manufacturerId.name as manufacturer,
dev.name as devName, dev.name as devName,
device.IP as ip, device.IP as ip,
CASE linedetail.Power_Flag
WHEN 0 THEN '电网侧'
WHEN 1 THEN '非电网侧'
END AS powerFlag,
case linedetail.Run_Flag case linedetail.Run_Flag
when 0 then '投运' when 0 then '投运'
when 1 then '检修' when 1 then '检修'
@@ -506,7 +516,14 @@
pv.scale lineVoltage, pv.scale lineVoltage,
pqsub.scale subVoltage, pqsub.scale subVoltage,
lineDetail.monitor_id monitorId, lineDetail.monitor_id monitorId,
lineDetail.Actual_Area actualArea lineDetail.Actual_Area actualArea,
CASE lineDetail.Run_Flag
WHEN 0 THEN'投运'
WHEN 1 THEN'检修'
WHEN 2 THEN'停运'
WHEN 3 THEN'调试'
WHEN 4 THEN'退运'
END AS runFlag
FROM FROM
pq_line line, pq_line line,
pq_line_detail lineDetail, pq_line_detail lineDetail,
@@ -530,5 +547,31 @@
AND substation.id = pqsub.id AND substation.id = pqsub.id
AND subv.id = pv.id AND subv.id = pv.id
</select> </select>
<select id="selectDevPowerFlagByIds" resultType="com.njcn.device.pq.pojo.vo.DevDetail$DevPowerFlag">
SELECT DISTINCT
device.id as devIndex,
CASE lineDetail.Power_Flag
WHEN 0 THEN '电网侧'
WHEN 1 THEN '非电网侧'
END AS powerFlag
FROM
pq_line line,
pq_dept_line pd,
pq_line voltage,
pq_line device,
pq_line_detail lineDetail
<where>
<if test="ids!=null and ids.size()>0">
device.id IN
<foreach collection="ids" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
AND line.pid = voltage.id
AND line.id = pd.Line_Id
AND voltage.pid = device.id
AND line.id = lineDetail.id
</where>
</select>
</mapper> </mapper>

View File

@@ -148,6 +148,8 @@ public interface LineMapper extends BaseMapper<Line> {
*/ */
List<Line> getLineByCondition(@Param("ids") List<String> ids, @Param("deviceInfoParam") DeviceInfoParam deviceInfoParam); List<Line> getLineByCondition(@Param("ids") List<String> ids, @Param("deviceInfoParam") DeviceInfoParam deviceInfoParam);
List<Line> getLineByConditionBySearchValue(@Param("ids") List<String> ids, @Param("deviceInfoParam") DeviceInfoParam deviceInfoParam);
/** /**
* 查询终端信息 * 查询终端信息
* *

View File

@@ -88,7 +88,9 @@
voltage.name busBarname, voltage.name busBarname,
pq_voltage.scale voltageLevel, pq_voltage.scale voltageLevel,
bd.name bdName, bd.name bdName,
gd.name gdName gd.name gdName,
supervision_user_report.project_name objName
from pq_dept_line pq_dept_line from pq_dept_line pq_dept_line
inner join pq_line point on pq_dept_line.line_id = point.id inner join pq_line point on pq_dept_line.line_id = point.id
inner join pq_line_detail lineDetail on point.id = lineDetail.id inner join pq_line_detail lineDetail on point.id = lineDetail.id
@@ -98,6 +100,7 @@
inner join pq_device device on dev.id = device.id inner join pq_device device on dev.id = device.id
inner join pq_line bd on dev.pid = bd.id inner join pq_line bd on dev.pid = bd.id
inner join pq_line gd on bd.pid = gd.id inner join pq_line gd on bd.pid = gd.id
left join supervision_user_report on lineDetail.Obj_Id = supervision_user_report.id
where device.Dev_Model = 1 where device.Dev_Model = 1
and point.state = 1 and point.state = 1
and device.Dev_Data_Type in and device.Dev_Data_Type in

View File

@@ -235,4 +235,10 @@ public interface LineService extends IService<Line> {
* 终端运行状态修改时,同时调整监测点的运行状态 * 终端运行状态修改时,同时调整监测点的运行状态
*/ */
void updateLineRunFlag(String id, Integer status); void updateLineRunFlag(String id, Integer status);
/**
* 自动修改验证pids是否正确
*/
void updatePids();
} }

View File

@@ -83,10 +83,9 @@ public class DeptLineServiceImpl extends ServiceImpl<DeptLineMapper, DeptLine> i
List<String> deptList = Arrays.asList("130700000000", "130300000000", "130800000000", "130200000000", "131000000000"); List<String> deptList = Arrays.asList("130700000000", "130300000000", "130800000000", "130200000000", "131000000000");
Dept data = deptFeignClient.getDeptById(deptLineParam.getId()).getData(); Dept data = deptFeignClient.getDeptById(deptLineParam.getId()).getData();
if (deptList.contains(data.getArea())) { if (deptList.contains(data.getArea())) {
List<String> lineIds = list.stream().map(LineDetail::getId).collect(Collectors.toList());
detailMapper.update(null, new LambdaUpdateWrapper<LineDetail>() detailMapper.update(null, new LambdaUpdateWrapper<LineDetail>()
.set(LineDetail::getActualArea, data.getArea()) .set(LineDetail::getActualArea, data.getArea())
.in(LineDetail::getId, lineIds)); .in(LineDetail::getId, ids));
} }
} }
} }

View File

@@ -6,9 +6,11 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum; import com.njcn.common.pojo.enums.common.DataStateEnum;
@@ -45,6 +47,7 @@ import com.njcn.influx.imapper.PqsCommunicateMapper;
import com.njcn.influx.pojo.po.PqsCommunicate; import com.njcn.influx.pojo.po.PqsCommunicate;
import com.njcn.influx.query.InfluxQueryWrapper; import com.njcn.influx.query.InfluxQueryWrapper;
import com.njcn.supervision.pojo.vo.user.NewUserReportVO; import com.njcn.supervision.pojo.vo.user.NewUserReportVO;
import com.njcn.supervision.pojo.vo.user.UserReportVO;
import com.njcn.system.api.AreaFeignClient; import com.njcn.system.api.AreaFeignClient;
import com.njcn.system.api.DicDataFeignClient; import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataTypeEnum; import com.njcn.system.enums.DicDataTypeEnum;
@@ -157,8 +160,10 @@ public class LineServiceImpl extends ServiceImpl<LineMapper, Line> implements Li
lineDetailDataVO.setIp(device.getIp()); lineDetailDataVO.setIp(device.getIp());
lineDetailDataVO.setLoginTime(device.getLoginTime()); lineDetailDataVO.setLoginTime(device.getLoginTime());
lineDetailDataVO.setDevId(device.getId()); lineDetailDataVO.setDevId(device.getId());
lineDetailDataVO.setDevType(device.getDevType());
lineDetailDataVO.setBusinessType(dicDataFeignClient.getDicDataById(lineDetail.getBusinessType()).getData().getName()); lineDetailDataVO.setBusinessType(dicDataFeignClient.getDicDataById(lineDetail.getBusinessType()).getData().getName());
lineDetailDataVO.setLoadType(dicDataFeignClient.getDicDataById(lineDetail.getLoadType()).getData().getName()); lineDetailDataVO.setLoadType(dicDataFeignClient.getDicDataById(lineDetail.getLoadType()).getData().getName());
lineDetailDataVO.setObjId(lineDetail.getObjId());
lineDetailDataVO.setObjName(lineDetail.getObjName()); lineDetailDataVO.setObjName(lineDetail.getObjName());
lineDetailDataVO.setId(lineDetail.getNum()); lineDetailDataVO.setId(lineDetail.getNum());
lineDetailDataVO.setPtType(PubUtils.ptType(lineDetail.getPtType())); lineDetailDataVO.setPtType(PubUtils.ptType(lineDetail.getPtType()));
@@ -616,6 +621,11 @@ public class LineServiceImpl extends ServiceImpl<LineMapper, Line> implements Li
lineLineDTO.setLinename(lineName); lineLineDTO.setLinename(lineName);
lineLineDTO.setNum(lineDetail.getNum()); lineLineDTO.setNum(lineDetail.getNum());
lineLineDTO.setObjName(lineDetail.getObjName()); lineLineDTO.setObjName(lineDetail.getObjName());
lineLineDTO.setObjId(lineDetail.getObjId());
if(StringUtils.isNotEmpty(lineDetail.getObjId())){
UserReportVO userReportVO = userLedgerService.getUserReportById(lineDetail.getObjId());
lineLineDTO.setObjName2(userReportVO.getProjectName());
}
lineLineDTO.setLoadType(dicDataFeignClient.getDicDataById(lineDetail.getLoadType()).getData().getName()); lineLineDTO.setLoadType(dicDataFeignClient.getDicDataById(lineDetail.getLoadType()).getData().getName());
//电压使用母线电压 //电压使用母线电压
lineLineDTO.setVoltageLevel(dicDataFeignClient.getDicDataById(voltage.getScale()).getData().getName()); lineLineDTO.setVoltageLevel(dicDataFeignClient.getDicDataById(voltage.getScale()).getData().getName());
@@ -834,6 +844,82 @@ public class LineServiceImpl extends ServiceImpl<LineMapper, Line> implements Li
} }
} }
@Override
public void updatePids() {
List<Line> list = this.list();
List<String> strings = this.checkPidsError(list);
if(CollUtil.isNotEmpty(strings)){
for (String msg : strings) {
// 1. 按 | 分割成三部分
String[] parts = msg.split(" \\| ");
// 2. 提取节点 ID
String id = parts[0].replace("节点ID", "").trim();
// 3. 提取正确 pids去掉括号
String newPids = parts[2].replace("正确pids[", "").replace("]", "").trim();
this.update(new LambdaUpdateWrapper<Line>()
.set(Line::getPids, newPids)
.eq(Line::getId, id));
}
}
}
/**
* 校验所有节点 pids 是否正确
* 正确规则去掉开头0 + 去掉自身ID只保留祖先链
*/
public List<String> checkPidsError(List<Line> allList) {
List<String> errorList = new ArrayList<>();
Map<String, Line> idMap = allList.stream().collect(Collectors.toMap(Line::getId,Function.identity()));
for (Line node : allList) {
// 1. 生成正确格式的 pids你的规则
String correctPids = getCorrectPids(node.getId(), idMap);
// 2. 数据库存储的 pids
String dbPids = node.getPids() == null ? "" : node.getPids().trim();
// 3. 对比,不一致就是错误
if (!correctPids.equals(dbPids)) {
errorList.add("节点ID" + node.getId() +
" | 数据库pids[" + dbPids +
"] | 正确pids[" + correctPids + "]");
}
}
return errorList;
}
/**
* 核心:生成【你要求】的正确 pids
* 规则:
* 1. 向上遍历所有祖先
* 2. 去掉开头 0
* 3. 去掉最后一位自身ID
* 4. 用逗号拼接
*/
private String getCorrectPids(String nodeId, Map<String, Line> idMap) {
Deque<String> pathDeque = new LinkedList<>();
String currentId = nodeId;
// 向上收集所有节点(包含自身 + 所有祖先 + 0
while (currentId != null && !currentId.isEmpty()) {
Line node = idMap.get(currentId);
if (ObjectUtil.isNotNull(node)) {
// 头插,保证顺序正确
pathDeque.addFirst(currentId);
currentId = node.getPid();
}
}
// 转列表
List<String> path = new ArrayList<>(pathDeque);
// 1. 去掉开头的 0
if (!path.isEmpty() && "0".equals(path.get(0))) {
path.remove(0);
}
// 2. 去掉最后一位自身ID
if (!path.isEmpty()) {
path.remove(path.size() - 1);
}
// 拼接成最终正确 pids
return String.join(",", path);
}
@Override @Override
public List<Overlimit> getOverLimitByList(PollutionParamDTO pollutionParamDTO) { public List<Overlimit> getOverLimitByList(PollutionParamDTO pollutionParamDTO) {
@@ -908,6 +994,7 @@ public class LineServiceImpl extends ServiceImpl<LineMapper, Line> implements Li
areaLineInfoVO.setSubName(newUserReportVO.getProjectName()); areaLineInfoVO.setSubName(newUserReportVO.getProjectName());
areaLineInfoVO.setLat(newUserReportVO.getLatitude()); areaLineInfoVO.setLat(newUserReportVO.getLatitude());
areaLineInfoVO.setLng(newUserReportVO.getLongitude()); areaLineInfoVO.setLng(newUserReportVO.getLongitude());
areaLineInfoVO.setObjName(newUserReportVO.getProjectName());
} }
} }
} }

View File

@@ -8,6 +8,7 @@
pq_device.Id id, pq_device.Id id,
pq_device.IP ip, pq_device.IP ip,
s1.Name devType, s1.Name devType,
S3.Name comType,
pq_device.Port port, pq_device.Port port,
pq_line.Name name, pq_line.Name name,
sub.Name subName, sub.Name subName,
@@ -25,15 +26,16 @@
LEFT JOIN pq_line sub on pq_line.pid = sub.id LEFT JOIN pq_line sub on pq_line.pid = sub.id
LEFT JOIN pq_device_process on pq_device_process.id = pq_device.id LEFT JOIN pq_device_process on pq_device_process.id = pq_device.id
LEFT JOIN pq_dev_type s1 ON pq_device.Dev_Type = s1.id LEFT JOIN pq_dev_type s1 ON pq_device.Dev_Type = s1.id
LEFT JOIN sys_dict_data s3 ON pq_device.Front_Type = s3.id
LEFT JOIN sys_dict_data s2 ON pq_device.Manufacturer = s2.id LEFT JOIN sys_dict_data s2 ON pq_device.Manufacturer = s2.id
<where> <where>
<if test="nodeDeviceParam.ip!=null and nodeDeviceParam.ip != ''"> <if test="nodeDeviceParam.ip!=null and nodeDeviceParam.ip != ''">
pq_node.ip=#{nodeDeviceParam.ip} pq_node.ip=#{nodeDeviceParam.ip}
</if> </if>
<if test="nodeDeviceParam.devId!=null and nodeDeviceParam.devId != ''"> <if test="nodeDeviceParam.devId!=null and nodeDeviceParam.devId != ''">
pq_device.id=#{nodeDeviceParam.devId} pq_device.id=#{nodeDeviceParam.devId}
</if> </if>
<if test="nodeDeviceParam.runFlag!=null and nodeDeviceParam.runFlag.size()!=0"> <if test="nodeDeviceParam.runFlag!=null and nodeDeviceParam.runFlag.size()!=0">
AND pq_device.Run_Flag in AND pq_device.Run_Flag in
<foreach collection="nodeDeviceParam.runFlag" open="(" close=")" item="item" separator=","> <foreach collection="nodeDeviceParam.runFlag" open="(" close=")" item="item" separator=",">
#{item} #{item}

View File

@@ -69,7 +69,7 @@
select select
if(sum(real_time*1.0)/sum(due_time)*100>100, if(sum(real_time*1.0)/sum(due_time)*100>100,
100, 100,
IFNULL(ROUND( sum(real_time)/sum(due_time)*100,2),0)) IFNULL(ROUND( sum(real_time*1.0)/sum(due_time)*100,2),0))
as integrityRate as integrityRate
from from
r_stat_integrity_d r_stat_integrity_d

View File

@@ -24,6 +24,10 @@ public interface TerminalMaintainMapper {
*/ */
List<TerminalMaintainVO> getTerminalDevInfo(@Param("devIds") List<String> devIds, @Param("comFlag") Integer comFlag, @Param("devType") String devType); List<TerminalMaintainVO> getTerminalDevInfo(@Param("devIds") List<String> devIds, @Param("comFlag") Integer comFlag, @Param("devType") String devType);
List<TerminalMaintainVO> terminalConfig(@Param("devIds") List<String> devIds, @Param("comFlag") Integer comFlag, @Param("devType") String devType);
/** /**
* 获取区域 * 获取区域
* @author cdf * @author cdf

View File

@@ -38,6 +38,35 @@
</if> </if>
</select> </select>
<select id="terminalConfig" resultType="TerminalMaintainVO">
SELECT distinct
IF(TRIM(detail.obj_name) != '', CONCAT(detail.obj_name,'_',a.NAME), a.NAME) as name,
a.id,
a.pid,
a.level,
b.run_flag,
b.ip,
b.com_flag,
b.dev_type devType
FROM
pq_line line
inner join pq_line_detail detail on line.id = detail.id
inner join pq_line bus on line.pid = bus.id
inner join pq_line a on bus.pid = a.id
INNER JOIN pq_device b ON a.id = b.id
where a.id in
<foreach collection="devIds" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
<if test="comFlag != null">
AND b.Com_Flag=#{comFlag}
</if>
<if test="devType !=null and devType != ''">
AND b.Dev_Type =#{devType}
</if>
</select>
<select id="getGdAndSubList" resultType="TerminalMaintainVO"> <select id="getGdAndSubList" resultType="TerminalMaintainVO">
select id,name,level,pid from pq_line where level = #{level} and state = 1 order by sort select id,name,level,pid from pq_line where level = #{level} and state = 1 order by sort
</select> </select>
@@ -77,14 +106,17 @@
<select id="getRunFlagList" resultType="TerminalMaintainVO"> <select id="getRunFlagList" resultType="TerminalMaintainVO">
SELECT SELECT
IF(TRIM(detail.obj_name) != '', CONCAT(detail.obj_name,'_',a.NAME), a.NAME) as name,
a.id, a.id,
a.pid, a.pid,
a.NAME,
b.ip, b.ip,
a.level, a.level,
b.run_flag b.run_flag
FROM FROM
pq_line a pq_line line
inner join pq_line_detail detail on line.id = detail.id
inner join pq_line bus on line.pid = bus.id
inner join pq_line a on bus.pid = a.id
INNER JOIN pq_device b ON a.id = b.id INNER JOIN pq_device b ON a.id = b.id
WHERE a.id in WHERE a.id in
<foreach collection="ids" item="item" separator="," index="index" open="(" close=")"> <foreach collection="ids" item="item" separator="," index="index" open="(" close=")">

View File

@@ -3,6 +3,7 @@ package com.njcn.device.terminal.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.njcn.common.pojo.dto.SimpleDTO; import com.njcn.common.pojo.dto.SimpleDTO;
@@ -108,10 +109,13 @@ public class TerminalMaintainServiceImpl implements TerminalMaintainService {
terminalMaintainVO.setName(generalDeviceDTO.getName()); terminalMaintainVO.setName(generalDeviceDTO.getName());
terminalMaintainVO.setId(generalDeviceDTO.getIndex()); terminalMaintainVO.setId(generalDeviceDTO.getIndex());
terminalMaintainVO.setLevel(1); terminalMaintainVO.setLevel(1);
List<TerminalMaintainVO> devList = terminalMaintainMapper.getTerminalDevInfo(devIds,terminalMainQueryParam.getComFlag(),terminalMainQueryParam.getDevType()); List<TerminalMaintainVO> devList = terminalMaintainMapper.terminalConfig(devIds,terminalMainQueryParam.getComFlag(),terminalMainQueryParam.getDevType());
if (CollectionUtil.isEmpty(devList)) { if (CollectionUtil.isEmpty(devList)) {
continue; continue;
} }
List<String> subIndexes = devList.stream().map(TerminalMaintainVO::getPid).collect(Collectors.toList()); List<String> subIndexes = devList.stream().map(TerminalMaintainVO::getPid).collect(Collectors.toList());
List<TerminalMaintainVO> subList1 = terminalMaintainMapper.getPqLineGdAndSubList(subIndexes); List<TerminalMaintainVO> subList1 = terminalMaintainMapper.getPqLineGdAndSubList(subIndexes);
List<String> gdIndexes = subList1.stream().map(TerminalMaintainVO::getPid).collect(Collectors.toList()); List<String> gdIndexes = subList1.stream().map(TerminalMaintainVO::getPid).collect(Collectors.toList());
@@ -187,14 +191,14 @@ public class TerminalMaintainServiceImpl implements TerminalMaintainService {
if (device.getRunFlag() == 0) { if (device.getRunFlag() == 0) {
newFlag = "投运"; newFlag = "投运";
} else if (device.getRunFlag() == 1) { } else if (device.getRunFlag() == 1) {
newFlag = "热备用"; newFlag = "检修";
} else if (device.getRunFlag() == 2) { } else if (device.getRunFlag() == 2) {
newFlag = "停运"; newFlag = "停运";
} }
if (device1.getRunFlag() == 0) { if (device1.getRunFlag() == 0) {
oldFlag = "投运"; oldFlag = "投运";
} else if (device1.getRunFlag() == 1) { } else if (device1.getRunFlag() == 1) {
oldFlag = "热备用"; oldFlag = "检修";
} else if (device1.getRunFlag() == 2) { } else if (device1.getRunFlag() == 2) {
oldFlag = "停运"; oldFlag = "停运";
} }

View File

@@ -7,6 +7,7 @@ import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum; import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult; import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil; import com.njcn.common.utils.HttpResultUtil;
import com.njcn.device.pq.pojo.param.TerminalCheckParam;
import com.njcn.device.userledger.service.UserLedgerService; import com.njcn.device.userledger.service.UserLedgerService;
import com.njcn.supervision.pojo.param.SensitiveUserParam; import com.njcn.supervision.pojo.param.SensitiveUserParam;
import com.njcn.supervision.pojo.param.user.UserReportParam; import com.njcn.supervision.pojo.param.user.UserReportParam;
@@ -19,6 +20,7 @@ import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.ir.Terminal;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -147,4 +149,15 @@ public class UserLedgerController extends BaseController {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, userReportVO, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, userReportVO, methodDescribe);
} }
@OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.UPLOAD)
@PostMapping("/userCheckUpload")
@ApiOperation("周期检测")
@ApiImplicitParam(name = "terminalCheckParam", value = "实体参数", required = true)
public HttpResult<Boolean> userCheckUpload(@RequestBody @Validated TerminalCheckParam terminalCheckParam) {
String methodDescribe = getMethodDescribe("userCheckUpload");
Boolean f = userReportPOService.userCheckUpload(terminalCheckParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, f, methodDescribe);
}
} }

View File

@@ -0,0 +1,15 @@
package com.njcn.device.userledger.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.device.pq.pojo.po.SupervisionUserReportFile;
import org.apache.ibatis.annotations.Mapper;
/**
* @Author: cdf
* @CreateTime: 2026-07-07
* @Description:
*/
@Mapper
public interface SupervisionUserReportFileMapper extends BaseMapper<SupervisionUserReportFile> {
}

View File

@@ -27,6 +27,7 @@
supervision_user_report.status, supervision_user_report.status,
supervision_user_report.dev_id, supervision_user_report.dev_id,
supervision_user_report.line_id, supervision_user_report.line_id,
supervision_user_report.station_id,
supervision_user_report.second_assessment_id secondAssessmentId supervision_user_report.second_assessment_id secondAssessmentId
FROM supervision_user_report supervision_user_report FROM supervision_user_report supervision_user_report
WHERE ${ew.sqlSegment} WHERE ${ew.sqlSegment}

View File

@@ -0,0 +1,8 @@
package com.njcn.device.userledger.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.device.pq.pojo.po.SupervisionUserReportFile;
public interface SupervisionUserReportFileService extends IService<SupervisionUserReportFile> {
}

View File

@@ -2,6 +2,7 @@ package com.njcn.device.userledger.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.device.pq.pojo.param.TerminalCheckParam;
import com.njcn.supervision.pojo.param.SensitiveUserParam; import com.njcn.supervision.pojo.param.SensitiveUserParam;
import com.njcn.supervision.pojo.param.user.UserReportParam; import com.njcn.supervision.pojo.param.user.UserReportParam;
import com.njcn.supervision.pojo.po.user.UserReportPO; import com.njcn.supervision.pojo.po.user.UserReportPO;
@@ -90,4 +91,7 @@ public interface UserLedgerService extends IService<UserReportPO> {
* @return * @return
*/ */
UserReportVO getUserReportById(String id); UserReportVO getUserReportById(String id);
Boolean userCheckUpload(TerminalCheckParam terminalCheckParam);
} }

View File

@@ -0,0 +1,19 @@
package com.njcn.device.userledger.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.device.userledger.mapper.SupervisionUserReportFileMapper;
import com.njcn.device.pq.pojo.po.SupervisionUserReportFile;
import com.njcn.device.userledger.service.SupervisionUserReportFileService;
import org.springframework.stereotype.Service;
/**
* @Author: cdf
* @CreateTime: 2026-07-07
* @Description:
*/
@Service
public class SupervisionUserReportFileServiceImpl extends ServiceImpl<SupervisionUserReportFileMapper, SupervisionUserReportFile>
implements SupervisionUserReportFileService {
}

View File

@@ -17,12 +17,19 @@ import com.njcn.bpm.enums.BpmTaskStatusEnum;
import com.njcn.common.pojo.constant.PatternRegex; import com.njcn.common.pojo.constant.PatternRegex;
import com.njcn.common.pojo.enums.common.DataStateEnum; import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.device.mapper.DeviceMapper;
import com.njcn.device.line.mapper.LineDetailMapper;
import com.njcn.device.line.mapper.LineMapper;
import com.njcn.device.pq.pojo.param.TerminalCheckParam;
import com.njcn.device.pq.pojo.po.Device;
import com.njcn.device.pq.pojo.po.Line;
import com.njcn.device.pq.pojo.po.LineDetail;
import com.njcn.device.pq.pojo.po.SupervisionUserReportFile;
import com.njcn.device.substation.mapper.SubstationMapper;
import com.njcn.device.userledger.mapper.SupervisionUserReportFileMapper;
import com.njcn.device.userledger.mapper.UserReportNormalMapper; import com.njcn.device.userledger.mapper.UserReportNormalMapper;
import com.njcn.device.userledger.mapper.UserReportPOMapper; import com.njcn.device.userledger.mapper.UserReportPOMapper;
import com.njcn.device.userledger.service.UserLedgerService; import com.njcn.device.userledger.service.*;
import com.njcn.device.userledger.service.UserReportProjectPOService;
import com.njcn.device.userledger.service.UserReportSensitivePOService;
import com.njcn.device.userledger.service.UserReportSubstationPOService;
import com.njcn.supervision.enums.FlowStatusEnum; import com.njcn.supervision.enums.FlowStatusEnum;
import com.njcn.supervision.enums.SupervisionResponseEnum; import com.njcn.supervision.enums.SupervisionResponseEnum;
import com.njcn.supervision.enums.UserNatureEnum; import com.njcn.supervision.enums.UserNatureEnum;
@@ -44,8 +51,10 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -67,6 +76,10 @@ public class UserLedgerServiceImpl extends ServiceImpl<UserReportPOMapper, UserR
private final UserReportNormalMapper userReportNormalMapper; private final UserReportNormalMapper userReportNormalMapper;
private final UserReportSensitivePOService userReportSensitivePOService; private final UserReportSensitivePOService userReportSensitivePOService;
private final UserFeignClient userFeignClient; private final UserFeignClient userFeignClient;
private final LineMapper substationMapper;
private final LineDetailMapper lineDetailMapper;
private final SupervisionUserReportFileService supervisionUserReportFileService;
private final DeviceMapper deviceMapper;
@Override @Override
public List<UserLedgerVO> selectUserList(UserReportParam userReportParam) { public List<UserLedgerVO> selectUserList(UserReportParam userReportParam) {
@@ -171,7 +184,19 @@ public class UserLedgerServiceImpl extends ServiceImpl<UserReportPOMapper, UserR
userReportVOQueryWrapper.orderByDesc("supervision_user_report.create_time"); userReportVOQueryWrapper.orderByDesc("supervision_user_report.create_time");
Page<UserReportVO> page; Page<UserReportVO> page;
page = this.baseMapper.page(new Page<>(PageFactory.getPageNum(userReportQueryParam), PageFactory.getPageSize(userReportQueryParam)), userReportVOQueryWrapper); page = this.baseMapper.page(new Page<>(PageFactory.getPageNum(userReportQueryParam), PageFactory.getPageSize(userReportQueryParam)), userReportVOQueryWrapper);
Map<String,String> atationMap = new HashMap<>();
if(CollUtil.isNotEmpty(page.getRecords())){
List<String> stationIds = page.getRecords().stream().map(UserReportVO::getStationId).filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList());
if(CollUtil.isNotEmpty(stationIds)){
List<Line> stationList = substationMapper.selectBatchIds(stationIds);
stationList.forEach(line -> atationMap.put(line.getId(), line.getName()));
}
List<String> ids = page.getRecords().stream().map(UserReportVO::getId).collect(Collectors.toList());
List<SupervisionUserReportFile> supervisionUserReportFiles = supervisionUserReportFileService.lambdaQuery().in(SupervisionUserReportFile::getId,ids).list();
Map<String,SupervisionUserReportFile> stringSupervisionUserReportFileMap = supervisionUserReportFiles.stream().collect(Collectors.toMap(SupervisionUserReportFile::getId, Function.identity()));
page.getRecords().forEach(temp -> { page.getRecords().forEach(temp -> {
temp.setStationId(atationMap.getOrDefault(temp.getStationId(),"/"));
Integer needGovernance = 0; Integer needGovernance = 0;
if ( if (
CollectionUtil.newArrayList( CollectionUtil.newArrayList(
@@ -217,7 +242,16 @@ public class UserLedgerServiceImpl extends ServiceImpl<UserReportPOMapper, UserR
} }
} }
temp.setType(type); temp.setType(type);
if(stringSupervisionUserReportFileMap.containsKey(temp.getId())){
SupervisionUserReportFile supervisionUserReportFile = stringSupervisionUserReportFileMap.get(temp.getId());
temp.setCheckUrl(supervisionUserReportFile.getCheckUrl());
//temp.setCheckHistoryUrl(supervisionUserReportFile.getCheckHistoryUrl());
temp.setAssessUrl(supervisionUserReportFile.getAssessUrl());
temp.setOtherUrl(supervisionUserReportFile.getOtherUrl());
}
}); });
}
return page; return page;
} }
@@ -241,6 +275,13 @@ public class UserLedgerServiceImpl extends ServiceImpl<UserReportPOMapper, UserR
userReportVO.setOrgName(dept.getName()); userReportVO.setOrgName(dept.getName());
} }
} }
SupervisionUserReportFile supervisionUserReportFile = supervisionUserReportFileService.getOne(new LambdaQueryWrapper<SupervisionUserReportFile>().eq(SupervisionUserReportFile::getId,userReportPO.getId()));
if(Objects.nonNull(supervisionUserReportFile)){
userReportVO.setCheckUrl(supervisionUserReportFile.getCheckUrl());
userReportVO.setAssessUrl(supervisionUserReportFile.getAssessUrl());
userReportVO.setOtherUrl(supervisionUserReportFile.getOtherUrl());
}
/* /*
根据用户性质获取自己特有的字段,此处需要特殊处理 根据用户性质获取自己特有的字段,此处需要特殊处理
1、每个附件需要返回文件名称以及可以预览的url 1、每个附件需要返回文件名称以及可以预览的url
@@ -287,6 +328,7 @@ public class UserLedgerServiceImpl extends ServiceImpl<UserReportPOMapper, UserR
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public String addUserReport(UserReportParam userReportParam) { public String addUserReport(UserReportParam userReportParam) {
UserReportPO userReportPO = new UserReportPO(); UserReportPO userReportPO = new UserReportPO();
BeanUtils.copyProperties(userReportParam, userReportPO); BeanUtils.copyProperties(userReportParam, userReportPO);
@@ -315,6 +357,27 @@ public class UserLedgerServiceImpl extends ServiceImpl<UserReportPOMapper, UserR
userReportPO.setDataType(0); userReportPO.setDataType(0);
} }
this.saveOrUpdate(userReportPO); this.saveOrUpdate(userReportPO);
//需要同步更新pq_line_detail 表里的obj_name字段
if(Objects.nonNull(userReportParam.getDataType()) && userReportParam.getDataType() == 1){
if(StrUtil.isNotBlank(userReportPO.getId())){
List<LineDetail> lineDetailList = lineDetailMapper.selectList(new LambdaQueryWrapper<LineDetail>().eq(LineDetail::getId, userReportPO.getId()));
if(CollUtil.isNotEmpty(lineDetailList)){
List<String> ids = lineDetailList.stream().map(LineDetail::getId).collect(Collectors.toList());
LineDetail lineDetail = new LineDetail();
lineDetail.setObjName(userReportPO.getProjectName());
lineDetailMapper.update(lineDetail,new LambdaUpdateWrapper<LineDetail>().in(LineDetail::getId,ids));
}
}
}
//处理需要上传的附件
SupervisionUserReportFile supervisionUserReportFile = new SupervisionUserReportFile();
supervisionUserReportFile.setId(userReportPO.getId());
supervisionUserReportFile.setCheckUrl(userReportParam.getCheckUrl());
supervisionUserReportFile.setAssessUrl(userReportParam.getAssessUrl());
supervisionUserReportFile.setOtherUrl(userReportParam.getOtherUrl());
supervisionUserReportFileService.saveOrUpdate(supervisionUserReportFile);
userReportPO = this.getById(userReportPO.getId()); userReportPO = this.getById(userReportPO.getId());
if ( if (
CollectionUtil.newArrayList( CollectionUtil.newArrayList(
@@ -383,6 +446,21 @@ public class UserLedgerServiceImpl extends ServiceImpl<UserReportPOMapper, UserR
return this.baseMapper.getUserReportById(userReportVOQueryWrapper); return this.baseMapper.getUserReportById(userReportVOQueryWrapper);
} }
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean userCheckUpload(TerminalCheckParam terminalCheckParam) {
SupervisionUserReportFile supervisionUserReportFile = new SupervisionUserReportFile();
supervisionUserReportFile.setId(terminalCheckParam.getObjId());
supervisionUserReportFile.setCheckUrl(terminalCheckParam.getCheckUrl());
supervisionUserReportFileService.saveOrUpdate(supervisionUserReportFile);
Device device = new Device();
device.setId(terminalCheckParam.getDevId());
device.setThisTimeCheck(terminalCheckParam.getThisCheckTime());
device.setNextTimeCheck(terminalCheckParam.getNextCheckTime());
deviceMapper.updateById(device);
return true;
}
/** /**
* 判断工程名称是否重复如果重复则提示用户XXX已经创建该工程 * 判断工程名称是否重复如果重复则提示用户XXX已经创建该工程
* *

View File

@@ -0,0 +1,59 @@
package com.njcn.device.utils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.device.line.mapper.LineMapper;
import com.njcn.device.pq.pojo.po.Line;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
* @Author: cdf
* @CreateTime: 2026-06-13
* @Description:
*/
@Component
@RequiredArgsConstructor
public class LineSortHelper {
private final LineMapper lineMapper;
/**
* 获取同一父节点下的最大 sort 值 + 1
* @param level 层级
* @return 下一个可用的 sort 值
*/
public Integer getNextSort(Integer level) {
LambdaQueryWrapper<Line> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Line::getState, DataStateEnum.ENABLE.getCode())
.eq(Line::getLevel,level)
.orderByDesc(Line::getSort)
.last("limit 1");
Line maxSortLine = lineMapper.selectOne(wrapper);
if (Objects.nonNull(maxSortLine) && Objects.nonNull(maxSortLine.getSort())) {
return maxSortLine.getSort() + 1;
}
return 0;
}
public void handleSort(Integer level, Integer sort,Line line) {
int lastSort;
if (Objects.isNull(sort) || sort == 0) {
lastSort = getNextSort(level);
}else {
lastSort = sort;
}
line.setSort(lastSort);
}
public Integer handleSortBatch(Integer currentSort, Line line) {
line.setSort(currentSort);
return currentSort + 1;
}
}

View File

@@ -6,9 +6,7 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
/** /**
* @author xxy * @author xxy
@@ -35,4 +33,7 @@ public class StatisticsParam implements Serializable {
@ApiModelProperty(name = "flag",value = "标识") @ApiModelProperty(name = "flag",value = "标识")
private Integer flag; private Integer flag;
@ApiModelProperty(name = "isDip",value = "是否只统计暂降")
private Boolean isDip;
} }

View File

@@ -76,7 +76,7 @@ public class AdvanceEventDetailVO {
private String sagsource; private String sagsource;
@ApiModelProperty(value = "开始时间") @ApiModelProperty(value = "开始时间")
@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss.SSS") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS",timezone = "GMT+8")
private LocalDateTime startTime; private LocalDateTime startTime;
@ApiModelProperty(value = "持续时间,单位秒") @ApiModelProperty(value = "持续时间,单位秒")

Some files were not shown because too many files have changed in this diff Show More