Merge remote-tracking branch 'origin/main'

This commit is contained in:
2025-12-03 17:39:56 +08:00
3 changed files with 172 additions and 2 deletions

View File

@@ -8,9 +8,9 @@ import java.util.Objects;
@Getter
public enum KeyResultTypeEnum {
IMAGE("图片/动画", 1, "图片结果"),
VALUE("数值", 2, "曲线结果"),
CURVE("曲线", 2, "曲线结果"),
DOCUMENT("报告", 3, "报告结果"),
CURVE("曲线", 4, "数值结果");
VALUE("数值", 4, "数值结果");
private final String name;
private final Integer keyResultType;

View File

@@ -0,0 +1,27 @@
package com.sdm.project.model.bo;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 从曲线结果提取的参数
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CurveParamDto {
@JsonProperty("max")
@Schema(description = "最大值")
private Double max;
@JsonProperty("min")
@Schema(description = "最小值")
private Double min;
@JsonProperty("unit")
@Schema(description = "单位")
private String unit;
}

View File

@@ -47,6 +47,7 @@ import com.sdm.project.common.TaskExeStatusEnum;
import com.sdm.project.dao.SimulationProjectMapper;
import com.sdm.project.dao.SimulationRunMapper;
import com.sdm.project.model.bo.ApprovalDeliverableContentsModel;
import com.sdm.project.model.bo.CurveParamDto;
import com.sdm.project.model.bo.TaskNode;
import com.sdm.project.model.bo.TaskNodeTag;
import com.sdm.project.model.entity.*;
@@ -71,8 +72,13 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.stream.Collectors;
@@ -125,8 +131,13 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
@Autowired
private DataAnalysisFeignClientImpl analysisFeignClient;
private final ObjectMapper objectMapper = new ObjectMapper();
private static final String TEMP_REPORT_PATH = "/opt/report/";
// 临时文件存储目录
private final String tempFileDir = System.getProperty("user.dir") + "/csv_uploads/";
private int getCurrentNodeDepth(NodeAllBase eachNode) {
String tag1 = eachNode.getTag1();
String tag2 = eachNode.getTag2();
@@ -732,6 +743,11 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
@Override
@Transactional(rollbackFor = Exception.class)
public SdmResponse addSimulationKeyResult(KeyResultReq req) {
if (KeyResultTypeEnum.CURVE.getKeyResultType().equals(req.getKeyResultType())) {
CurveParamDto curveParamDto = getCurveParamsFromUpload(req.getFile(), 2);
return SdmResponse.success(curveParamDto);
}
SimulationRunKeyResult simulationRunKeyResult = new SimulationRunKeyResult();
BeanUtils.copyProperties(req, simulationRunKeyResult);
simulationRunKeyResult.setUuid(RandomUtil.generateString(32));
@@ -759,6 +775,133 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
return SdmResponse.success(simulationRunKeyResult.getUuid());
}
/**
* 保存上传的文件到临时目录
*/
private String saveUploadedFile(MultipartFile file) throws IOException {
// 确保临时目录存在
Path uploadPath = Paths.get(tempFileDir);
if (!Files.exists(uploadPath)) {
Files.createDirectories(uploadPath);
}
// 生成唯一的文件名
String fileName = RandomUtil.generateString(16) + "_" + file.getOriginalFilename();
Path filePath = uploadPath.resolve(fileName);
// 保存文件
Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
log.info("文件已保存到临时目录: {}", filePath.toString());
return filePath.toString();
}
/**
* 清理临时文件
*/
private void cleanupTempFile(String filePath) {
try {
Path path = Paths.get(filePath);
if (Files.exists(path)) {
Files.delete(path);
log.info("临时文件已删除: {}", filePath);
}
} catch (IOException e) {
log.warn("删除临时文件失败: {}", filePath, e);
}
}
/**
* 执行 Python 脚本获取曲线参数(通过上传的文件)
*/
public CurveParamDto getCurveParamsFromUpload(MultipartFile file, Integer decimal) {
String tempFilePath = null;
try {
// 保存上传的文件到临时目录
tempFilePath = saveUploadedFile(file);
// 执行 Python 脚本
return executePythonScript(tempFilePath, decimal);
} catch (Exception e) {
log.error("处理上传文件时发生错误", e);
throw new RuntimeException("处理文件失败: " + e.getMessage());
} finally {
// 清理临时文件
if (tempFilePath != null) {
cleanupTempFile(tempFilePath);
}
}
}
/**
* 执行 Python 脚本
*/
private CurveParamDto executePythonScript(String filePath, Integer decimal) {
try {
String pythonInterpreter = "python";
// 构建 Python 脚本路径
// String projectRoot = System.getProperty("user.dir") + File.separator + "project";
// String pythonScriptPath = projectRoot + File.separator +"get_curve_params.py";
String pythonScriptPath = "/opt/script/get_curve_params.py";
// 构建命令参数
List<String> command = new ArrayList<>();
command.add(pythonInterpreter);
command.add(pythonScriptPath);
command.add(filePath);
if (decimal != null) {
command.add(decimal.toString());
}
String commands = String.join(" ", command);
log.info("执行 Python 命令: {}", commands);
// 执行命令
Process process = Runtime.getRuntime().exec(commands);
// 读取输出
StringBuilder output = new StringBuilder();
StringBuilder errors = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
// 读取标准输出
String line;
while ((line = reader.readLine()) != null) {
output.append(line);
log.info("Python输出: {}", line);
}
// 读取错误输出
while (errorReader.ready()) {
String errorLine = errorReader.readLine();
if (errorLine != null) {
errors.append(errorLine).append("\n");
log.error("Python错误: {}", errorLine);
}
}
}
// 等待进程结束
int exitCode = process.waitFor();
if (exitCode != 0) {
throw new RuntimeException("Python执行失败退出码: " + exitCode + "错误信息: " + errors.toString());
}
// 解析结果
if (!output.isEmpty()) {
log.info("Python返回JSON: {}", output.toString());
return objectMapper.readValue(output.toString(), CurveParamDto.class);
} else {
throw new RuntimeException("Python脚本没有输出");
}
} catch (IOException | InterruptedException e) {
log.error("执行Python脚本时发生错误", e);
throw new RuntimeException("执行Python脚本时发生错误: " + e.getMessage());
}
}
/**
* 重载方法,不指定小数位数
*/
public CurveParamDto getCurveParamsFromUpload(MultipartFile file) {
return getCurveParamsFromUpload(file, null);
}
@Override
@Transactional(rollbackFor = Exception.class)
public SdmResponse<List<BatchAddFileInfoResp>> batchAddSimulationKeyResult(KeyResultReq req) {