feat(event): 添加暂态事件波形查看与导出功能
- 新增 getTransientEventWave 接口用于查看暂态事件波形 - 新增 exportTransientEventWaves 接口用于批量导出暂态事件波形 - 添加 EventWaveExportParam 参数类支持波形导出 - 在 EventListMapper 中增加 selectTransientDetailsByIds 查询方法 - 更新事件列表查询参数支持毫秒级时间格式 - 移除事件描述模糊查询条件优化查询性能 - 添加波形导出相关的常量和工具类集成
This commit is contained in:
@@ -38,7 +38,6 @@ public class SteadyTrendFieldResolver {
|
||||
validateBasicParam(param);
|
||||
List<String> lineIds = normalizeTextList(param.getLineIds());
|
||||
List<String> indicatorCodes = normalizeTextList(param.getIndicatorCodes());
|
||||
List<String> requestPhases = normalizeUpperList(param.getPhases());
|
||||
List<String> statTypes = normalizeUpperList(param.getStatTypes());
|
||||
if (statTypes.isEmpty()) {
|
||||
statTypes.add("AVG");
|
||||
@@ -47,7 +46,7 @@ public class SteadyTrendFieldResolver {
|
||||
for (String lineId : lineIds) {
|
||||
for (String indicatorCode : indicatorCodes) {
|
||||
SteadyTrendIndicatorDefinitionBO indicator = requireIndicator(indicatorCode);
|
||||
List<String> phases = resolvePhases(indicator, requestPhases);
|
||||
List<String> phases = resolvePhases(indicator);
|
||||
for (String phase : phases) {
|
||||
for (String statType : statTypes) {
|
||||
validateStatType(indicator, statType);
|
||||
@@ -57,7 +56,7 @@ public class SteadyTrendFieldResolver {
|
||||
}
|
||||
}
|
||||
if (result.size() > MAX_SERIES_COUNT) {
|
||||
throw fail("趋势曲线数量不能超过 24 条,请缩小监测点、指标、相别或统计类型范围");
|
||||
throw fail("趋势曲线数量不能超过 24 条,请缩小监测点、指标或统计类型范围");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -165,23 +164,8 @@ public class SteadyTrendFieldResolver {
|
||||
return indicator;
|
||||
}
|
||||
|
||||
private List<String> resolvePhases(SteadyTrendIndicatorDefinitionBO indicator, List<String> requestPhases) {
|
||||
if (requestPhases.isEmpty()) {
|
||||
return new ArrayList<String>(indicator.getPhaseCodes());
|
||||
}
|
||||
List<String> result = new ArrayList<String>();
|
||||
for (String phase : requestPhases) {
|
||||
if (!"A".equals(phase) && !"B".equals(phase) && !"C".equals(phase) && !"T".equals(phase)) {
|
||||
throw fail("相别只能是 A、B、C、T");
|
||||
}
|
||||
if (indicator.getPhaseCodes().contains(phase) && !result.contains(phase)) {
|
||||
result.add(phase);
|
||||
}
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
throw fail("指标 " + indicator.getIndicatorCode() + " 不支持当前相别");
|
||||
}
|
||||
return result;
|
||||
private List<String> resolvePhases(SteadyTrendIndicatorDefinitionBO indicator) {
|
||||
return new ArrayList<String>(indicator.getPhaseCodes());
|
||||
}
|
||||
|
||||
private void validateStatType(SteadyTrendIndicatorDefinitionBO indicator, String statType) {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package com.njcn.gather.steady.datavie.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
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.steady.datavie.pojo.param.SteadyDataViewDetailParam;
|
||||
import com.njcn.gather.steady.datavie.pojo.param.SteadyDataViewQueryParam;
|
||||
import com.njcn.gather.steady.datavie.pojo.vo.SteadyDataViewTemplateVO;
|
||||
import com.njcn.gather.steady.datavie.pojo.vo.SteadyDataViewVO;
|
||||
import com.njcn.gather.steady.datavie.service.SteadyDataViewService;
|
||||
@@ -40,16 +38,6 @@ public class SteadyDataViewController extends BaseController {
|
||||
/** 稳态数据查看服务。 */
|
||||
private final SteadyDataViewService steadyDataViewService;
|
||||
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@ApiOperation("分页查询稳态数据")
|
||||
@PostMapping("/page")
|
||||
public HttpResult<Page<SteadyDataViewVO>> pageSteadyData(@RequestBody SteadyDataViewQueryParam param) {
|
||||
String methodDescribe = getMethodDescribe("pageSteadyData");
|
||||
LogUtil.njcnDebug(log, "{},开始分页查询稳态数据,param={}", methodDescribe, param);
|
||||
Page<SteadyDataViewVO> result = steadyDataViewService.pageSteadyData(param);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@ApiOperation("查询稳态数据详情")
|
||||
@PostMapping("/detail")
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.njcn.gather.steady.datavie.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.gather.steady.datavie.pojo.param.SteadyDataViewQueryParam;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
@@ -12,11 +10,6 @@ import java.util.Map;
|
||||
*/
|
||||
public interface SteadyDataViewMapper {
|
||||
|
||||
Page<Map<String, Object>> selectSteadyPage(Page<Map<String, Object>> page,
|
||||
@Param("tableName") String tableName,
|
||||
@Param("columns") List<String> columns,
|
||||
@Param("param") SteadyDataViewQueryParam param);
|
||||
|
||||
Map<String, Object> selectSteadyDetail(@Param("tableName") String tableName,
|
||||
@Param("columns") List<String> columns,
|
||||
@Param("lineId") String lineId,
|
||||
|
||||
@@ -3,39 +3,6 @@
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.gather.steady.datavie.mapper.SteadyDataViewMapper">
|
||||
|
||||
<sql id="SteadyDataWhere">
|
||||
<where>
|
||||
<if test="param.timeStart != null and param.timeStart != ''">
|
||||
AND TIMEID >= #{param.timeStart}
|
||||
</if>
|
||||
<if test="param.timeEnd != null and param.timeEnd != ''">
|
||||
AND TIMEID <= #{param.timeEnd}
|
||||
</if>
|
||||
<if test="param.phasicType != null and param.phasicType != ''">
|
||||
AND PHASIC_TYPE = #{param.phasicType}
|
||||
</if>
|
||||
<if test="param.qualityFlag != null">
|
||||
AND QUALITYFLAG = #{param.qualityFlag}
|
||||
</if>
|
||||
<if test="param.lineIds != null and param.lineIds.size() > 0">
|
||||
AND LINEID IN
|
||||
<foreach collection="param.lineIds" item="lineId" open="(" separator="," close=")">
|
||||
#{lineId}
|
||||
</foreach>
|
||||
</if>
|
||||
</where>
|
||||
</sql>
|
||||
|
||||
<select id="selectSteadyPage" resultType="java.util.LinkedHashMap">
|
||||
SELECT
|
||||
<foreach collection="columns" item="column" separator=",">
|
||||
`${column}`
|
||||
</foreach>
|
||||
FROM `${tableName}`
|
||||
<include refid="SteadyDataWhere"/>
|
||||
ORDER BY TIMEID DESC, LINEID ASC, PHASIC_TYPE ASC
|
||||
</select>
|
||||
|
||||
<select id="selectSteadyDetail" resultType="java.util.LinkedHashMap">
|
||||
SELECT
|
||||
<foreach collection="columns" item="column" separator=",">
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package com.njcn.gather.steady.datavie.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.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 稳态数据查看查询参数。
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel("稳态数据查看查询参数")
|
||||
public class SteadyDataViewQueryParam extends BaseParam {
|
||||
|
||||
@ApiModelProperty("表名,对应 add-data 模板表名")
|
||||
private String tableName;
|
||||
|
||||
@ApiModelProperty("时间开始,格式 yyyy-MM-dd HH:mm:ss")
|
||||
private String timeStart;
|
||||
|
||||
@ApiModelProperty("时间结束,格式 yyyy-MM-dd HH:mm:ss")
|
||||
private String timeEnd;
|
||||
|
||||
@ApiModelProperty("相别:A/B/C/T")
|
||||
private String phasicType;
|
||||
|
||||
@ApiModelProperty("质量标识")
|
||||
private Integer qualityFlag;
|
||||
|
||||
@ApiModelProperty("监测点 ID 列表")
|
||||
private List<String> lineIds = new ArrayList<String>();
|
||||
|
||||
@ApiModelProperty("工程名称关键字")
|
||||
private String engineeringName;
|
||||
|
||||
@ApiModelProperty("项目名称关键字")
|
||||
private String projectName;
|
||||
|
||||
@ApiModelProperty("设备名称关键字")
|
||||
private String equipmentName;
|
||||
|
||||
@ApiModelProperty("监测点名称关键字")
|
||||
private String lineName;
|
||||
}
|
||||
@@ -23,9 +23,6 @@ public class SteadyTrendQueryParam {
|
||||
@ApiModelProperty("统计类型:AVG/MAX/MIN/CP95")
|
||||
private List<String> statTypes = new ArrayList<String>();
|
||||
|
||||
@ApiModelProperty("相别:A/B/C/T")
|
||||
private List<String> phases = new ArrayList<String>();
|
||||
|
||||
@ApiModelProperty("开始时间,格式 yyyy-MM-dd HH:mm:ss")
|
||||
private String timeStart;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.njcn.gather.steady.datavie.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.gather.steady.datavie.pojo.param.SteadyDataViewDetailParam;
|
||||
import com.njcn.gather.steady.datavie.pojo.param.SteadyDataViewQueryParam;
|
||||
import com.njcn.gather.steady.datavie.pojo.vo.SteadyDataViewTemplateVO;
|
||||
import com.njcn.gather.steady.datavie.pojo.vo.SteadyDataViewVO;
|
||||
|
||||
@@ -13,8 +11,6 @@ import java.util.List;
|
||||
*/
|
||||
public interface SteadyDataViewService {
|
||||
|
||||
Page<SteadyDataViewVO> pageSteadyData(SteadyDataViewQueryParam param);
|
||||
|
||||
SteadyDataViewVO getSteadyDataDetail(SteadyDataViewDetailParam param);
|
||||
|
||||
List<SteadyDataViewTemplateVO> listTemplates();
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.njcn.gather.steady.datavie.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.steady.datavie.mapper.SteadyDataViewMapper;
|
||||
import com.njcn.gather.steady.datavie.pojo.param.SteadyDataViewDetailParam;
|
||||
import com.njcn.gather.steady.datavie.pojo.param.SteadyDataViewQueryParam;
|
||||
import com.njcn.gather.steady.datavie.pojo.vo.SteadyDataViewTemplateVO;
|
||||
import com.njcn.gather.steady.datavie.pojo.vo.SteadyDataViewVO;
|
||||
import com.njcn.gather.steady.datavie.service.SteadyDataViewService;
|
||||
@@ -13,12 +11,9 @@ import com.njcn.gather.tool.adddata.component.AddDataTableRegistry;
|
||||
import com.njcn.gather.tool.adddata.component.AddDataTemplateRegistry;
|
||||
import com.njcn.gather.tool.adddata.pojo.bo.AddDataTableDefinition;
|
||||
import com.njcn.gather.tool.adddata.pojo.vo.AddDataTemplateVO;
|
||||
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 lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
@@ -34,13 +29,10 @@ import java.util.Map;
|
||||
/**
|
||||
* 稳态数据查看服务实现。
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SteadyDataViewServiceImpl implements SteadyDataViewService {
|
||||
|
||||
private static final int LEDGER_LINE_QUERY_LIMIT = 1000;
|
||||
private static final int STEADY_LINE_ID_QUERY_LIMIT = 1000;
|
||||
private static final String DEFAULT_TABLE_NAME = "data_v";
|
||||
private static final String EMPTY_TEXT = "-";
|
||||
private static final DateTimeFormatter OUTPUT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
@@ -56,22 +48,6 @@ public class SteadyDataViewServiceImpl implements SteadyDataViewService {
|
||||
private final AddDataTableRegistry addDataTableRegistry;
|
||||
private final AddDataTemplateRegistry addDataTemplateRegistry;
|
||||
|
||||
@Override
|
||||
public Page<SteadyDataViewVO> pageSteadyData(SteadyDataViewQueryParam param) {
|
||||
SteadyDataViewQueryParam queryParam = normalizeQueryParam(param);
|
||||
AddDataTableDefinition definition = resolveTableDefinition(queryParam.getTableName());
|
||||
if (!resolveLineFilter(queryParam)) {
|
||||
return emptyPage(queryParam);
|
||||
}
|
||||
Page<Map<String, Object>> steadyPage = steadyDataViewMapper.selectSteadyPage(
|
||||
new Page<Map<String, Object>>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)),
|
||||
definition.getTableName(), definition.getColumns(), queryParam);
|
||||
List<SteadyDataViewVO> records = buildSteadyDataList(definition.getTableName(), definition.getColumns(), steadyPage.getRecords());
|
||||
Page<SteadyDataViewVO> resultPage = new Page<SteadyDataViewVO>(steadyPage.getCurrent(), steadyPage.getSize(), steadyPage.getTotal());
|
||||
resultPage.setRecords(records);
|
||||
return resultPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SteadyDataViewVO getSteadyDataDetail(SteadyDataViewDetailParam param) {
|
||||
if (param == null) {
|
||||
@@ -156,69 +132,6 @@ public class SteadyDataViewServiceImpl implements SteadyDataViewService {
|
||||
return vo;
|
||||
}
|
||||
|
||||
private SteadyDataViewQueryParam normalizeQueryParam(SteadyDataViewQueryParam param) {
|
||||
SteadyDataViewQueryParam queryParam = param == null ? new SteadyDataViewQueryParam() : param;
|
||||
queryParam.setTableName(normalizeTableName(queryParam.getTableName()));
|
||||
LocalDateTime startTime = parseDateTime(queryParam.getTimeStart());
|
||||
LocalDateTime endTime = parseDateTime(queryParam.getTimeEnd());
|
||||
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, "开始时间不能大于结束时间");
|
||||
}
|
||||
queryParam.setTimeStart(OUTPUT_FORMATTER.format(startTime));
|
||||
queryParam.setTimeEnd(OUTPUT_FORMATTER.format(endTime));
|
||||
queryParam.setPhasicType(normalizePhasicType(queryParam.getPhasicType()));
|
||||
validateQualityFlag(queryParam.getQualityFlag());
|
||||
queryParam.setEngineeringName(trimToNull(queryParam.getEngineeringName()));
|
||||
queryParam.setProjectName(trimToNull(queryParam.getProjectName()));
|
||||
queryParam.setEquipmentName(trimToNull(queryParam.getEquipmentName()));
|
||||
queryParam.setLineName(trimToNull(queryParam.getLineName()));
|
||||
List<String> lineIds = normalizeIds(queryParam.getLineIds());
|
||||
if (lineIds.size() > STEADY_LINE_ID_QUERY_LIMIT) {
|
||||
throw new BusinessException(CommonResponseEnum.FAIL, "监测点 ID 查询数量不能超过 1000 个");
|
||||
}
|
||||
queryParam.setLineIds(lineIds);
|
||||
return queryParam;
|
||||
}
|
||||
|
||||
private boolean resolveLineFilter(SteadyDataViewQueryParam 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<String> ledgerLineIds = addLedgerService.listLineIdsByPathQuery(linePathQueryParam);
|
||||
if (ledgerLineIds.size() > LEDGER_LINE_QUERY_LIMIT) {
|
||||
throw new BusinessException(CommonResponseEnum.FAIL, "台账检索匹配监测点过多,请缩小查询条件");
|
||||
}
|
||||
if (ledgerLineIds.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
List<String> explicitLineIds = normalizeIds(queryParam.getLineIds());
|
||||
if (explicitLineIds.isEmpty()) {
|
||||
queryParam.setLineIds(ledgerLineIds);
|
||||
return true;
|
||||
}
|
||||
List<String> intersectLineIds = new ArrayList<String>();
|
||||
for (String lineId : explicitLineIds) {
|
||||
if (ledgerLineIds.contains(lineId)) {
|
||||
intersectLineIds.add(lineId);
|
||||
}
|
||||
}
|
||||
queryParam.setLineIds(intersectLineIds);
|
||||
return !intersectLineIds.isEmpty();
|
||||
}
|
||||
|
||||
private AddDataTableDefinition resolveTableDefinition(String tableName) {
|
||||
try {
|
||||
return addDataTableRegistry.getDefinition(tableName);
|
||||
@@ -267,39 +180,6 @@ public class SteadyDataViewServiceImpl implements SteadyDataViewService {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
private void validateQualityFlag(Integer qualityFlag) {
|
||||
if (qualityFlag != null && qualityFlag != 0 && qualityFlag != 1) {
|
||||
throw new BusinessException(CommonResponseEnum.FAIL, "质量标识只能是 0 或 1");
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> normalizeIds(List<String> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<String> normalizedIds = new ArrayList<String>();
|
||||
for (String id : ids) {
|
||||
String normalizedId = trimToNull(id);
|
||||
if (normalizedId != null && !normalizedIds.contains(normalizedId)) {
|
||||
normalizedIds.add(normalizedId);
|
||||
}
|
||||
}
|
||||
return normalizedIds;
|
||||
}
|
||||
|
||||
private boolean hasLedgerKeyword(SteadyDataViewQueryParam queryParam) {
|
||||
return trimToNull(queryParam.getEngineeringName()) != null
|
||||
|| trimToNull(queryParam.getProjectName()) != null
|
||||
|| trimToNull(queryParam.getEquipmentName()) != null
|
||||
|| trimToNull(queryParam.getLineName()) != null;
|
||||
}
|
||||
|
||||
private Page<SteadyDataViewVO> emptyPage(SteadyDataViewQueryParam queryParam) {
|
||||
Page<SteadyDataViewVO> page = new Page<SteadyDataViewVO>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam), 0);
|
||||
page.setRecords(Collections.<SteadyDataViewVO>emptyList());
|
||||
return page;
|
||||
}
|
||||
|
||||
private List<String> resolveValueColumns(List<String> columns) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
for (String column : columns) {
|
||||
|
||||
@@ -183,7 +183,6 @@ public class SteadyDataViewTrendServiceImpl implements SteadyDataViewTrendServic
|
||||
target.setLineIds(copyList(source.getLineIds()));
|
||||
target.setIndicatorCodes(copyList(source.getIndicatorCodes()));
|
||||
target.setStatTypes(copyList(source.getStatTypes()));
|
||||
target.setPhases(copyList(source.getPhases()));
|
||||
target.setTimeStart(source.getTimeStart());
|
||||
target.setTimeEnd(source.getTimeEnd());
|
||||
target.setBucket(source.getBucket());
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
package com.njcn.gather.steady.datavie.component;
|
||||
|
||||
import com.njcn.gather.steady.datavie.config.SteadyInfluxDbProperties;
|
||||
import com.njcn.gather.steady.datavie.pojo.bo.SteadyTrendResolvedFieldBO;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* InfluxQL 查询语句生成测试。
|
||||
*/
|
||||
class SteadyInfluxQueryComponentTest {
|
||||
|
||||
@Test
|
||||
void shouldBuildBucketedTrendQueryWithRequiredTags() {
|
||||
SteadyInfluxQueryComponent component = new SteadyInfluxQueryComponent(new SteadyInfluxDbProperties());
|
||||
SteadyTrendResolvedFieldBO field = new SteadyTrendResolvedFieldBO();
|
||||
field.setMeasurement("data_v");
|
||||
field.setField("RMS_CP95");
|
||||
field.setLineId("line-001");
|
||||
field.setPhase("A");
|
||||
|
||||
String query = component.buildTrendQuery(field,
|
||||
LocalDateTime.of(2026, 5, 1, 0, 0, 0),
|
||||
LocalDateTime.of(2026, 5, 1, 1, 0, 0),
|
||||
"10m",
|
||||
1);
|
||||
|
||||
Assertions.assertEquals("SELECT mean(\"RMS_CP95\") AS \"value\" FROM \"data_v\" WHERE time >= '2026-05-01T00:00:00Z' AND time <= '2026-05-01T01:00:00Z' AND \"LINEID\" = 'line-001' AND \"PHASIC_TYPE\" = 'A' AND \"QUALITYFLAG\" = '1' GROUP BY time(10m) fill(none)", query);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldEscapeTagValuesInTrendQuery() {
|
||||
SteadyInfluxQueryComponent component = new SteadyInfluxQueryComponent(new SteadyInfluxDbProperties());
|
||||
SteadyTrendResolvedFieldBO field = new SteadyTrendResolvedFieldBO();
|
||||
field.setMeasurement("data_v");
|
||||
field.setField("RMS");
|
||||
field.setLineId("line'001");
|
||||
field.setPhase("A");
|
||||
|
||||
String query = component.buildTrendQuery(field,
|
||||
LocalDateTime.of(2026, 5, 1, 0, 0, 0),
|
||||
LocalDateTime.of(2026, 5, 1, 1, 0, 0),
|
||||
null,
|
||||
null);
|
||||
|
||||
Assertions.assertTrue(query.contains("\"LINEID\" = 'line\\'001'"));
|
||||
Assertions.assertFalse(query.contains("GROUP BY time"));
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 稳态趋势字段解析测试。
|
||||
@@ -26,31 +27,25 @@ class SteadyTrendFieldResolverTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveVoltageRmsAverageAndCp95Fields() {
|
||||
void shouldExpandAllCatalogPhasesWithoutRequestPhaseFilter() {
|
||||
SteadyTrendQueryParam param = new SteadyTrendQueryParam();
|
||||
param.setLineIds(Arrays.asList("line-001"));
|
||||
param.setIndicatorCodes(Arrays.asList("V_RMS"));
|
||||
param.setPhases(Arrays.asList("A"));
|
||||
param.setStatTypes(Arrays.asList("AVG", "CP95"));
|
||||
param.setStatTypes(Arrays.asList("AVG"));
|
||||
param.setTimeStart("2026-05-01 00:00:00");
|
||||
param.setTimeEnd("2026-05-01 01:00:00");
|
||||
|
||||
List<SteadyTrendResolvedFieldBO> fields = resolver.resolveFields(param);
|
||||
List<String> phases = fields.stream().map(SteadyTrendResolvedFieldBO::getPhase).collect(Collectors.toList());
|
||||
|
||||
Assertions.assertEquals(2, fields.size());
|
||||
Assertions.assertEquals("data_v", fields.get(0).getMeasurement());
|
||||
Assertions.assertEquals("RMS", fields.get(0).getField());
|
||||
Assertions.assertEquals("AVG", fields.get(0).getStatType());
|
||||
Assertions.assertEquals("RMS_CP95", fields.get(1).getField());
|
||||
Assertions.assertEquals("V", fields.get(1).getUnit());
|
||||
Assertions.assertEquals(Arrays.asList("A", "B", "C"), phases);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExpandLineVoltageTotalPhaseToThreeSeries() {
|
||||
void shouldExpandTotalPhaseIndicatorWithoutRequestPhaseFilter() {
|
||||
SteadyTrendQueryParam param = new SteadyTrendQueryParam();
|
||||
param.setLineIds(Arrays.asList("line-001"));
|
||||
param.setIndicatorCodes(Arrays.asList("V_LINE_RMS"));
|
||||
param.setPhases(Arrays.asList("T"));
|
||||
param.setStatTypes(Arrays.asList("AVG"));
|
||||
param.setTimeStart("2026-05-01 00:00:00");
|
||||
param.setTimeEnd("2026-05-01 01:00:00");
|
||||
@@ -58,10 +53,10 @@ class SteadyTrendFieldResolverTest {
|
||||
List<SteadyTrendResolvedFieldBO> fields = resolver.resolveFields(param);
|
||||
|
||||
Assertions.assertEquals(3, fields.size());
|
||||
Assertions.assertEquals("T", fields.get(0).getPhase());
|
||||
Assertions.assertEquals("RMSAB", fields.get(0).getField());
|
||||
Assertions.assertEquals("RMSBC", fields.get(1).getField());
|
||||
Assertions.assertEquals("RMSCA", fields.get(2).getField());
|
||||
Assertions.assertEquals("T", fields.get(0).getPhase());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -69,7 +64,6 @@ class SteadyTrendFieldResolverTest {
|
||||
SteadyTrendQueryParam param = new SteadyTrendQueryParam();
|
||||
param.setLineIds(Arrays.asList("line-001"));
|
||||
param.setIndicatorCodes(Arrays.asList("V_HARMONIC"));
|
||||
param.setPhases(Arrays.asList("A"));
|
||||
param.setStatTypes(Arrays.asList("AVG"));
|
||||
param.setTimeStart("2026-05-01 00:00:00");
|
||||
param.setTimeEnd("2026-05-01 01:00:00");
|
||||
@@ -80,11 +74,10 @@ class SteadyTrendFieldResolverTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveSelectedHarmonicOrdersOnly() {
|
||||
void shouldResolveSelectedHarmonicOrdersForAllCatalogPhases() {
|
||||
SteadyTrendQueryParam param = new SteadyTrendQueryParam();
|
||||
param.setLineIds(Arrays.asList("line-001"));
|
||||
param.setIndicatorCodes(Arrays.asList("V_HARMONIC"));
|
||||
param.setPhases(Arrays.asList("A"));
|
||||
param.setStatTypes(Arrays.asList("MAX"));
|
||||
param.setHarmonicOrders(Arrays.asList(3, 5));
|
||||
param.setTimeStart("2026-05-01 00:00:00");
|
||||
@@ -92,8 +85,11 @@ class SteadyTrendFieldResolverTest {
|
||||
|
||||
List<SteadyTrendResolvedFieldBO> fields = resolver.resolveFields(param);
|
||||
|
||||
Assertions.assertEquals(2, fields.size());
|
||||
Assertions.assertEquals(6, fields.size());
|
||||
Assertions.assertEquals("A", fields.get(0).getPhase());
|
||||
Assertions.assertEquals("V_3_MAX", fields.get(0).getField());
|
||||
Assertions.assertEquals("V_5_MAX", fields.get(1).getField());
|
||||
Assertions.assertEquals("B", fields.get(2).getPhase());
|
||||
Assertions.assertEquals("C", fields.get(4).getPhase());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.njcn.gather.steady.datavie.controller;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 稳态数据查看接口契约测试。
|
||||
*/
|
||||
class SteadyDataViewControllerTest {
|
||||
|
||||
@Test
|
||||
void shouldNotExposePageQueryEndpointMethod() {
|
||||
for (Method method : SteadyDataViewController.class.getDeclaredMethods()) {
|
||||
Assertions.assertNotEquals("pageSteadyData", method.getName(), "本功能不提供分页检索接口");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.njcn.gather.steady.datavie.pojo.param;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* 稳态趋势查询参数契约测试。
|
||||
*/
|
||||
class SteadyTrendQueryParamTest {
|
||||
|
||||
@Test
|
||||
void shouldNotExposePhaseFilterInTrendQueryParam() {
|
||||
for (Field field : SteadyTrendQueryParam.class.getDeclaredFields()) {
|
||||
Assertions.assertNotEquals("phases", field.getName(), "趋势检索请求不再携带相别条件");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.njcn.gather.steady.datavie.service.impl;
|
||||
|
||||
import com.njcn.gather.steady.datavie.component.SteadyTrendIndicatorCatalog;
|
||||
import com.njcn.gather.steady.datavie.pojo.vo.SteadyDataViewIndicatorNodeVO;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 稳态趋势指标服务测试。
|
||||
*/
|
||||
class SteadyDataViewIndicatorServiceImplTest {
|
||||
|
||||
@Test
|
||||
void shouldGroupIndicatorsByCategory() {
|
||||
SteadyDataViewIndicatorServiceImpl service = new SteadyDataViewIndicatorServiceImpl(new SteadyTrendIndicatorCatalog());
|
||||
|
||||
List<SteadyDataViewIndicatorNodeVO> tree = service.listIndicatorTree();
|
||||
|
||||
Assertions.assertEquals(5, tree.size());
|
||||
Assertions.assertEquals("VOLTAGE", tree.get(0).getGroupCode());
|
||||
Assertions.assertTrue(tree.get(0).getChildren().size() >= 2);
|
||||
Assertions.assertEquals("V_RMS", tree.get(0).getChildren().get(0).getIndicatorCode());
|
||||
Assertions.assertTrue(tree.get(0).getChildren().get(0).getSelectable());
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
package com.njcn.gather.steady.datavie.service.impl;
|
||||
|
||||
import com.njcn.gather.steady.datavie.component.SteadyInfluxQueryComponent;
|
||||
import com.njcn.gather.steady.datavie.component.SteadyTrendFieldResolver;
|
||||
import com.njcn.gather.steady.datavie.pojo.bo.SteadyTrendResolvedFieldBO;
|
||||
import com.njcn.gather.steady.datavie.pojo.param.SteadyTrendQueryParam;
|
||||
import com.njcn.gather.steady.datavie.pojo.vo.SteadyTrendPointVO;
|
||||
import com.njcn.gather.steady.datavie.pojo.vo.SteadyTrendQueryVO;
|
||||
import com.njcn.gather.steady.datavie.pojo.vo.SteadyTrendSummaryVO;
|
||||
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerLinePathVO;
|
||||
import com.njcn.gather.tool.addledger.service.AddLedgerService;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* 稳态趋势服务编排测试。
|
||||
*/
|
||||
class SteadyDataViewTrendServiceImplTest {
|
||||
|
||||
@Test
|
||||
void shouldBuildTrendQueryWithDefaultBucketAndLineName() {
|
||||
SteadyTrendFieldResolver fieldResolver = Mockito.mock(SteadyTrendFieldResolver.class);
|
||||
SteadyInfluxQueryComponent influxQueryComponent = Mockito.mock(SteadyInfluxQueryComponent.class);
|
||||
AddLedgerService addLedgerService = Mockito.mock(AddLedgerService.class);
|
||||
|
||||
SteadyTrendQueryParam param = new SteadyTrendQueryParam();
|
||||
param.setLineIds(Arrays.asList("line-001"));
|
||||
param.setIndicatorCodes(Arrays.asList("V_RMS"));
|
||||
param.setPhases(Arrays.asList("A"));
|
||||
param.setStatTypes(Arrays.asList("AVG"));
|
||||
param.setTimeStart("2026-05-01 00:00:00");
|
||||
param.setTimeEnd("2026-05-01 05:59:59");
|
||||
|
||||
SteadyTrendResolvedFieldBO field = new SteadyTrendResolvedFieldBO();
|
||||
field.setMeasurement("data_v");
|
||||
field.setField("RMS");
|
||||
field.setLineId("line-001");
|
||||
field.setIndicatorCode("V_RMS");
|
||||
field.setIndicatorName("相电压有效值");
|
||||
field.setSeriesName("相电压有效值");
|
||||
field.setPhase("A");
|
||||
field.setStatType("AVG");
|
||||
field.setUnit("V");
|
||||
field.setSeriesKey("line-001|V_RMS|A|AVG|RMS");
|
||||
|
||||
Mockito.when(fieldResolver.parseRequiredTime("2026-05-01 00:00:00", "开始时间不能为空"))
|
||||
.thenReturn(LocalDateTime.of(2026, 5, 1, 0, 0, 0));
|
||||
Mockito.when(fieldResolver.parseRequiredTime("2026-05-01 05:59:59", "结束时间不能为空"))
|
||||
.thenReturn(LocalDateTime.of(2026, 5, 1, 5, 59, 59));
|
||||
Mockito.when(fieldResolver.resolveFields(Mockito.any())).thenReturn(Collections.singletonList(field));
|
||||
Mockito.when(addLedgerService.listLinePathByLineIds(Collections.singletonList("line-001")))
|
||||
.thenReturn(Collections.singletonMap("line-001", buildLinePath("进线一")));
|
||||
Mockito.when(influxQueryComponent.queryTrendPoints(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.eq("1m"), Mockito.isNull()))
|
||||
.thenReturn(Collections.singletonList(new SteadyTrendPointVO("2026-05-01 00:00:00", new BigDecimal("1.2"))));
|
||||
|
||||
SteadyDataViewTrendServiceImpl service = new SteadyDataViewTrendServiceImpl(fieldResolver, influxQueryComponent, addLedgerService);
|
||||
SteadyTrendQueryVO result = service.queryTrend(param);
|
||||
|
||||
Assertions.assertEquals("1m", result.getBucket());
|
||||
Assertions.assertTrue(result.getSampled());
|
||||
Assertions.assertEquals("进线一", result.getSeries().get(0).getLineName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCalculateTrendSummaryFromSeriesPoints() {
|
||||
SteadyTrendFieldResolver fieldResolver = Mockito.mock(SteadyTrendFieldResolver.class);
|
||||
SteadyInfluxQueryComponent influxQueryComponent = Mockito.mock(SteadyInfluxQueryComponent.class);
|
||||
AddLedgerService addLedgerService = Mockito.mock(AddLedgerService.class);
|
||||
|
||||
SteadyTrendQueryParam param = new SteadyTrendQueryParam();
|
||||
param.setLineIds(Arrays.asList("line-001"));
|
||||
param.setIndicatorCodes(Arrays.asList("V_RMS"));
|
||||
param.setPhases(Arrays.asList("A"));
|
||||
param.setStatTypes(Arrays.asList("AVG"));
|
||||
param.setTimeStart("2026-05-01 00:00:00");
|
||||
param.setTimeEnd("2026-05-01 05:59:59");
|
||||
|
||||
SteadyTrendResolvedFieldBO field = new SteadyTrendResolvedFieldBO();
|
||||
field.setMeasurement("data_v");
|
||||
field.setField("RMS");
|
||||
field.setLineId("line-001");
|
||||
field.setIndicatorCode("V_RMS");
|
||||
field.setIndicatorName("相电压有效值");
|
||||
field.setSeriesName("相电压有效值");
|
||||
field.setPhase("A");
|
||||
field.setStatType("AVG");
|
||||
field.setUnit("V");
|
||||
field.setSeriesKey("line-001|V_RMS|A|AVG|RMS");
|
||||
|
||||
Mockito.when(fieldResolver.parseRequiredTime(Mockito.anyString(), Mockito.anyString()))
|
||||
.thenReturn(LocalDateTime.of(2026, 5, 1, 0, 0, 0))
|
||||
.thenReturn(LocalDateTime.of(2026, 5, 1, 5, 59, 59));
|
||||
Mockito.when(fieldResolver.resolveFields(param)).thenReturn(Collections.singletonList(field));
|
||||
Mockito.when(addLedgerService.listLinePathByLineIds(Collections.singletonList("line-001")))
|
||||
.thenReturn(Collections.<String, AddLedgerLinePathVO>emptyMap());
|
||||
Mockito.when(influxQueryComponent.queryTrendPoints(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.isNull(), Mockito.isNull()))
|
||||
.thenReturn(Arrays.asList(
|
||||
new SteadyTrendPointVO("2026-05-01 00:00:00", new BigDecimal("1")),
|
||||
new SteadyTrendPointVO("2026-05-01 01:00:00", new BigDecimal("3")),
|
||||
new SteadyTrendPointVO("2026-05-01 02:00:00", new BigDecimal("2"))
|
||||
));
|
||||
|
||||
SteadyDataViewTrendServiceImpl service = new SteadyDataViewTrendServiceImpl(fieldResolver, influxQueryComponent, addLedgerService);
|
||||
SteadyTrendSummaryVO summary = service.summarizeTrend(param);
|
||||
|
||||
Assertions.assertEquals(new BigDecimal("3"), summary.getItems().get(0).getMax());
|
||||
Assertions.assertEquals(new BigDecimal("1"), summary.getItems().get(0).getMin());
|
||||
Assertions.assertEquals(new BigDecimal("2.000000"), summary.getItems().get(0).getAvg());
|
||||
Assertions.assertEquals(new BigDecimal("3"), summary.getItems().get(0).getCp95());
|
||||
}
|
||||
|
||||
private AddLedgerLinePathVO buildLinePath(String lineName) {
|
||||
AddLedgerLinePathVO linePathVO = new AddLedgerLinePathVO();
|
||||
linePathVO.setLineName(lineName);
|
||||
return linePathVO;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user