feat(harmonic): 新增前置调试日志和事件统计功能

- 添加获取前置调试日志接口,支持按时间和关键词筛选
- 实现暂降原因和暂降类型统计数据查询功能
- 新增CsEventLogsVo和CsEventReasonAndTypeVo数据传输对象
- 优化事件查询逻辑,支持多等级告警筛选
- 修复设备交付服务中的空指针异常问题
- 移除设备使用状态修改的日志记录功能
- 更新事件用户服务中的前置信息显示逻辑
This commit is contained in:
xy
2026-06-13 11:33:31 +08:00
parent b2e9597839
commit ad7835f0db
14 changed files with 330 additions and 48 deletions

View File

@@ -26,6 +26,12 @@ public class EventStatisticParam extends BaseParam {
@ApiModelProperty("暂态事件类型 0:全部 1:暂降 2:中断 3:暂升")
private Integer eventType;
/**
* 告警等级
*/
@ApiModelProperty("告警等级(1:Ⅰ级 2:Ⅱ级 3:Ⅲ级 4:DEBUG 5:NORMAL 6:WARN 7:ERROR)")
private String level;
/**
* 安装位置
*/

View File

@@ -0,0 +1,60 @@
package com.njcn.csharmonic.pojo.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.njcn.db.bo.BaseEntity;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* @author hongawen
* @version 1.0.0
* @date 2023年09月20日 15:57
*/
@Data
@NoArgsConstructor
public class CsEventLogsVo {
/**
* id
*/
private String id;
/**
* 监测点id
*/
private String lineId;
/**
* 监测点名称
*/
private String lineName;
/**
* 装置id
*/
private String deviceId;
/**
* 装置名称
*/
private String deviceName;
/**
* 事件时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime startTime;
/**
* 事件描述
*/
private String event;
/**
* 事件等级
* 告警等级(1:Ⅰ级 2:Ⅱ级 3:Ⅲ级 4:DEBUG 5:NORMAL 6:WARN 7:ERROR)
*/
private Integer level;
}

View File

@@ -0,0 +1,44 @@
package com.njcn.csharmonic.pojo.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* @author hongawen
* @version 1.0.0
* @date 2023年09月20日 15:57
*/
@Data
@NoArgsConstructor
public class CsEventReasonAndTypeVo {
@ApiModelProperty(value = "暂降原因")
private List<EventReason> eventReason;
@ApiModelProperty(value = "暂降类型")
private List<EventType> eventType;
@Data
public static class EventReason implements Serializable {
@ApiModelProperty(value = "暂降原因id")
private String eventReasonId;
@ApiModelProperty(value = "个数")
private Integer eventReasonCount;
}
@Data
public static class EventType implements Serializable {
@ApiModelProperty(value = "暂降类型id")
private String eventTypeId;
@ApiModelProperty(value = "个数")
private Integer eventTypeCount;
}
}

View File

@@ -1,5 +1,6 @@
package com.njcn.csharmonic.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
@@ -13,6 +14,8 @@ import com.njcn.csharmonic.param.CsEventUserQueryParam;
import com.njcn.csharmonic.param.DataParam;
import com.njcn.csharmonic.pojo.param.EventStatisticParam;
import com.njcn.csharmonic.pojo.po.CsEventPO;
import com.njcn.csharmonic.pojo.vo.CsEventLogsVo;
import com.njcn.csharmonic.pojo.vo.CsEventReasonAndTypeVo;
import com.njcn.csharmonic.pojo.vo.CsEventVO;
import com.njcn.csharmonic.pojo.vo.EventDetailVO;
import com.njcn.csharmonic.service.CsEventPOService;
@@ -198,5 +201,23 @@ public class CsEventController extends BaseController {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/getFrontDebugLogs")
@ApiOperation("获取前置调试日志")
@ApiImplicitParam(name = "param", value = "param", required = true)
public HttpResult<IPage<CsEventLogsVo>> getEventByIdList(@RequestBody EventStatisticParam param) {
String methodDescribe = getMethodDescribe("getEventByIdList");
IPage<CsEventLogsVo> result = csEventPOService.getFrontDebugLogs(param);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/eventReasonAndTypeStatistics")
@ApiOperation("暂降原因和暂降类型统计")
@ApiImplicitParam(name = "param", value = "param", required = true)
public HttpResult<CsEventReasonAndTypeVo> eventReasonAndTypeStatistics(@RequestBody EventStatisticParam param) {
String methodDescribe = getMethodDescribe("eventReasonAndTypeStatistics");
CsEventReasonAndTypeVo result = csEventPOService.eventReasonAndTypeStatistics(param);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
}

View File

@@ -2,6 +2,7 @@ package com.njcn.csharmonic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.csharmonic.pojo.po.CsEventPO;
import com.njcn.csharmonic.pojo.vo.CsEventReasonAndTypeVo;
import com.njcn.csharmonic.pojo.vo.CsWarnDescVO;
import org.apache.ibatis.annotations.Param;
@@ -17,4 +18,9 @@ import java.util.List;
*/
public interface CsEventPOMapper extends BaseMapper<CsEventPO> {
List<CsWarnDescVO> getEventDesc(@Param("lineIdList")List<String> lineIdList, @Param("count")int count);
List<CsEventReasonAndTypeVo.EventReason> getReasonStatistics(@Param("begin") String begin, @Param("end") String end, @Param("otherId") String otherId);
List<CsEventReasonAndTypeVo.EventType> getTypeStatistics(@Param("begin") String begin, @Param("end") String end, @Param("otherId") String otherId);
}

View File

@@ -42,4 +42,28 @@
LIMIT 60
</select>
<select id="getReasonStatistics" resultType="com.njcn.csharmonic.pojo.vo.CsEventReasonAndTypeVo$EventReason">
SELECT
IF(advance_reason IS NULL OR advance_reason = '', #{otherId}, advance_reason) AS eventReasonId,
COUNT(*) AS eventReasonCount
FROM cs_event
WHERE type = 0
AND tag = 'Evt_Sys_DipStr'
AND start_time BETWEEN #{begin} AND #{end}
GROUP BY IF(advance_reason IS NULL OR advance_reason = '', #{otherId}, advance_reason)
ORDER BY eventReasonCount DESC
</select>
<select id="getTypeStatistics" resultType="com.njcn.csharmonic.pojo.vo.CsEventReasonAndTypeVo$EventType">
SELECT
IF(advance_type IS NULL OR advance_type = '', #{otherId}, advance_type) AS eventTypeId,
COUNT(*) AS eventTypeCount
FROM cs_event
WHERE type = 0
AND tag = 'Evt_Sys_DipStr'
AND start_time BETWEEN #{begin} AND #{end}
GROUP BY IF(advance_type IS NULL OR advance_type = '', #{otherId}, advance_type)
ORDER BY eventTypeCount DESC
</select>
</mapper>

View File

@@ -224,7 +224,12 @@
AND b.severity &lt; #{csEventUserQueryPage.severityMax}
</if>
<if test="csEventUserQueryPage!=null and csEventUserQueryPage.searchValue != null and csEventUserQueryPage.searchValue !=''">
AND d.name like concat('%',#{csEventUserQueryPage.searchValue},'%')
<if test="csEventUserQueryPage.type != null and csEventUserQueryPage.type !='' and csEventUserQueryPage.type == 3 ">
AND e.name like concat('%',#{csEventUserQueryPage.searchValue},'%')
</if>
<if test="csEventUserQueryPage.type != null and csEventUserQueryPage.type !='' and csEventUserQueryPage.type != 3 ">
AND d.name like concat('%',#{csEventUserQueryPage.searchValue},'%')
</if>
</if>
<if test="csEventUserQueryPage!=null and csEventUserQueryPage.fileFlag != null">
<if test="csEventUserQueryPage!=null and csEventUserQueryPage.fileFlag == 0 ">

View File

@@ -1,14 +1,13 @@
package com.njcn.csharmonic.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.csdevice.pojo.vo.DataGroupEventVO;
import com.njcn.csharmonic.param.*;
import com.njcn.csharmonic.pojo.param.EventStatisticParam;
import com.njcn.csharmonic.pojo.po.CsEventPO;
import com.njcn.csharmonic.pojo.vo.CsEventVO;
import com.njcn.csharmonic.pojo.vo.CsWarnDescVO;
import com.njcn.csharmonic.pojo.vo.EventDetailVO;
import com.njcn.csharmonic.pojo.vo.*;
import com.njcn.event.file.pojo.dto.WaveDataDTO;
import javax.servlet.http.HttpServletResponse;
@@ -70,4 +69,8 @@ public interface CsEventPOService extends IService<CsEventPO>{
List<CsEventPO> getEvents(List<String> idList);
List<CsEventPO> getDevAlarmList(CsEventUserQueryParam param);
IPage<CsEventLogsVo> getFrontDebugLogs(EventStatisticParam param);
CsEventReasonAndTypeVo eventReasonAndTypeStatistics(EventStatisticParam param);
}

View File

@@ -9,8 +9,10 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.advance.api.EventCauseFeignClient;
@@ -19,6 +21,7 @@ import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.csdevice.api.CsLedgerFeignClient;
import com.njcn.csdevice.api.CsLineFeignClient;
import com.njcn.csdevice.enums.AlgorithmResponseEnum;
import com.njcn.csdevice.pojo.dto.CsLineDTO;
import com.njcn.csdevice.pojo.dto.DevDetailDTO;
import com.njcn.csdevice.pojo.po.CsLinePO;
import com.njcn.csdevice.pojo.vo.DataGroupEventVO;
@@ -28,9 +31,7 @@ import com.njcn.csharmonic.mapper.CsEventPOMapper;
import com.njcn.csharmonic.param.*;
import com.njcn.csharmonic.pojo.param.EventStatisticParam;
import com.njcn.csharmonic.pojo.po.CsEventPO;
import com.njcn.csharmonic.pojo.vo.CsEventVO;
import com.njcn.csharmonic.pojo.vo.CsWarnDescVO;
import com.njcn.csharmonic.pojo.vo.EventDetailVO;
import com.njcn.csharmonic.pojo.vo.*;
import com.njcn.csharmonic.service.CsEventPOService;
import com.njcn.csharmonic.service.CsEventUserPOService;
import com.njcn.csharmonic.utils.DataChangeUtil;
@@ -89,6 +90,7 @@ import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -124,6 +126,7 @@ public class CsEventPOServiceImpl extends ServiceImpl<CsEventPOMapper, CsEventPO
private final EventAnalysisService eventAnalysisService;
private final EventCauseFeignClient eventCauseFeignClient;
private final MsgSendFeignClient msgSendFeignClient;
private final CsEventPOMapper csEventPOMapper;
/** 两段数据间隔区域补null点数量可通过Nacos配置wave.gap.null.points调整 */
@Value("${wave.gap.null.points:5}")
private int waveGapNullPoints;
@@ -545,6 +548,8 @@ public class CsEventPOServiceImpl extends ServiceImpl<CsEventPOMapper, CsEventPO
.update();
//更新文件信息
updateEvent(param,id1,id2);
//生成移动端图片
this.getWavePics(event.getId(),2);
}
}
}
@@ -651,6 +656,112 @@ public class CsEventPOServiceImpl extends ServiceImpl<CsEventPOMapper, CsEventPO
return this.list(wrapper);
}
@Override
public IPage<CsEventLogsVo> getFrontDebugLogs(EventStatisticParam param) {
IPage<CsEventLogsVo> result = new Page<>(param.getPageNum(), param.getPageSize());
List<CsEventLogsVo> voRecords = new ArrayList<>();
IPage<CsEventPO> page = new Page<>(param.getPageNum(), param.getPageSize());
//获取所有监测点信息
List<CsLineDTO> lineList = csLineFeignClient.getAllLineDetail().getData();
if (CollectionUtil.isEmpty(lineList)) {
return result;
}
Map<String,List<CsLineDTO>> devMap = lineList.stream().collect(Collectors.groupingBy(CsLineDTO::getDeviceId));
Map<String, CsLineDTO> lineMap = lineList.stream().collect(Collectors.toMap(CsLineDTO::getLineId, Function.identity()));
List<String> lineIds = new ArrayList<>();
List<String> devIds = new ArrayList<>();
//根据关键字筛选(用户可能输入监测点名称或设备名称)
if (StringUtil.isNotBlank(param.getSearchValue())) {
String keyword = param.getSearchValue();
lineIds = lineList.stream()
.filter(item -> item.getName().contains(keyword))
.map(CsLineDTO::getLineId)
.distinct()
.collect(Collectors.toList());
devIds = lineList.stream()
.filter(item -> item.getDeviceName().contains(keyword))
.map(CsLineDTO::getDeviceId)
.distinct()
.collect(Collectors.toList());
//关键字筛选后没有任何匹配,返回空页
if (CollectionUtil.isEmpty(lineIds) && CollectionUtil.isEmpty(devIds)) {
return result;
}
}
LambdaQueryWrapper<CsEventPO> queryWrapper = new LambdaQueryWrapper<>();
//时间范围和类型是通用条件
queryWrapper
.between(CsEventPO::getStartTime,
DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())).toString(),
DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime())).toString())
.in(CsEventPO::getLevel, Arrays.asList(4, 5, 6, 7))
.eq(CsEventPO::getType, 3)
.orderByDesc(CsEventPO::getStartTime);
//关键字筛选:监测点名称 OR 设备名称
if (StringUtil.isNotBlank(param.getSearchValue())) {
List<String> finalLineIds = lineIds;
List<String> finalDevIds = devIds;
queryWrapper.and(i -> {
if (CollUtil.isNotEmpty(finalLineIds)) {
i.in(CsEventPO::getLineId, finalLineIds);
}
if (CollUtil.isNotEmpty(finalDevIds)) {
i.or().in(CsEventPO::getDeviceId, finalDevIds);
}
});
}
//告警等级筛选
if (StringUtil.isNotBlank(param.getLevel())) {
List<Integer> levelList = Arrays.stream(param.getLevel().split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.map(Integer::parseInt)
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(levelList)) {
queryWrapper.in(CsEventPO::getLevel, levelList);
}
}
page = csEventPOMapper.selectPage(page, queryWrapper);
List<CsEventPO> records = page.getRecords();
if (CollUtil.isNotEmpty(records)) {
records.forEach(item->{
CsEventLogsVo vo = new CsEventLogsVo();
BeanUtils.copyProperties(item,vo);
if (!Objects.isNull(item.getLineId())) {
vo.setLineName(lineMap.get(item.getLineId()).getName());
}
if (!Objects.isNull(item.getDeviceId())) {
vo.setDeviceName(devMap.get(item.getDeviceId()).get(0).getName());
}
vo.setEvent(item.getTag());
voRecords.add(vo);
});
}
result.setRecords(voRecords);
result.setTotal(page.getTotal());
result.setSize(page.getSize());
result.setCurrent(page.getCurrent());
result.setPages(page.getPages());
return result;
}
@Override
public CsEventReasonAndTypeVo eventReasonAndTypeStatistics(EventStatisticParam param) {
CsEventReasonAndTypeVo vo = new CsEventReasonAndTypeVo();
String begin = DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())).toString();
String end = DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime())).toString();
DictData data1 = dicDataFeignClient.getDicDataByCode(DicDataEnum.RESON_REST.getCode()).getData();
DictData data2 = dicDataFeignClient.getDicDataByCode(DicDataEnum.TYPE_REST.getCode()).getData();
vo.setEventReason(csEventPOMapper.getReasonStatistics(begin, end, data1.getId()));
vo.setEventType(csEventPOMapper.getTypeStatistics(begin, end, data2.getId()));
return vo;
}
/**
* 获取该事件的严重度
*

View File

@@ -539,9 +539,10 @@ public class CsEventUserPOServiceImpl extends ServiceImpl<CsEventUserPOMapper, C
public Page<CsEventPO> getFrontWarnInfo(CldWarnParam baseParam) {
Page<CsEventPO> page = new Page<>(baseParam.getPageNum(), baseParam.getPageSize());
List<Node> nodeList = nodeFeignClient.nodeAllList().getData();
Map<String, Node> nodeMap = nodeList.stream().collect(Collectors.toMap(Node::getId, Function.identity()));
Map<String, Node> nodeMap = new HashMap<>();
if (CollectionUtil.isNotEmpty(nodeList)) {
nodeMap = nodeList.stream().collect(Collectors.toMap(Node::getId, Function.identity()));
if (ObjectUtil.isNotNull(baseParam.getSearchValue()) || StringUtil.isNotBlank(baseParam.getSearchValue())) {
nodeList = nodeList.stream().filter(item-> item.getName().contains(baseParam.getSearchValue()) || item.getIp().contains(baseParam.getSearchValue())).collect(Collectors.toList());
}
@@ -567,10 +568,20 @@ public class CsEventUserPOServiceImpl extends ServiceImpl<CsEventUserPOMapper, C
}
List<CsEventPO> records = page.getRecords();
if (CollUtil.isNotEmpty(records)) {
Map<String, Node> finalNodeMap = nodeMap;
page.getRecords().forEach(item->{
//这边将前置名称放进lineId字段将前置IP放进wavePath字段进程号使用clDid
item.setLineId(nodeMap.get(item.getDeviceId()).getName());
item.setWavePath(nodeMap.get(item.getDeviceId()).getIp());
Node node = finalNodeMap.get(item.getDeviceId());
item.setLineId(Objects.isNull(node) ? null : node.getName());
item.setWavePath(Objects.isNull(node) ? null : node.getIp());
//事件等级(1:Ⅰ级||ERROR 2:Ⅱ级||WARN 3:Ⅲ级||(DEBUG&&NORMAL))
if (item.getLevel() == 4 || item.getLevel() == 5) {
item.setLevel(3);
} else if (item.getLevel() == 6) {
item.setLevel(2);
} else if (item.getLevel() == 7) {
item.setLevel(1);
}
});
}
return page;