From ff156a1864fd4809583b4bc0d82ea1c396063322 Mon Sep 17 00:00:00 2001 From: lidongyang <506508008@qq.com> Date: Fri, 20 Mar 2026 07:09:06 +0800 Subject: [PATCH] =?UTF-8?q?fix[project]:=20=E5=AF=BC=E5=85=A5=E4=BB=BF?= =?UTF-8?q?=E7=9C=9F=E7=AD=96=E5=88=92=E5=A4=96=E9=83=A8=E8=A1=A8=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sdm/project/bo/ExportOperate.java | 124 +++++++++++++++++- .../SimulationProjectController.java | 13 ++ .../project/model/po/ExportExternalForm.java | 10 ++ .../com/sdm/project/model/po/NodeAllBase.java | 6 + .../com/sdm/project/service/ITaskService.java | 2 + .../project/service/impl/TaskServiceImpl.java | 6 + 6 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 project/src/main/java/com/sdm/project/model/po/ExportExternalForm.java diff --git a/project/src/main/java/com/sdm/project/bo/ExportOperate.java b/project/src/main/java/com/sdm/project/bo/ExportOperate.java index fba9e7b7..34e00d9b 100644 --- a/project/src/main/java/com/sdm/project/bo/ExportOperate.java +++ b/project/src/main/java/com/sdm/project/bo/ExportOperate.java @@ -1,11 +1,16 @@ package com.sdm.project.bo; +import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; import com.sdm.common.common.SdmResponse; import com.sdm.common.entity.req.project.SimulationPerformance; import com.sdm.common.utils.SystemOperate; +import com.sdm.project.model.po.ExportExternalForm; +import com.sdm.project.model.po.NodeAllBase; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; @@ -24,7 +29,7 @@ public class ExportOperate { private String scriptPath; /** 临时导出路径 */ - private static final String TEMP_EXPORT_PATH = "/opt/export/"; + private static final String TEMP_EXPORT_PATH = "D:\\scripts\\"; /** Python脚本名称 */ private static final String PYTHON_INPUT_SCRIPT_NAME = "inputExcel.py"; @@ -32,8 +37,9 @@ public class ExportOperate { /** Python命令前缀 */ private static final String PYTHON_CMD_PREFIX = "python "; - /** 脚本执行参数:固定值1 */ - private static final String SCRIPT_FIXED_PARAM = "1"; + /** 脚本执行参数:1(一维导入) 2(二维导入) */ + private static final String SCRIPT_ONE_DIMENSIONAL_FIXED_PARAM = "1"; + private static final String SCRIPT_TWO_DIMENSIONAL_FIXED_PARAM = "2"; private static final String ERROR_SAVE_COLUMN = "保存指标字段信息失败"; private static final String ERROR_SCRIPT_EXECUTE = "解析指标文件脚本执行错误"; @@ -149,7 +155,7 @@ public class ExportOperate { // 构建Python执行命令 String shellPath = scriptPath + File.separator + PYTHON_INPUT_SCRIPT_NAME; String pythonCmd = String.format("%s%s %s %s %s %s", - PYTHON_CMD_PREFIX, shellPath, jsonOutputFile, excelFile, columnFile, SCRIPT_FIXED_PARAM); + PYTHON_CMD_PREFIX, shellPath, jsonOutputFile, excelFile, columnFile, SCRIPT_ONE_DIMENSIONAL_FIXED_PARAM); log.info("开始执行Python脚本,命令:{}", pythonCmd); long startTime = System.currentTimeMillis(); @@ -175,6 +181,43 @@ public class ExportOperate { } } + /** + * 执行Python脚本解析Excel文件 + * @param jsonOutputFile 脚本输出的JSON文件路径 + * @param excelFile 待解析的Excel文件路径 + * @param columnFile 指标字段配置文件路径 + * @return 解析结果响应 + */ + private SdmResponse executeExternalFormPythonScript(String jsonOutputFile, String excelFile, String columnFile) { + // 构建Python执行命令 + String shellPath = scriptPath + File.separator + PYTHON_INPUT_SCRIPT_NAME; + String pythonCmd = String.format("%s%s %s %s %s %s", + PYTHON_CMD_PREFIX, shellPath, jsonOutputFile, excelFile, columnFile, SCRIPT_TWO_DIMENSIONAL_FIXED_PARAM); + + log.info("开始执行Python脚本,命令:{}", pythonCmd); + long startTime = System.currentTimeMillis(); + + try { + // 执行脚本 + String resultString = SystemOperate.exeShellCmd(pythonCmd); + long endTime = System.currentTimeMillis(); + + log.info("Python脚本执行完成,耗时:{}ms,执行结果:{}", (endTime - startTime), resultString); + + // 检查脚本执行结果 + if (resultString != null && resultString.contains("error")) { + log.error("Python脚本执行错误,返回信息:{}", resultString); + return SdmResponse.failed(ERROR_SCRIPT_EXECUTE); + } + + // 读取并解析JSON结果文件 + return parseExternalFormScriptOutput(jsonOutputFile); + } catch (Exception e) { + log.error("执行Python脚本异常", e); + return SdmResponse.failed(ERROR_SCRIPT_EXECUTE + ":" + e.getMessage()); + } + } + /** * 解析脚本输出的JSON文件 * @param jsonFile JSON文件路径 @@ -202,6 +245,28 @@ public class ExportOperate { } } + /** + * 解析脚本输出的JSON文件 + * @param jsonFile JSON文件路径 + * @return 解析结果响应 + */ + private SdmResponse parseExternalFormScriptOutput(String jsonFile) { + // 使用try-with-resources自动关闭流,无需手动close + try (InputStream inputStream = new FileInputStream(jsonFile)) { + byte[] jsonContents = inputStream.readAllBytes(); + String externalFormJsonString = new String(jsonContents, StandardCharsets.UTF_8); + log.info("读取JSON结果文件成功,内容长度:{}", externalFormJsonString.length()); + ExportExternalForm exportExternalForm = JSON.parseObject(externalFormJsonString, ExportExternalForm.class); + log.info("解析出的项目树为:{}", exportExternalForm); + SdmResponse response = SdmResponse.success(); + response.setData(exportExternalForm); + return response; + } catch (IOException e) { + log.error("读取JSON结果文件异常", e); + return SdmResponse.failed("读取解析结果文件失败:" + e.getMessage()); + } + } + /** * 清理临时文件 * @param filePaths 待删除的文件路径列表 @@ -328,5 +393,56 @@ public class ExportOperate { // return response; // } + /** + * 解析仿真策划的外部表单 + * @param externalFormFile 外部表单Excel文件 + * @param columns 外部表单字段JSON字符串 + * @return 解析结果响应 + */ + public SdmResponse parseSimulationExternalForm(MultipartFile externalFormFile, String columns) { + // 1. 参数校验 + if (externalFormFile == null || externalFormFile.isEmpty()) { + log.warn("解析外部表单文件失败:文件为空"); + return SdmResponse.failed(ERROR_EMPTY_FILE); + } + if (columns == null || columns.trim().isEmpty()) { + log.warn("解析外部表单文件失败:外部表单字段信息为空"); + return SdmResponse.failed(ERROR_EMPTY_COLUMNS); + } + + SdmResponse response; + String externalmanceFileName = null; + String columnFileName = null; + String externalFormJsonFileName = null; + + try { + // 2. 上传外部表单文件 + externalmanceFileName = uploadMultipartFile(externalFormFile); + log.info("外部表单文件上传成功,文件名:{}", externalmanceFileName); + + // 3. 生成临时文件名称 + columnFileName = generateTempFileName("column.json"); + externalFormJsonFileName = generateTempFileName("externalForm.json"); + + // 4. 保存外部表单字段信息 + if (!saveContentsToFile(columns, columnFileName)) { + log.error("保存指标字段信息失败,文件路径:{}", columnFileName); + return SdmResponse.failed(ERROR_SAVE_COLUMN); + } + + // 5. 执行Python脚本解析文件 + response = executeExternalFormPythonScript(externalFormJsonFileName, externalmanceFileName, columnFileName); + } catch (Exception e) { + log.error("解析外部表单文件发生异常", e); + response = SdmResponse.failed(ERROR_PARSE_FILE + ":" + e.getMessage()); + } finally { + // 6. 清理临时文件 + // TODO 暂不清理,方便调试 +// cleanTempFiles(externalFormJsonFileName, externalmanceFileName, columnFileName); + } + + return response; + } + } diff --git a/project/src/main/java/com/sdm/project/controller/SimulationProjectController.java b/project/src/main/java/com/sdm/project/controller/SimulationProjectController.java index fef5307b..a796113b 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationProjectController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationProjectController.java @@ -22,6 +22,7 @@ import org.apache.ibatis.annotations.Param; import org.springframework.util.DigestUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.util.List; @@ -117,4 +118,16 @@ public class SimulationProjectController implements ISimulationProjectFeignClien return projectService.getWorkspaceReportList(req); } + /** + * 仿真策划导入外部表单 + * @param file + * @param columns + * @return + */ + @PostMapping(value = "/importSimulationExternalForm") + @ResponseBody + SdmResponse importSimulationExternalForm(@RequestParam("file") MultipartFile file, @RequestParam("columns")String columns) { + return taskService.importSimulationExternalForm(file,columns); + } + } diff --git a/project/src/main/java/com/sdm/project/model/po/ExportExternalForm.java b/project/src/main/java/com/sdm/project/model/po/ExportExternalForm.java new file mode 100644 index 00000000..98e0dab0 --- /dev/null +++ b/project/src/main/java/com/sdm/project/model/po/ExportExternalForm.java @@ -0,0 +1,10 @@ +package com.sdm.project.model.po; + +import lombok.Data; + +import java.util.List; + +@Data +public class ExportExternalForm { + List nodes; +} diff --git a/project/src/main/java/com/sdm/project/model/po/NodeAllBase.java b/project/src/main/java/com/sdm/project/model/po/NodeAllBase.java index 6860d144..9b977126 100644 --- a/project/src/main/java/com/sdm/project/model/po/NodeAllBase.java +++ b/project/src/main/java/com/sdm/project/model/po/NodeAllBase.java @@ -231,4 +231,10 @@ public class NodeAllBase extends BaseEntity { @JsonProperty(value = "eMemberList") private List eMemberList; + /** + * 3D负责人 + */ + @JsonProperty(value = "tMemberList") + private List tMemberList; + } diff --git a/project/src/main/java/com/sdm/project/service/ITaskService.java b/project/src/main/java/com/sdm/project/service/ITaskService.java index 271aab7f..9c2301c5 100644 --- a/project/src/main/java/com/sdm/project/service/ITaskService.java +++ b/project/src/main/java/com/sdm/project/service/ITaskService.java @@ -113,4 +113,6 @@ public interface ITaskService { SdmResponse mergeQueryNode(SpdmMergeQueryNodeReq req); + SdmResponse importSimulationExternalForm(MultipartFile file, String columns); + } diff --git a/project/src/main/java/com/sdm/project/service/impl/TaskServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/TaskServiceImpl.java index bd5635cc..00cf0250 100644 --- a/project/src/main/java/com/sdm/project/service/impl/TaskServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/TaskServiceImpl.java @@ -5129,6 +5129,12 @@ public class TaskServiceImpl implements ITaskService { return SdmResponse.success(mergeQueryRespList.stream().sorted(Comparator.comparing(NodeMergeQueryResp::getName)).toList()); } + @Override + public SdmResponse importSimulationExternalForm(MultipartFile file, String columns) { + // 通过脚本解析导入的指标excel文件 + return exportOperate.parseSimulationExternalForm(file,columns); + } + public static String getMaxNonEmptyTagForTask(SimulationTask req) { // 空对象校验