diff --git a/entrance/pom.xml b/entrance/pom.xml index f467996..eabe987 100644 --- a/entrance/pom.xml +++ b/entrance/pom.xml @@ -58,6 +58,11 @@ add-ledger 1.0.0 + + com.njcn.gather + event-list + 1.0.0 + diff --git a/event/event-list/pom.xml b/event/event-list/pom.xml new file mode 100644 index 0000000..0ddb213 --- /dev/null +++ b/event/event-list/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + com.njcn.gather + event + 1.0.0 + + + event-list + + + + com.njcn + njcn-common + 0.0.1 + + + + com.njcn + mybatis-plus + 0.0.1 + + + + com.njcn + spingboot2.3.12 + 2.3.12 + + + + com.njcn.gather + add-ledger + 1.0.0 + + + diff --git a/event/event-list/src/main/java/com/njcn/gather/event/eventlist/controller/EventListController.java b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/controller/EventListController.java new file mode 100644 index 0000000..a370836 --- /dev/null +++ b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/controller/EventListController.java @@ -0,0 +1,67 @@ +package com.njcn.gather.event.eventlist.controller; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.njcn.common.pojo.annotation.OperateInfo; +import com.njcn.common.pojo.constant.OperateType; +import com.njcn.common.pojo.enums.common.LogEnum; +import com.njcn.common.pojo.enums.response.CommonResponseEnum; +import com.njcn.common.pojo.response.HttpResult; +import com.njcn.common.utils.LogUtil; +import com.njcn.gather.event.eventlist.pojo.param.EventListQueryParam; +import com.njcn.gather.event.eventlist.pojo.vo.EventListVO; +import com.njcn.gather.event.eventlist.service.EventListService; +import com.njcn.web.controller.BaseController; +import com.njcn.web.utils.HttpResultUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 事件列表接口预留入口。 + */ +@Validated +@Slf4j +@Api(tags = "事件列表") +@RestController +@RequestMapping("/event/list") +@RequiredArgsConstructor +public class EventListController extends BaseController { + + /** 事件列表服务。 */ + private final EventListService eventListService; + + @OperateInfo(info = LogEnum.BUSINESS_COMMON) + @ApiOperation("分页查询暂态事件列表") + @PostMapping("/transient/page") + public HttpResult> pageTransientEvents(@RequestBody EventListQueryParam param) { + String methodDescribe = getMethodDescribe("pageTransientEvents"); + LogUtil.njcnDebug(log, "{},开始分页查询暂态事件列表,param={}", methodDescribe, param); + Page result = eventListService.pageTransientEvents(param); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); + } + + @OperateInfo(info = LogEnum.BUSINESS_COMMON) + @ApiOperation("查询暂态事件详情") + @GetMapping("/transient/{eventId}") + public HttpResult getTransientEventDetail(@PathVariable("eventId") String eventId) { + String methodDescribe = getMethodDescribe("getTransientEventDetail"); + LogUtil.njcnDebug(log, "{},开始查询暂态事件详情,eventId={}", methodDescribe, eventId); + EventListVO result = eventListService.getTransientEventDetail(eventId); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); + } + + @OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.DOWNLOAD) + @ApiOperation("导出暂态事件列表") + @PostMapping("/transient/export") + public void exportTransientEvents(@RequestBody EventListQueryParam param) { + eventListService.exportTransientEvents(param); + } +} diff --git a/event/event-list/src/main/java/com/njcn/gather/event/eventlist/mapper/EventListMapper.java b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/mapper/EventListMapper.java new file mode 100644 index 0000000..c3909fb --- /dev/null +++ b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/mapper/EventListMapper.java @@ -0,0 +1,21 @@ +package com.njcn.gather.event.eventlist.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.njcn.gather.event.eventlist.pojo.param.EventListQueryParam; +import com.njcn.gather.event.eventlist.pojo.po.MpEventDetailPO; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 暂态事件列表 Mapper。 + */ +public interface EventListMapper extends BaseMapper { + + Page selectTransientPage(Page page, @Param("param") EventListQueryParam param); + + List selectTransientExportList(@Param("param") EventListQueryParam param, @Param("limit") Integer limit); + + MpEventDetailPO selectTransientDetail(@Param("eventId") String eventId); +} diff --git a/event/event-list/src/main/java/com/njcn/gather/event/eventlist/mapper/mapping/EventListMapper.xml b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/mapper/mapping/EventListMapper.xml new file mode 100644 index 0000000..891bd90 --- /dev/null +++ b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/mapper/mapping/EventListMapper.xml @@ -0,0 +1,104 @@ + + + + + + event_id, + measurement_point_id, + start_time, + event_type, + advance_reason, + advance_type, + feature_amplitude, + duration, + eventass_index, + dq_time, + deal_time, + num, + file_flag, + deal_flag, + first_time, + first_type, + first_ms, + energy, + severity, + sagsource, + phase, + event_describe, + wave_path, + create_time, + transient_value, + verify_reason, + verify_reason_detail + + + + + + AND start_time >= #{param.startTimeStart} + + + AND start_time <= #{param.startTimeEnd} + + + AND event_type = #{param.eventType} + + + AND phase = #{param.phase} + + + AND event_describe LIKE CONCAT('%', #{param.eventDescribe}, '%') + + + AND duration >= #{param.durationMin} + + + AND duration <= #{param.durationMax} + + + AND feature_amplitude >= #{param.featureAmplitudeMin} + + + AND feature_amplitude <= #{param.featureAmplitudeMax} + + + AND file_flag = #{param.fileFlag} + + + AND deal_flag = #{param.dealFlag} + + + AND measurement_point_id IN + + #{lineId} + + + + + + + + + + + diff --git a/event/event-list/src/main/java/com/njcn/gather/event/eventlist/pojo/param/EventListQueryParam.java b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/pojo/param/EventListQueryParam.java new file mode 100644 index 0000000..cfb2f82 --- /dev/null +++ b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/pojo/param/EventListQueryParam.java @@ -0,0 +1,68 @@ +package com.njcn.gather.event.eventlist.pojo.param; + +import com.njcn.web.pojo.param.BaseParam; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * 暂态事件列表查询参数。 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel("暂态事件列表查询参数") +public class EventListQueryParam extends BaseParam { + + @ApiModelProperty("发生时刻开始,格式 yyyy-MM-dd HH:mm:ss") + private String startTimeStart; + + @ApiModelProperty("发生时刻结束,格式 yyyy-MM-dd HH:mm:ss") + private String startTimeEnd; + + @ApiModelProperty("事件类型") + private String eventType; + + @ApiModelProperty("相别") + private String phase; + + @ApiModelProperty("事件描述关键字") + private String eventDescribe; + + @ApiModelProperty("持续时间下限,单位秒") + private BigDecimal durationMin; + + @ApiModelProperty("持续时间上限,单位秒") + private BigDecimal durationMax; + + @ApiModelProperty("暂降/暂升幅值下限") + private BigDecimal featureAmplitudeMin; + + @ApiModelProperty("暂降/暂升幅值上限") + private BigDecimal featureAmplitudeMax; + + @ApiModelProperty("波形文件状态:0 未招,1 已招") + private Integer fileFlag; + + @ApiModelProperty("处理状态:0 未处理,1 已处理,2 已处理无结果,3 计算失败") + private Integer dealFlag; + + @ApiModelProperty("监测点 ID 列表") + private List lineIds = new ArrayList(); + + @ApiModelProperty("工程名称关键字") + private String engineeringName; + + @ApiModelProperty("项目名称关键字") + private String projectName; + + @ApiModelProperty("设备名称关键字") + private String equipmentName; + + @ApiModelProperty("监测点名称关键字") + private String lineName; +} diff --git a/event/event-list/src/main/java/com/njcn/gather/event/eventlist/pojo/po/MpEventDetailPO.java b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/pojo/po/MpEventDetailPO.java new file mode 100644 index 0000000..eaac035 --- /dev/null +++ b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/pojo/po/MpEventDetailPO.java @@ -0,0 +1,91 @@ +package com.njcn.gather.event.eventlist.pojo.po; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 暂态事件明细。 + */ +@Data +@TableName("r_mp_event_detail") +public class MpEventDetailPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId("event_id") + private String eventId; + + private String measurementPointId; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) + private LocalDateTime startTime; + + private String eventType; + + private String advanceReason; + + private String advanceType; + + private BigDecimal featureAmplitude; + + private BigDecimal duration; + + private String eventassIndex; + + private Double dqTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) + private LocalDateTime dealTime; + + private Integer num; + + private Integer fileFlag; + + private Integer dealFlag; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) + private LocalDateTime firstTime; + + private String firstType; + + private BigDecimal firstMs; + + private Double energy; + + private Double severity; + + private String sagsource; + + private String phase; + + private String eventDescribe; + + private String wavePath; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) + private LocalDateTime createTime; + + private Double transientValue; + + private String verifyReason; + + private String verifyReasonDetail; +} diff --git a/event/event-list/src/main/java/com/njcn/gather/event/eventlist/pojo/vo/EventListVO.java b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/pojo/vo/EventListVO.java new file mode 100644 index 0000000..f7f4fc0 --- /dev/null +++ b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/pojo/vo/EventListVO.java @@ -0,0 +1,72 @@ +package com.njcn.gather.event.eventlist.pojo.vo; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 暂态事件列表展示对象。 + */ +@Data +public class EventListVO implements Serializable { + + private static final long serialVersionUID = 1L; + + private String eventId; + + private String measurementPointId; + + private String eventType; + + @Excel(name = "设备名称", width = 25) + private String equipmentName; + + @Excel(name = "工程名称", width = 25) + private String engineeringName; + + @Excel(name = "项目名称", width = 25) + private String projectName; + + @Excel(name = "发生时刻", width = 25, exportFormat = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) + private LocalDateTime startTime; + + @Excel(name = "监测点名称", width = 25) + private String lineName; + + @Excel(name = "事件描述", width = 25) + private String eventDescribe; + + @Excel(name = "事件发生位置", width = 18) + private String sagsource; + + @Excel(name = "相别", width = 15) + private String phase; + + @Excel(name = "持续时间(s)", width = 18) + private BigDecimal duration; + + @Excel(name = "暂降/暂升幅值(%)", width = 20) + private BigDecimal featureAmplitude; + + private String wavePath; + + private Integer fileFlag; + + private Integer dealFlag; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) + private LocalDateTime createTime; +} diff --git a/event/event-list/src/main/java/com/njcn/gather/event/eventlist/service/EventListService.java b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/service/EventListService.java new file mode 100644 index 0000000..74267ba --- /dev/null +++ b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/service/EventListService.java @@ -0,0 +1,17 @@ +package com.njcn.gather.event.eventlist.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.njcn.gather.event.eventlist.pojo.param.EventListQueryParam; +import com.njcn.gather.event.eventlist.pojo.vo.EventListVO; + +/** + * 事件列表服务。 + */ +public interface EventListService { + + Page pageTransientEvents(EventListQueryParam param); + + EventListVO getTransientEventDetail(String eventId); + + void exportTransientEvents(EventListQueryParam param); +} diff --git a/event/event-list/src/main/java/com/njcn/gather/event/eventlist/service/impl/EventListServiceImpl.java b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/service/impl/EventListServiceImpl.java new file mode 100644 index 0000000..7446e82 --- /dev/null +++ b/event/event-list/src/main/java/com/njcn/gather/event/eventlist/service/impl/EventListServiceImpl.java @@ -0,0 +1,286 @@ +package com.njcn.gather.event.eventlist.service.impl; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.njcn.common.pojo.enums.response.CommonResponseEnum; +import com.njcn.common.pojo.exception.BusinessException; +import com.njcn.gather.event.eventlist.mapper.EventListMapper; +import com.njcn.gather.event.eventlist.pojo.param.EventListQueryParam; +import com.njcn.gather.event.eventlist.pojo.po.MpEventDetailPO; +import com.njcn.gather.event.eventlist.pojo.vo.EventListVO; +import com.njcn.gather.event.eventlist.service.EventListService; +import com.njcn.gather.tool.addledger.pojo.param.AddLedgerLinePathQueryParam; +import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerLinePathVO; +import com.njcn.gather.tool.addledger.service.AddLedgerService; +import com.njcn.web.factory.PageFactory; +import com.njcn.web.utils.ExcelUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * 事件列表服务实现。 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class EventListServiceImpl implements EventListService { + + private static final int LEDGER_LINE_QUERY_LIMIT = 1000; + private static final int EVENT_LINE_ID_QUERY_LIMIT = 1000; + private static final int EXPORT_LIMIT = 5000; + private static final String EMPTY_TEXT = "-"; + private static final DateTimeFormatter OUTPUT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + private static final DateTimeFormatter[] INPUT_FORMATTERS = new DateTimeFormatter[]{ + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"), + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"), + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"), + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS") + }; + + private final EventListMapper eventListMapper; + private final AddLedgerService addLedgerService; + + @Override + public Page pageTransientEvents(EventListQueryParam param) { + EventListQueryParam queryParam = normalizeQueryParam(param); + if (!resolveLineFilter(queryParam)) { + return emptyPage(queryParam); + } + Page eventPage = eventListMapper.selectTransientPage( + new Page(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), + queryParam); + List records = buildEventList(eventPage.getRecords()); + Page resultPage = new Page(eventPage.getCurrent(), eventPage.getSize(), eventPage.getTotal()); + resultPage.setRecords(records); + return resultPage; + } + + @Override + public EventListVO getTransientEventDetail(String eventId) { + String normalizedEventId = trimToNull(eventId); + if (normalizedEventId == null) { + throw new BusinessException(CommonResponseEnum.FAIL, "事件 ID 不能为空"); + } + MpEventDetailPO eventDetail = eventListMapper.selectTransientDetail(normalizedEventId); + if (eventDetail == null) { + throw new BusinessException(CommonResponseEnum.FAIL, "暂态事件不存在"); + } + List eventDetails = new ArrayList(); + eventDetails.add(eventDetail); + return buildEventList(eventDetails).get(0); + } + + @Override + public void exportTransientEvents(EventListQueryParam param) { + EventListQueryParam queryParam = normalizeQueryParam(param); + List exportRecords; + if (resolveLineFilter(queryParam)) { + List eventDetails = eventListMapper.selectTransientExportList(queryParam, EXPORT_LIMIT + 1); + if (eventDetails.size() > EXPORT_LIMIT) { + throw new BusinessException(CommonResponseEnum.FAIL, "导出数据超过 5000 条,请缩小查询条件"); + } + exportRecords = buildEventList(eventDetails); + } else { + exportRecords = Collections.emptyList(); + } + ExcelUtil.exportExcel("暂态事件列表.xlsx", "暂态事件列表", EventListVO.class, exportRecords); + } + + private List buildEventList(List eventDetails) { + if (eventDetails == null || eventDetails.isEmpty()) { + return Collections.emptyList(); + } + List lineIds = new ArrayList(); + for (MpEventDetailPO eventDetail : eventDetails) { + String lineId = trimToNull(eventDetail.getMeasurementPointId()); + if (lineId != null && !lineIds.contains(lineId)) { + lineIds.add(lineId); + } + } + Map linePathMap = addLedgerService.listLinePathByLineIds(lineIds); + List result = new ArrayList(); + for (MpEventDetailPO eventDetail : eventDetails) { + AddLedgerLinePathVO linePath = linePathMap.get(eventDetail.getMeasurementPointId()); + result.add(buildEventVO(eventDetail, linePath)); + } + return result; + } + + private EventListVO buildEventVO(MpEventDetailPO eventDetail, AddLedgerLinePathVO linePath) { + EventListVO vo = new EventListVO(); + vo.setEventId(eventDetail.getEventId()); + vo.setMeasurementPointId(eventDetail.getMeasurementPointId()); + vo.setEventType(eventDetail.getEventType()); + vo.setEquipmentName(linePath == null ? EMPTY_TEXT : defaultText(linePath.getEquipmentName())); + vo.setEngineeringName(linePath == null ? EMPTY_TEXT : defaultText(linePath.getEngineeringName())); + vo.setProjectName(linePath == null ? EMPTY_TEXT : defaultText(linePath.getProjectName())); + vo.setStartTime(eventDetail.getStartTime()); + vo.setLineName(linePath == null ? EMPTY_TEXT : defaultText(linePath.getLineName())); + vo.setEventDescribe(defaultText(eventDetail.getEventDescribe(), eventDetail.getEventType())); + vo.setSagsource(defaultText(eventDetail.getSagsource())); + vo.setPhase(defaultText(eventDetail.getPhase())); + vo.setDuration(eventDetail.getDuration()); + vo.setFeatureAmplitude(eventDetail.getFeatureAmplitude()); + vo.setWavePath(eventDetail.getWavePath()); + vo.setFileFlag(eventDetail.getFileFlag()); + vo.setDealFlag(eventDetail.getDealFlag()); + vo.setCreateTime(eventDetail.getCreateTime()); + return vo; + } + + private EventListQueryParam normalizeQueryParam(EventListQueryParam param) { + EventListQueryParam queryParam = param == null ? new EventListQueryParam() : param; + LocalDateTime startTime = parseDateTime(queryParam.getStartTimeStart()); + LocalDateTime endTime = parseDateTime(queryParam.getStartTimeEnd()); + if (startTime == null) { + LocalDateTime now = LocalDateTime.now(); + startTime = LocalDateTime.of(now.getYear(), now.getMonth(), 1, 0, 0, 0); + } + if (endTime == null) { + endTime = LocalDateTime.now(); + } + if (startTime.isAfter(endTime)) { + throw new BusinessException(CommonResponseEnum.FAIL, "开始时间不能大于结束时间"); + } + validateRange(queryParam.getDurationMin(), queryParam.getDurationMax(), "持续时间下限不能大于上限"); + validateRange(queryParam.getFeatureAmplitudeMin(), queryParam.getFeatureAmplitudeMax(), "幅值下限不能大于上限"); + validateFlag(queryParam.getFileFlag(), "波形文件状态只能是 0 或 1"); + validateDealFlag(queryParam.getDealFlag()); + queryParam.setStartTimeStart(OUTPUT_FORMATTER.format(startTime)); + queryParam.setStartTimeEnd(OUTPUT_FORMATTER.format(endTime)); + queryParam.setEventType(trimToNull(queryParam.getEventType())); + queryParam.setPhase(trimToNull(queryParam.getPhase())); + queryParam.setEventDescribe(trimToNull(queryParam.getEventDescribe())); + queryParam.setEngineeringName(trimToNull(queryParam.getEngineeringName())); + queryParam.setProjectName(trimToNull(queryParam.getProjectName())); + queryParam.setEquipmentName(trimToNull(queryParam.getEquipmentName())); + queryParam.setLineName(trimToNull(queryParam.getLineName())); + List lineIds = normalizeIds(queryParam.getLineIds()); + if (lineIds.size() > EVENT_LINE_ID_QUERY_LIMIT) { + throw new BusinessException(CommonResponseEnum.FAIL, "监测点 ID 查询数量不能超过 1000 个"); + } + queryParam.setLineIds(lineIds); + return queryParam; + } + + /** + * 台账关键字先转成测点 ID,避免在事件模块直接联查台账表。 + */ + private boolean resolveLineFilter(EventListQueryParam queryParam) { + if (!hasLedgerKeyword(queryParam)) { + return true; + } + AddLedgerLinePathQueryParam linePathQueryParam = new AddLedgerLinePathQueryParam(); + linePathQueryParam.setEngineeringName(queryParam.getEngineeringName()); + linePathQueryParam.setProjectName(queryParam.getProjectName()); + linePathQueryParam.setEquipmentName(queryParam.getEquipmentName()); + linePathQueryParam.setLineName(queryParam.getLineName()); + linePathQueryParam.setLimit(LEDGER_LINE_QUERY_LIMIT + 1); + List ledgerLineIds = addLedgerService.listLineIdsByPathQuery(linePathQueryParam); + if (ledgerLineIds.size() > LEDGER_LINE_QUERY_LIMIT) { + throw new BusinessException(CommonResponseEnum.FAIL, "台账检索匹配监测点过多,请缩小查询条件"); + } + if (ledgerLineIds.isEmpty()) { + return false; + } + List explicitLineIds = normalizeIds(queryParam.getLineIds()); + if (explicitLineIds.isEmpty()) { + queryParam.setLineIds(ledgerLineIds); + return true; + } + List intersectLineIds = new ArrayList(); + for (String lineId : explicitLineIds) { + if (ledgerLineIds.contains(lineId)) { + intersectLineIds.add(lineId); + } + } + queryParam.setLineIds(intersectLineIds); + return !intersectLineIds.isEmpty(); + } + + private Page emptyPage(EventListQueryParam queryParam) { + Page page = new Page(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam), 0); + page.setRecords(Collections.emptyList()); + return page; + } + + private LocalDateTime parseDateTime(String value) { + String text = trimToNull(value); + if (text == null) { + return null; + } + for (DateTimeFormatter formatter : INPUT_FORMATTERS) { + try { + return LocalDateTime.parse(text, formatter); + } catch (DateTimeParseException ignored) { + // 尝试下一个前端可能传入的时间格式。 + } + } + throw new BusinessException(CommonResponseEnum.FAIL, "时间格式不正确,仅支持 yyyy-MM-dd HH:mm:ss"); + } + + private List normalizeIds(List ids) { + if (ids == null || ids.isEmpty()) { + return Collections.emptyList(); + } + List normalizedIds = new ArrayList(); + for (String id : ids) { + String normalizedId = trimToNull(id); + if (normalizedId != null && !normalizedIds.contains(normalizedId)) { + normalizedIds.add(normalizedId); + } + } + return normalizedIds; + } + + private boolean hasLedgerKeyword(EventListQueryParam queryParam) { + return trimToNull(queryParam.getEngineeringName()) != null + || trimToNull(queryParam.getProjectName()) != null + || trimToNull(queryParam.getEquipmentName()) != null + || trimToNull(queryParam.getLineName()) != null; + } + + private void validateRange(BigDecimal min, BigDecimal max, String message) { + if (min != null && max != null && min.compareTo(max) > 0) { + throw new BusinessException(CommonResponseEnum.FAIL, message); + } + } + + private void validateFlag(Integer flag, String message) { + if (flag != null && flag != 0 && flag != 1) { + throw new BusinessException(CommonResponseEnum.FAIL, message); + } + } + + private void validateDealFlag(Integer dealFlag) { + if (dealFlag != null && (dealFlag < 0 || dealFlag > 3)) { + throw new BusinessException(CommonResponseEnum.FAIL, "处理状态只能是 0、1、2、3"); + } + } + + private String defaultText(String value) { + return defaultText(value, EMPTY_TEXT); + } + + private String defaultText(String value, String defaultValue) { + String text = trimToNull(value); + return text == null ? defaultValue : text; + } + + private String trimToNull(String value) { + if (value == null) { + return null; + } + String trimmed = value.trim(); + return trimmed.isEmpty() ? null : trimmed; + } +} diff --git a/event/event-list/src/main/resources/sql/event-list/event-list-index.sql b/event/event-list/src/main/resources/sql/event-list/event-list-index.sql new file mode 100644 index 0000000..d1074f5 --- /dev/null +++ b/event/event-list/src/main/resources/sql/event-list/event-list-index.sql @@ -0,0 +1,14 @@ +-- 暂态事件列表查询建议索引。 +-- 本脚本不自动执行,请按数据库现状审阅后单独执行。 + +CREATE INDEX idx_event_start_id +ON r_mp_event_detail (start_time, event_id); + +CREATE INDEX idx_event_mp_time_id +ON r_mp_event_detail (measurement_point_id, start_time, event_id); + +CREATE INDEX idx_event_type_time_id +ON r_mp_event_detail (event_type, start_time, event_id); + +CREATE INDEX idx_event_phase_time_id +ON r_mp_event_detail (phase, start_time, event_id); diff --git a/event/pom.xml b/event/pom.xml new file mode 100644 index 0000000..e4f3066 --- /dev/null +++ b/event/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + com.njcn.gather + CN_Tool + 1.0.0 + + + event + pom + + + event-list + + + + 8 + 8 + UTF-8 + + + diff --git a/pom.xml b/pom.xml index 0953afe..18b8fde 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ user detection tools + event diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLineMapper.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLineMapper.java index 7e8e3d7..8accb5b 100644 --- a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLineMapper.java +++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLineMapper.java @@ -1,7 +1,9 @@ package com.njcn.gather.tool.addledger.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.njcn.gather.tool.addledger.pojo.param.AddLedgerLinePathQueryParam; import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLinePO; +import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerLinePathVO; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -17,5 +19,9 @@ public interface AddLedgerLineMapper extends BaseMapper { @Param("lineNo") Integer lineNo, @Param("lineId") String lineId); + List selectLinePathByLineIds(@Param("lineIds") List lineIds); + + List selectLinePathByQuery(@Param("param") AddLedgerLinePathQueryParam param); + int softDeleteByIds(@Param("ids") List ids, @Param("updateBy") String updateBy); } diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLineMapper.xml b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLineMapper.xml index 4a2cc82..f00ac2a 100644 --- a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLineMapper.xml +++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLineMapper.xml @@ -25,6 +25,62 @@ + + + + UPDATE cs_line SET status = 0, diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerLinePathQueryParam.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerLinePathQueryParam.java new file mode 100644 index 0000000..49b1fd7 --- /dev/null +++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerLinePathQueryParam.java @@ -0,0 +1,26 @@ +package com.njcn.gather.tool.addledger.pojo.param; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 监测点台账链路检索参数。 + */ +@Data +public class AddLedgerLinePathQueryParam { + + @ApiModelProperty("工程名称关键字") + private String engineeringName; + + @ApiModelProperty("项目名称关键字") + private String projectName; + + @ApiModelProperty("设备名称关键字") + private String equipmentName; + + @ApiModelProperty("监测点名称关键字") + private String lineName; + + @ApiModelProperty("最大返回监测点数量") + private Integer limit; +} diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerLinePathVO.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerLinePathVO.java new file mode 100644 index 0000000..7ec9940 --- /dev/null +++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerLinePathVO.java @@ -0,0 +1,30 @@ +package com.njcn.gather.tool.addledger.pojo.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 监测点所属台账链路。 + */ +@Data +public class AddLedgerLinePathVO implements Serializable { + + private static final long serialVersionUID = 1L; + + private String engineeringId; + + private String engineeringName; + + private String projectId; + + private String projectName; + + private String equipmentId; + + private String equipmentName; + + private String lineId; + + private String lineName; +} diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/AddLedgerService.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/AddLedgerService.java index e78a643..e3ceb3c 100644 --- a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/AddLedgerService.java +++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/AddLedgerService.java @@ -2,12 +2,15 @@ package com.njcn.gather.tool.addledger.service; import com.njcn.gather.tool.addledger.pojo.param.AddLedgerEngineeringSaveParam; import com.njcn.gather.tool.addledger.pojo.param.AddLedgerEquipmentSaveParam; +import com.njcn.gather.tool.addledger.pojo.param.AddLedgerLinePathQueryParam; import com.njcn.gather.tool.addledger.pojo.param.AddLedgerLineSaveParam; import com.njcn.gather.tool.addledger.pojo.param.AddLedgerProjectSaveParam; import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerDetailVO; +import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerLinePathVO; import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerTreeNodeVO; import java.util.List; +import java.util.Map; /** * 数据台账服务。 @@ -28,5 +31,9 @@ public interface AddLedgerService { List availableLineNos(String deviceId, String lineId); + Map listLinePathByLineIds(List lineIds); + + List listLineIdsByPathQuery(AddLedgerLinePathQueryParam param); + boolean deleteNode(String id, Integer level); } diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/impl/AddLedgerServiceImpl.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/impl/AddLedgerServiceImpl.java index d5cb9f7..766f573 100644 --- a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/impl/AddLedgerServiceImpl.java +++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/impl/AddLedgerServiceImpl.java @@ -10,6 +10,7 @@ import com.njcn.gather.tool.addledger.mapper.AddLedgerProjectMapper; import com.njcn.gather.tool.addledger.pojo.constant.AddLedgerConst; import com.njcn.gather.tool.addledger.pojo.param.AddLedgerEngineeringSaveParam; import com.njcn.gather.tool.addledger.pojo.param.AddLedgerEquipmentSaveParam; +import com.njcn.gather.tool.addledger.pojo.param.AddLedgerLinePathQueryParam; import com.njcn.gather.tool.addledger.pojo.param.AddLedgerLineSaveParam; import com.njcn.gather.tool.addledger.pojo.param.AddLedgerProjectSaveParam; import com.njcn.gather.tool.addledger.pojo.po.AddLedgerEngineeringPO; @@ -18,6 +19,7 @@ import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLedgerPO; import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLinePO; import com.njcn.gather.tool.addledger.pojo.po.AddLedgerProjectPO; import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerDetailVO; +import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerLinePathVO; import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerTreeNodeVO; import com.njcn.gather.tool.addledger.service.AddLedgerService; import com.njcn.gather.tool.addledger.util.AddLedgerIdUtil; @@ -29,7 +31,10 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; /** * 数据台账服务实现。 @@ -38,6 +43,9 @@ import java.util.List; @RequiredArgsConstructor public class AddLedgerServiceImpl implements AddLedgerService { + private static final int DEFAULT_LINE_PATH_QUERY_LIMIT = 1000; + private static final int MAX_LINE_PATH_QUERY_LIMIT = 5000; + private final AddLedgerEngineeringMapper engineeringMapper; private final AddLedgerProjectMapper projectMapper; private final AddLedgerEquipmentMapper equipmentMapper; @@ -220,6 +228,43 @@ public class AddLedgerServiceImpl implements AddLedgerService { return AddLedgerLineNoUtil.resolveAvailableLineNos(usedLineNos, null); } + @Override + public Map listLinePathByLineIds(List lineIds) { + List normalizedLineIds = normalizeIds(lineIds); + if (normalizedLineIds.isEmpty()) { + return Collections.emptyMap(); + } + List linePaths = lineMapper.selectLinePathByLineIds(normalizedLineIds); + Map result = new LinkedHashMap(); + for (AddLedgerLinePathVO linePath : linePaths) { + if (linePath != null && !isBlank(linePath.getLineId())) { + result.put(linePath.getLineId(), linePath); + } + } + return result; + } + + @Override + public List listLineIdsByPathQuery(AddLedgerLinePathQueryParam param) { + if (!hasPathKeyword(param)) { + return Collections.emptyList(); + } + AddLedgerLinePathQueryParam queryParam = new AddLedgerLinePathQueryParam(); + queryParam.setEngineeringName(trimToNull(param.getEngineeringName())); + queryParam.setProjectName(trimToNull(param.getProjectName())); + queryParam.setEquipmentName(trimToNull(param.getEquipmentName())); + queryParam.setLineName(trimToNull(param.getLineName())); + queryParam.setLimit(normalizeLimit(param.getLimit())); + List linePaths = lineMapper.selectLinePathByQuery(queryParam); + List lineIds = new ArrayList(); + for (AddLedgerLinePathVO linePath : linePaths) { + if (linePath != null && !isBlank(linePath.getLineId())) { + lineIds.add(linePath.getLineId()); + } + } + return lineIds; + } + @Override @Transactional public boolean deleteNode(String id, Integer level) { @@ -487,6 +532,35 @@ public class AddLedgerServiceImpl implements AddLedgerService { return trimToNull(value) == null; } + private List normalizeIds(List ids) { + if (ids == null || ids.isEmpty()) { + return Collections.emptyList(); + } + List normalizedIds = new ArrayList(); + for (String id : ids) { + String normalizedId = trimToNull(id); + if (normalizedId != null && !normalizedIds.contains(normalizedId)) { + normalizedIds.add(normalizedId); + } + } + return normalizedIds; + } + + private boolean hasPathKeyword(AddLedgerLinePathQueryParam param) { + return param != null + && (trimToNull(param.getEngineeringName()) != null + || trimToNull(param.getProjectName()) != null + || trimToNull(param.getEquipmentName()) != null + || trimToNull(param.getLineName()) != null); + } + + private int normalizeLimit(Integer limit) { + if (limit == null || limit <= 0) { + return DEFAULT_LINE_PATH_QUERY_LIMIT; + } + return Math.min(limit, MAX_LINE_PATH_QUERY_LIMIT); + } + private String currentUserId() { try { String userId = RequestUtil.getUserId();