fix[project]: 导入仿真策划外部表单
This commit is contained in:
@@ -1,11 +1,16 @@
|
|||||||
package com.sdm.project.bo;
|
package com.sdm.project.bo;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.sdm.common.common.SdmResponse;
|
import com.sdm.common.common.SdmResponse;
|
||||||
import com.sdm.common.entity.req.project.SimulationPerformance;
|
import com.sdm.common.entity.req.project.SimulationPerformance;
|
||||||
import com.sdm.common.utils.SystemOperate;
|
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 lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@@ -24,7 +29,7 @@ public class ExportOperate {
|
|||||||
private String scriptPath;
|
private String scriptPath;
|
||||||
|
|
||||||
/** 临时导出路径 */
|
/** 临时导出路径 */
|
||||||
private static final String TEMP_EXPORT_PATH = "/opt/export/";
|
private static final String TEMP_EXPORT_PATH = "D:\\scripts\\";
|
||||||
|
|
||||||
/** Python脚本名称 */
|
/** Python脚本名称 */
|
||||||
private static final String PYTHON_INPUT_SCRIPT_NAME = "inputExcel.py";
|
private static final String PYTHON_INPUT_SCRIPT_NAME = "inputExcel.py";
|
||||||
@@ -32,8 +37,9 @@ public class ExportOperate {
|
|||||||
/** Python命令前缀 */
|
/** Python命令前缀 */
|
||||||
private static final String PYTHON_CMD_PREFIX = "python ";
|
private static final String PYTHON_CMD_PREFIX = "python ";
|
||||||
|
|
||||||
/** 脚本执行参数:固定值1 */
|
/** 脚本执行参数:1(一维导入) 2(二维导入) */
|
||||||
private static final String SCRIPT_FIXED_PARAM = "1";
|
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_SAVE_COLUMN = "保存指标字段信息失败";
|
||||||
private static final String ERROR_SCRIPT_EXECUTE = "解析指标文件脚本执行错误";
|
private static final String ERROR_SCRIPT_EXECUTE = "解析指标文件脚本执行错误";
|
||||||
@@ -149,7 +155,7 @@ public class ExportOperate {
|
|||||||
// 构建Python执行命令
|
// 构建Python执行命令
|
||||||
String shellPath = scriptPath + File.separator + PYTHON_INPUT_SCRIPT_NAME;
|
String shellPath = scriptPath + File.separator + PYTHON_INPUT_SCRIPT_NAME;
|
||||||
String pythonCmd = String.format("%s%s %s %s %s %s",
|
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);
|
log.info("开始执行Python脚本,命令:{}", pythonCmd);
|
||||||
long startTime = System.currentTimeMillis();
|
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文件
|
* 解析脚本输出的JSON文件
|
||||||
* @param jsonFile 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 待删除的文件路径列表
|
* @param filePaths 待删除的文件路径列表
|
||||||
@@ -328,5 +393,56 @@ public class ExportOperate {
|
|||||||
// return response;
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.apache.ibatis.annotations.Param;
|
|||||||
import org.springframework.util.DigestUtils;
|
import org.springframework.util.DigestUtils;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -117,4 +118,16 @@ public class SimulationProjectController implements ISimulationProjectFeignClien
|
|||||||
return projectService.getWorkspaceReportList(req);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.sdm.project.model.po;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ExportExternalForm {
|
||||||
|
List<NodeAllBase> nodes;
|
||||||
|
}
|
||||||
@@ -231,4 +231,10 @@ public class NodeAllBase extends BaseEntity {
|
|||||||
@JsonProperty(value = "eMemberList")
|
@JsonProperty(value = "eMemberList")
|
||||||
private List<CIDUserResp> eMemberList;
|
private List<CIDUserResp> eMemberList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 3D负责人
|
||||||
|
*/
|
||||||
|
@JsonProperty(value = "tMemberList")
|
||||||
|
private List<CIDUserResp> tMemberList;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,4 +113,6 @@ public interface ITaskService {
|
|||||||
|
|
||||||
SdmResponse mergeQueryNode(SpdmMergeQueryNodeReq req);
|
SdmResponse mergeQueryNode(SpdmMergeQueryNodeReq req);
|
||||||
|
|
||||||
|
SdmResponse importSimulationExternalForm(MultipartFile file, String columns);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5129,6 +5129,12 @@ public class TaskServiceImpl implements ITaskService {
|
|||||||
return SdmResponse.success(mergeQueryRespList.stream().sorted(Comparator.comparing(NodeMergeQueryResp::getName)).toList());
|
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) {
|
public static String getMaxNonEmptyTagForTask(SimulationTask req) {
|
||||||
// 空对象校验
|
// 空对象校验
|
||||||
|
|||||||
Reference in New Issue
Block a user