洪圣文你是大傻逼
This commit is contained in:
11
AGENTS.md
11
AGENTS.md
@@ -34,6 +34,17 @@ Java 源码位于 `src/main/java`,配置文件位于 `src/main/resources`,My
|
|||||||
## 代码风格与命名规范
|
## 代码风格与命名规范
|
||||||
保持现有 Java 风格:4 空格缩进、UTF-8 文件编码、基础包名使用 `com.njcn.gather`。命名沿用分层后缀,如 `*Controller`、`*Service`、`*ServiceImpl`、`*Mapper`、`*Param`、`*PO`、`*VO`。优先复用现有 Lombok 注解,如 `@Data`、`@RequiredArgsConstructor`、`@Slf4j`。Mapper XML 文件名应与接口名保持一致。业务代码中,关键流程、分支判断、状态流转或容易误解的节点需要补充简洁的中文注释,但不要添加无信息量的注释。
|
保持现有 Java 风格:4 空格缩进、UTF-8 文件编码、基础包名使用 `com.njcn.gather`。命名沿用分层后缀,如 `*Controller`、`*Service`、`*ServiceImpl`、`*Mapper`、`*Param`、`*PO`、`*VO`。优先复用现有 Lombok 注解,如 `@Data`、`@RequiredArgsConstructor`、`@Slf4j`。Mapper XML 文件名应与接口名保持一致。业务代码中,关键流程、分支判断、状态流转或容易误解的节点需要补充简洁的中文注释,但不要添加无信息量的注释。
|
||||||
|
|
||||||
|
## 数据与 SQL 约束
|
||||||
|
- 新增业务表的 DO 优先复用当前 `BaseDO` / 审计字段风格;除非表本身明确不需要逻辑删除,不要再引入另一套审计基类。
|
||||||
|
- 不要假设运行时存在自动数据库迁移;如果代码依赖新表、新字段或新索引,必须同步补齐对应 SQL 与文档说明。
|
||||||
|
- SQL 脚本应放在目标模块的 `src/main/resources/sql/...` 下,并保持可审阅、可单独执行、语义清晰。
|
||||||
|
- 变更缓存、日志、审计相关逻辑时,优先沿用现有机制,不要绕开现有登录上下文、缓存约定和审计字段填充方式。
|
||||||
|
|
||||||
|
## 注释与编码
|
||||||
|
- 新增或修改代码时,关键字段、关键分支、关键约束和非直观实现应补充简洁中文注释。
|
||||||
|
- 不要为了省事删除原有有效注释,也不要添加无信息量的注释。
|
||||||
|
- 写入中文内容时必须保持 UTF-8 编码,并自行检查中文显示是否正常;不要用“改成英文”规避乱码问题。
|
||||||
|
|
||||||
## 提交与合并请求规范
|
## 提交与合并请求规范
|
||||||
当前 `main` 分支尚无可参考的提交历史,仓库内也没有既有提交规范。建议使用“模块前缀 + 动词短句”的提交格式,例如 `user: 优化登录会话校验`、`system: 增加字典参数校验`。提交 PR 时应说明影响模块、配置或数据结构变更、人工验证步骤;若接口行为有变化,附上请求与响应示例。
|
当前 `main` 分支尚无可参考的提交历史,仓库内也没有既有提交规范。建议使用“模块前缀 + 动词短句”的提交格式,例如 `user: 优化登录会话校验`、`system: 增加字典参数校验`。提交 PR 时应说明影响模块、配置或数据结构变更、人工验证步骤;若接口行为有变化,附上请求与响应示例。
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ CN_Tool 是一个基于 Spring Boot 的多模块后端聚合工程,当前仓
|
|||||||
- 系统字典、日志、系统配置、注册资源管理
|
- 系统字典、日志、系统配置、注册资源管理
|
||||||
- WebSocket / Netty 通信基础设施
|
- WebSocket / Netty 通信基础设施
|
||||||
- 激活码与许可证能力
|
- 激活码与许可证能力
|
||||||
|
- 波形文本解析与查看数据组装能力
|
||||||
|
|
||||||
## 当前真实模块
|
## 当前真实模块
|
||||||
|
|
||||||
@@ -17,9 +18,10 @@ CN_Tool 是一个基于 Spring Boot 的多模块后端聚合工程,当前仓
|
|||||||
- `detection`
|
- `detection`
|
||||||
- `tools`
|
- `tools`
|
||||||
|
|
||||||
其中 `tools` 当前仅保留:
|
其中 `tools` 当前包含:
|
||||||
|
|
||||||
- `activate-tool`
|
- `activate-tool`
|
||||||
|
- `wave-tool`
|
||||||
|
|
||||||
## 启动入口
|
## 启动入口
|
||||||
|
|
||||||
@@ -27,7 +29,7 @@ CN_Tool 是一个基于 Spring Boot 的多模块后端聚合工程,当前仓
|
|||||||
|
|
||||||
- `entrance/src/main/java/com/njcn/gather/EntranceApplication.java`
|
- `entrance/src/main/java/com/njcn/gather/EntranceApplication.java`
|
||||||
|
|
||||||
`entrance` 模块聚合了 `system`、`user`、`detection`、`activate-tool`,是当前运行时主入口。
|
`entrance` 模块聚合了 `system`、`user`、`detection`、`activate-tool`、`wave-tool`,是当前运行时主入口。
|
||||||
|
|
||||||
## 技术基线
|
## 技术基线
|
||||||
|
|
||||||
@@ -72,6 +74,8 @@ P0 已补齐基线文档,建议按以下顺序阅读:
|
|||||||
- 当前以通信基础设施为主,包含 WebSocket / Netty 相关组件
|
- 当前以通信基础设施为主,包含 WebSocket / Netty 相关组件
|
||||||
- `tools/activate-tool`
|
- `tools/activate-tool`
|
||||||
- 负责激活码生成、激活码验证、许可证读取等能力
|
- 负责激活码生成、激活码验证、许可证读取等能力
|
||||||
|
- `tools/wave-tool`
|
||||||
|
- 负责波形文本解析与查看数据组装能力
|
||||||
|
|
||||||
## 文档使用规则
|
## 文档使用规则
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,11 @@
|
|||||||
<artifactId>activate-tool</artifactId>
|
<artifactId>activate-tool</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.njcn.gather</groupId>
|
||||||
|
<artifactId>wave-tool</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -4,17 +4,19 @@
|
|||||||
|
|
||||||
`tools` 当前是工具能力聚合模块,但在本仓库内已经完成一次收口。
|
`tools` 当前是工具能力聚合模块,但在本仓库内已经完成一次收口。
|
||||||
|
|
||||||
当前真实保留的子模块只有:
|
当前真实保留的子模块有:
|
||||||
|
|
||||||
- `activate-tool`
|
- `activate-tool`
|
||||||
|
- `wave-tool`
|
||||||
|
|
||||||
因此,`tools` 现阶段不是一个包含多个通用工具的完整工具市场,而是一个仅保留激活能力的聚合模块。
|
因此,`tools` 现阶段仍然是聚合模块,但当前已实际承载激活工具和波形查看工具两个子模块。
|
||||||
|
|
||||||
## 当前结构
|
## 当前结构
|
||||||
|
|
||||||
```text
|
```text
|
||||||
tools/
|
tools/
|
||||||
└── activate-tool/
|
├── activate-tool/
|
||||||
|
└── wave-tool/
|
||||||
```
|
```
|
||||||
|
|
||||||
## activate-tool 的职责
|
## activate-tool 的职责
|
||||||
@@ -28,6 +30,17 @@ tools/
|
|||||||
|
|
||||||
从接口层看,当前主要围绕 `/activate/*` 路径提供能力。
|
从接口层看,当前主要围绕 `/activate/*` 路径提供能力。
|
||||||
|
|
||||||
|
## wave-tool 的职责
|
||||||
|
|
||||||
|
`wave-tool` 当前提供的能力主要围绕波形文本解析与查看数据组装:
|
||||||
|
|
||||||
|
- 解析单列幅值波形文本
|
||||||
|
- 解析双列时间/幅值波形文本
|
||||||
|
- 统计点位范围、均值、点数等摘要信息
|
||||||
|
- 按查看场景输出下采样后的点位集合
|
||||||
|
|
||||||
|
从接口层看,当前主要围绕 `/wave/*` 路径提供能力。
|
||||||
|
|
||||||
## 模块定位
|
## 模块定位
|
||||||
|
|
||||||
当前 `activate-tool` 更适合作为平台级基础能力模块,而不是业务检测模块的一部分。
|
当前 `activate-tool` 更适合作为平台级基础能力模块,而不是业务检测模块的一部分。
|
||||||
@@ -40,7 +53,7 @@ tools/
|
|||||||
|
|
||||||
## 依赖关系
|
## 依赖关系
|
||||||
|
|
||||||
`tools/activate-tool` 当前主要依赖:
|
`tools/activate-tool` 与 `tools/wave-tool` 当前主要依赖:
|
||||||
|
|
||||||
- `com.njcn:njcn-common`
|
- `com.njcn:njcn-common`
|
||||||
- `com.njcn:spingboot2.3.12`
|
- `com.njcn:spingboot2.3.12`
|
||||||
|
|||||||
@@ -16,9 +16,10 @@
|
|||||||
<description>Retained utility aggregator for platform capabilities.</description>
|
<description>Retained utility aggregator for platform capabilities.</description>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<!-- Key refactor point: business-side tool modules are removed, and only
|
<!-- Retain platform tools in the aggregator and add dedicated utility modules
|
||||||
the activation capability is retained in the tools aggregator. -->
|
here when they are actually introduced into this repository. -->
|
||||||
<module>activate-tool</module>
|
<module>activate-tool</module>
|
||||||
|
<module>wave-tool</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
28
tools/wave-tool/pom.xml
Normal file
28
tools/wave-tool/pom.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.njcn.gather</groupId>
|
||||||
|
<artifactId>tools</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>wave-tool</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.njcn</groupId>
|
||||||
|
<artifactId>njcn-common</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.njcn</groupId>
|
||||||
|
<artifactId>spingboot2.3.12</artifactId>
|
||||||
|
<version>2.3.12</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.njcn.gather.tool.wave.controller;
|
||||||
|
|
||||||
|
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.tool.wave.param.WaveParseParam;
|
||||||
|
import com.njcn.gather.tool.wave.service.WaveService;
|
||||||
|
import com.njcn.gather.tool.wave.vo.WaveParseResultVO;
|
||||||
|
import com.njcn.web.controller.BaseController;
|
||||||
|
import com.njcn.web.utils.HttpResultUtil;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Api(tags = "波形查看")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/wave")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class WaveController extends BaseController {
|
||||||
|
|
||||||
|
private final WaveService waveService;
|
||||||
|
|
||||||
|
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||||
|
@ApiOperation("解析波形文本")
|
||||||
|
@ApiImplicitParam(name = "param", value = "波形解析参数", required = true, dataType = "WaveParseParam")
|
||||||
|
@PostMapping("/parse")
|
||||||
|
public HttpResult<WaveParseResultVO> parse(@RequestBody WaveParseParam param) {
|
||||||
|
String methodDescribe = getMethodDescribe("parse");
|
||||||
|
LogUtil.njcnDebug(log, "{},开始解析波形文本", methodDescribe);
|
||||||
|
WaveParseResultVO result = waveService.parse(param);
|
||||||
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.njcn.gather.tool.wave.param;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ApiModel("波形解析参数")
|
||||||
|
public class WaveParseParam {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "波形文本内容,支持单列幅值、单行多值或双列时间/幅值数据", required = true)
|
||||||
|
private String waveformText;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分隔符,默认 AUTO 自动识别,支持直接传入具体字符,也支持 TAB 或 SPACE")
|
||||||
|
private String separator;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否包含 X 轴列,true 表示文本中显式传入时间列")
|
||||||
|
private Boolean containsXAxis;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "X 轴列下标,默认 0")
|
||||||
|
private Integer xColumnIndex;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "Y 轴列下标,单列波形默认 0,双列波形默认 1")
|
||||||
|
private Integer yColumnIndex;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "跳过的表头行数,默认 0")
|
||||||
|
private Integer skipHeaderLines;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "单列波形的采样间隔,默认 1")
|
||||||
|
private BigDecimal samplingInterval;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "返回的最大点位数,超过时自动下采样,默认 2000")
|
||||||
|
private Integer maxPointCount;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.njcn.gather.tool.wave.service;
|
||||||
|
|
||||||
|
import com.njcn.gather.tool.wave.param.WaveParseParam;
|
||||||
|
import com.njcn.gather.tool.wave.vo.WaveParseResultVO;
|
||||||
|
|
||||||
|
public interface WaveService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析波形文本并输出适合查看的点位结果。
|
||||||
|
*
|
||||||
|
* @param param 波形解析参数
|
||||||
|
* @return 波形查看结果
|
||||||
|
*/
|
||||||
|
WaveParseResultVO parse(WaveParseParam param);
|
||||||
|
}
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
package com.njcn.gather.tool.wave.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||||
|
import com.njcn.common.pojo.exception.BusinessException;
|
||||||
|
import com.njcn.gather.tool.wave.param.WaveParseParam;
|
||||||
|
import com.njcn.gather.tool.wave.service.WaveService;
|
||||||
|
import com.njcn.gather.tool.wave.vo.WaveParseResultVO;
|
||||||
|
import com.njcn.gather.tool.wave.vo.WavePointVO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class WaveServiceImpl implements WaveService {
|
||||||
|
|
||||||
|
private static final int DEFAULT_MAX_POINT_COUNT = 2000;
|
||||||
|
private static final String AUTO_SEPARATOR = "AUTO";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WaveParseResultVO parse(WaveParseParam param) {
|
||||||
|
if (param == null || StrUtil.isBlank(param.getWaveformText())) {
|
||||||
|
throw new BusinessException(CommonResponseEnum.FAIL, "波形文本不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean containsXAxis = Boolean.TRUE.equals(param.getContainsXAxis());
|
||||||
|
int skipHeaderLines = sanitizeSkipHeaderLines(param.getSkipHeaderLines());
|
||||||
|
int maxPointCount = sanitizeMaxPointCount(param.getMaxPointCount());
|
||||||
|
BigDecimal samplingInterval = sanitizeSamplingInterval(param.getSamplingInterval());
|
||||||
|
int xColumnIndex = sanitizeColumnIndex(param.getXColumnIndex(), 0);
|
||||||
|
int yColumnIndex = sanitizeColumnIndex(param.getYColumnIndex(), containsXAxis ? 1 : 0);
|
||||||
|
|
||||||
|
List<WavePointVO> sourcePoints = new ArrayList<>();
|
||||||
|
int ignoredLineCount = 0;
|
||||||
|
int nonBlankLineIndex = 0;
|
||||||
|
String[] lines = param.getWaveformText().split("\\r?\\n");
|
||||||
|
for (String line : lines) {
|
||||||
|
if (StrUtil.isBlank(line)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nonBlankLineIndex++ < skipHeaderLines) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String[] columns = splitColumns(line, param.getSeparator());
|
||||||
|
if (columns.length == 0) {
|
||||||
|
ignoredLineCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (containsXAxis) {
|
||||||
|
WavePointVO point = buildPoint(columns, xColumnIndex, yColumnIndex);
|
||||||
|
sourcePoints.add(point);
|
||||||
|
} else {
|
||||||
|
sourcePoints.addAll(buildSingleColumnPoints(columns, samplingInterval, sourcePoints.size()));
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ignoredLineCount++;
|
||||||
|
log.debug("波形行解析失败,line={}, reason={}", line, ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourcePoints.isEmpty()) {
|
||||||
|
throw new BusinessException(CommonResponseEnum.FAIL, "未解析到有效波形点位");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<WavePointVO> displayPoints = downSample(sourcePoints, maxPointCount);
|
||||||
|
return buildResult(sourcePoints, displayPoints, ignoredLineCount, containsXAxis);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WavePointVO buildPoint(String[] columns, int xColumnIndex, int yColumnIndex) {
|
||||||
|
BigDecimal yValue = parseNumber(readColumn(columns, yColumnIndex));
|
||||||
|
BigDecimal xValue = parseNumber(readColumn(columns, xColumnIndex));
|
||||||
|
return new WavePointVO(xValue, yValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<WavePointVO> buildSingleColumnPoints(String[] columns, BigDecimal samplingInterval, int startIndex) {
|
||||||
|
List<WavePointVO> points = new ArrayList<>();
|
||||||
|
for (int i = 0; i < columns.length; i++) {
|
||||||
|
BigDecimal yValue = parseNumber(columns[i]);
|
||||||
|
// 单列波形默认按采样间隔自动补齐 X 轴,便于前端直接绘制。
|
||||||
|
BigDecimal xValue = samplingInterval.multiply(BigDecimal.valueOf(startIndex + i));
|
||||||
|
points.add(new WavePointVO(xValue, yValue));
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readColumn(String[] columns, int columnIndex) {
|
||||||
|
if (columnIndex < 0 || columnIndex >= columns.length) {
|
||||||
|
throw new IllegalArgumentException("列下标超出范围");
|
||||||
|
}
|
||||||
|
return columns[columnIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal parseNumber(String value) {
|
||||||
|
if (StrUtil.isBlank(value)) {
|
||||||
|
throw new IllegalArgumentException("数值为空");
|
||||||
|
}
|
||||||
|
return new BigDecimal(value.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] splitColumns(String line, String separator) {
|
||||||
|
String trimmedLine = line.trim();
|
||||||
|
if (StrUtil.isBlank(trimmedLine)) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
String[] parts;
|
||||||
|
if (StrUtil.isBlank(separator) || AUTO_SEPARATOR.equalsIgnoreCase(separator)) {
|
||||||
|
parts = trimmedLine.split("[,;\\s]+");
|
||||||
|
} else if ("TAB".equalsIgnoreCase(separator)) {
|
||||||
|
parts = trimmedLine.split("\\t+");
|
||||||
|
} else if ("SPACE".equalsIgnoreCase(separator)) {
|
||||||
|
parts = trimmedLine.split("\\s+");
|
||||||
|
} else {
|
||||||
|
parts = trimmedLine.split(Pattern.quote(separator));
|
||||||
|
}
|
||||||
|
return Arrays.stream(parts)
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.toArray(String[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<WavePointVO> downSample(List<WavePointVO> sourcePoints, int maxPointCount) {
|
||||||
|
if (sourcePoints.size() <= maxPointCount) {
|
||||||
|
return sourcePoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<WavePointVO> result = new ArrayList<>();
|
||||||
|
int step = (int) Math.ceil((double) sourcePoints.size() / maxPointCount);
|
||||||
|
for (int i = 0; i < sourcePoints.size(); i += step) {
|
||||||
|
result.add(sourcePoints.get(i));
|
||||||
|
}
|
||||||
|
WavePointVO lastPoint = sourcePoints.get(sourcePoints.size() - 1);
|
||||||
|
if (!result.contains(lastPoint) && result.size() < maxPointCount) {
|
||||||
|
result.add(lastPoint);
|
||||||
|
} else if (!result.isEmpty()) {
|
||||||
|
result.set(result.size() - 1, lastPoint);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WaveParseResultVO buildResult(List<WavePointVO> sourcePoints, List<WavePointVO> displayPoints,
|
||||||
|
int ignoredLineCount, boolean containsXAxis) {
|
||||||
|
BigDecimal minX = sourcePoints.get(0).getX();
|
||||||
|
BigDecimal maxX = sourcePoints.get(0).getX();
|
||||||
|
BigDecimal minY = sourcePoints.get(0).getY();
|
||||||
|
BigDecimal maxY = sourcePoints.get(0).getY();
|
||||||
|
BigDecimal sumY = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
for (WavePointVO point : sourcePoints) {
|
||||||
|
if (point.getX().compareTo(minX) < 0) {
|
||||||
|
minX = point.getX();
|
||||||
|
}
|
||||||
|
if (point.getX().compareTo(maxX) > 0) {
|
||||||
|
maxX = point.getX();
|
||||||
|
}
|
||||||
|
if (point.getY().compareTo(minY) < 0) {
|
||||||
|
minY = point.getY();
|
||||||
|
}
|
||||||
|
if (point.getY().compareTo(maxY) > 0) {
|
||||||
|
maxY = point.getY();
|
||||||
|
}
|
||||||
|
sumY = sumY.add(point.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
WaveParseResultVO result = new WaveParseResultVO();
|
||||||
|
result.setContainsXAxis(containsXAxis);
|
||||||
|
result.setSourcePointCount(sourcePoints.size());
|
||||||
|
result.setDisplayPointCount(displayPoints.size());
|
||||||
|
result.setIgnoredLineCount(ignoredLineCount);
|
||||||
|
result.setSampled(sourcePoints.size() != displayPoints.size());
|
||||||
|
result.setMinX(minX);
|
||||||
|
result.setMaxX(maxX);
|
||||||
|
result.setMinY(minY);
|
||||||
|
result.setMaxY(maxY);
|
||||||
|
result.setAverageY(sumY.divide(BigDecimal.valueOf(sourcePoints.size()), 6, RoundingMode.HALF_UP));
|
||||||
|
result.setPoints(displayPoints);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int sanitizeSkipHeaderLines(Integer skipHeaderLines) {
|
||||||
|
if (skipHeaderLines == null || skipHeaderLines < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return skipHeaderLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int sanitizeMaxPointCount(Integer maxPointCount) {
|
||||||
|
if (maxPointCount == null || maxPointCount <= 0) {
|
||||||
|
return DEFAULT_MAX_POINT_COUNT;
|
||||||
|
}
|
||||||
|
return maxPointCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int sanitizeColumnIndex(Integer columnIndex, int defaultValue) {
|
||||||
|
if (columnIndex == null || columnIndex < 0) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return columnIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal sanitizeSamplingInterval(BigDecimal samplingInterval) {
|
||||||
|
if (samplingInterval == null || samplingInterval.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
return BigDecimal.ONE;
|
||||||
|
}
|
||||||
|
return samplingInterval;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.njcn.gather.tool.wave.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ApiModel("波形解析结果")
|
||||||
|
public class WaveParseResultVO {
|
||||||
|
|
||||||
|
@ApiModelProperty("是否包含显式 X 轴")
|
||||||
|
private Boolean containsXAxis;
|
||||||
|
|
||||||
|
@ApiModelProperty("原始有效点位数")
|
||||||
|
private Integer sourcePointCount;
|
||||||
|
|
||||||
|
@ApiModelProperty("返回的显示点位数")
|
||||||
|
private Integer displayPointCount;
|
||||||
|
|
||||||
|
@ApiModelProperty("被忽略的无效行数")
|
||||||
|
private Integer ignoredLineCount;
|
||||||
|
|
||||||
|
@ApiModelProperty("是否发生下采样")
|
||||||
|
private Boolean sampled;
|
||||||
|
|
||||||
|
@ApiModelProperty("X 轴最小值")
|
||||||
|
private BigDecimal minX;
|
||||||
|
|
||||||
|
@ApiModelProperty("X 轴最大值")
|
||||||
|
private BigDecimal maxX;
|
||||||
|
|
||||||
|
@ApiModelProperty("Y 轴最小值")
|
||||||
|
private BigDecimal minY;
|
||||||
|
|
||||||
|
@ApiModelProperty("Y 轴最大值")
|
||||||
|
private BigDecimal maxY;
|
||||||
|
|
||||||
|
@ApiModelProperty("Y 轴平均值")
|
||||||
|
private BigDecimal averageY;
|
||||||
|
|
||||||
|
@ApiModelProperty("用于查看的波形点位")
|
||||||
|
private List<WavePointVO> points;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.njcn.gather.tool.wave.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@ApiModel("波形点位")
|
||||||
|
public class WavePointVO {
|
||||||
|
|
||||||
|
@ApiModelProperty("X 轴值")
|
||||||
|
private BigDecimal x;
|
||||||
|
|
||||||
|
@ApiModelProperty("Y 轴值")
|
||||||
|
private BigDecimal y;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user