1、生成自动化脚本中使用动态模板

This commit is contained in:
2025-12-04 11:16:01 +08:00
parent a4c128106c
commit d919e7b793

View File

@@ -4,7 +4,6 @@ import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@@ -15,7 +14,6 @@ import com.sdm.common.entity.enums.ApproveTypeEnum;
import com.sdm.common.entity.enums.DirTypeEnum;
import com.sdm.common.entity.enums.NodeTypeEnum;
import com.sdm.common.entity.flowable.dto.FlowElementDTO;
import com.sdm.common.entity.flowable.dto.NodeStructureInfo;
import com.sdm.common.entity.flowable.dto.ProcessDefinitionDTO;
import com.sdm.common.entity.req.capability.FlowNodeDto;
import com.sdm.common.entity.req.data.*;
@@ -35,9 +33,6 @@ import com.sdm.common.feign.impl.data.DataClientFeignClientImpl;
import com.sdm.common.feign.impl.flowable.FlowableClientFeignClientImpl;
import com.sdm.common.feign.impl.system.ApproveFeignClientImpl;
import com.sdm.common.feign.impl.system.SysUserFeignClientImpl;
import com.sdm.common.feign.inter.capability.ISimulationFlowFeignClient;
import com.sdm.common.feign.inter.data.IDataFeignClient;
import com.sdm.common.feign.inter.flowable.IFlowableFeignClient;
import com.sdm.common.utils.PageUtils;
import com.sdm.common.utils.RandomUtil;
import com.sdm.project.common.KeyResultTypeEnum;
@@ -48,7 +43,6 @@ 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.*;
import com.sdm.project.model.po.NodeAllBase;
@@ -58,12 +52,8 @@ import com.sdm.project.model.po.TaskNodePo;
import com.sdm.project.model.req.*;
import com.sdm.project.model.resp.KeyResultAndTaskInfoResp;
import com.sdm.project.model.resp.RunVersionInfoResp;
import com.sdm.project.service.ISimulationPerformanceService;
import com.sdm.project.service.ISimulationRunService;
import com.sdm.project.service.ISimulationTaskMemberService;
import com.sdm.project.service.ISimulationTaskService;
import jakarta.servlet.http.HttpServletResponse;
import com.sdm.project.service.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
@@ -75,11 +65,11 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
@@ -136,7 +126,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
private static final String TEMP_REPORT_PATH = "/opt/report/";
private static final String TEMPLATE_PATH = " /opt/script/template staticsAnalyse";
private static final String TEMPLATE_PATH = " /opt/script/template ";
// 临时文件存储目录
private final String tempFileDir = System.getProperty("user.dir") + "/csv_uploads/";
@@ -564,7 +554,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
.eq(SimulationPerformance::getTaskId, simulationTask.getUuid())
.isNull(SimulationPerformance::getRunId)
.list();
if(CollectionUtils.isNotEmpty(simulationTaskPerformances)) {
if (CollectionUtils.isNotEmpty(simulationTaskPerformances)) {
List<SimulationPerformance> runPerformanceList = new ArrayList<>();
for (SimulationPerformance performanceBean : simulationTaskPerformances) {
SimulationPerformance runPerformance = new SimulationPerformance();
@@ -716,7 +706,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
BeanUtils.copyProperties(source, target);
return target;
}).collect(Collectors.toList());
return SdmResponse.success(buildRunTreeWithMap(runRespList));
return SdmResponse.success(buildRunTreeWithMap(runRespList));
}
return SdmResponse.success();
}
@@ -909,7 +899,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
@Transactional(rollbackFor = Exception.class)
public SdmResponse<List<BatchAddFileInfoResp>> batchAddSimulationKeyResult(KeyResultReq req) {
if (CollectionUtils.isNotEmpty(req.getKeyResultList())) {
UploadFilesReq filesReq = new UploadFilesReq();
UploadFilesReq filesReq = new UploadFilesReq();
BeanUtils.copyProperties(req, filesReq);
filesReq.setUuid(req.getTaskId());
filesReq.setSourceFiles(req.getKeyResultList().stream().map(i -> new UploadFilesReq(i.getFileName(), i.getFileSize(), i.getFileType())).toList());
@@ -949,7 +939,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
contentsModel.setTaskId(req.getTaskId());
contentsModel.setDifficult(req.getDifficult());
// 发起审批
String cidFlowId = launchParamApprove(req.getTemplateId(),req.getTemplateName(), JSONObject.toJSONString(contentsModel),1);
String cidFlowId = launchParamApprove(req.getTemplateId(), req.getTemplateName(), JSONObject.toJSONString(contentsModel), 1);
if (StringUtils.isEmpty(cidFlowId)) {
return SdmResponse.failed("发起评审失败");
}
@@ -962,17 +952,15 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
@Override
public SdmResponse deliverableApproveCallback(LaunchApproveReq req) {
SdmResponse response = SdmResponse.success();
SdmResponse response = SdmResponse.success();
int approveStatus = req.approveStatus;
String approveContent = req.approveContents;
JSONObject contentObj = JSONObject.parseObject(approveContent);
if(contentObj != null && contentObj.containsKey("taskId"))
{
if (contentObj != null && contentObj.containsKey("taskId")) {
String taskId = contentObj.getString("taskId");
Float difficult = contentObj.getFloat("difficult");
SimulationTask simulationTask = simulationTaskService.lambdaQuery().eq(SimulationTask::getUuid, taskId).one();
if(simulationTask != null)
{
if (simulationTask != null) {
// 审批通过 部署流程 保存部署流程部署id和流程定义id
if (NumberConstants.TWO == approveStatus) {
simulationTask.setDifficult(difficult);
@@ -985,7 +973,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
return response;
}
private String launchParamApprove(String templateId, String templateName,String approveContents,int approveAction) {
private String launchParamApprove(String templateId, String templateName, String approveContents, int approveAction) {
LaunchApproveReq req = new LaunchApproveReq();
req.templateId = templateId;
req.templateName = templateName;
@@ -996,9 +984,9 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
req.approveTitle = "交付物评审";
req.tenantId = ThreadLocalContext.getTenantId();
req.userId = ThreadLocalContext.getUserId();
req.creator = ThreadLocalContext.getUserId();
req.creator = ThreadLocalContext.getUserId();
SdmResponse response = approveFeignClient.launchApproval(req);
if(response.isSuccess()){
if (response.isSuccess()) {
// 成功
String cidFlowId = Optional.ofNullable(response.getData())
.map(Object::toString)
@@ -1050,7 +1038,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
// 删除结果
simulationKeyResultService.lambdaUpdate().eq(SimulationRunKeyResult::getUuid, req.getUuid()).remove();
// 删除文件
DelDirReq delDirReq = new DelDirReq();
DelDirReq delDirReq = new DelDirReq();
delDirReq.setDelDirId(req.getFileId());
log.info("删除关键结果调用删除文件夹的参数为:{}", req);
SdmResponse response = dataFeignClient.delDir(delDirReq);
@@ -1079,7 +1067,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
queryDirReq.setUuid(req.getRunId());
queryDirReq.setCurrent(1);
queryDirReq.setSize(10);
SdmResponse<PageDataResp<List<FileMetadataInfoResp>>> sdmResponse = queryRunDir(queryDirReq);
SdmResponse<PageDataResp<List<FileMetadataInfoResp>>> sdmResponse = queryRunDir(queryDirReq);
if (sdmResponse.getData() != null) {
List<FileMetadataInfoResp> fileMetadataInfoRespList = sdmResponse.getData().getData();
if (CollectionUtils.isNotEmpty(fileMetadataInfoRespList)) {
@@ -1093,112 +1081,111 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
@Override
public void generateReport(SpdmReportReq req, HttpServletResponse response) {
log.info("生成自动化报告参数为:{}",req);
log.info("生成自动化报告参数为:{}", req);
// 父节点信息
ProjecInfoReq projecInfoReq = req.getProjecInfoReq();
if (ObjectUtils.isEmpty(projecInfoReq) || StringUtils.isBlank(projecInfoReq.getLoadcaseName())) {
log.error("父节点信息不能为空");
return;
}
// 根据文件id下载文件到临时目录
List<Long> imageFileIdList = req.getImageFileIdList();
String randomId = RandomUtil.generateString(16);
if (CollectionUtils.isNotEmpty(imageFileIdList)) {
String randomId = RandomUtil.generateString(16);
log.info("临时路径为:{}" , randomId);
String commands = "python /opt/script/exportWord.py " + TEMP_REPORT_PATH + randomId + File.separator + TEMPLATE_PATH;
for (Long fileId : imageFileIdList) {
dataFeignClient.downloadFileToLocal(fileId, TEMP_REPORT_PATH + randomId);
}
// 生成projectInfo.json
// 父节点信息
ProjecInfoReq projecInfoReq = req.getProjecInfoReq();
if (ObjectUtils.isNotEmpty(projecInfoReq)) {
projecInfoReq.setReportCommand(commands);
String jsonString = JSON.toJSONString(projecInfoReq);
FileOutputStream projectInfoOutputStream = null;
try {
projectInfoOutputStream = new FileOutputStream(TEMP_REPORT_PATH + randomId + File.separator + "projectInfo.json");
projectInfoOutputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
projectInfoOutputStream.flush();
projectInfoOutputStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 生成performance.json
List<SimulationPerformance> performanceList = req.getPerformanceList();
// List<JSONObject> exportPerformanceList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(performanceList)) {
JSONObject allPerformanceInfoJson = new JSONObject();
for (SimulationPerformance performance : performanceList) {
PerformanceInfoReq performanceInfoReq = new PerformanceInfoReq();
performanceInfoReq.setValue(StringUtils.isNotBlank(performance.getTargetValue()) ? performance.getTargetValue() : "");
performanceInfoReq.setEnglishName(StringUtils.isNotBlank(performance.getEnglishName()) ? performance.getEnglishName() : "");
performanceInfoReq.setHighValue(StringUtils.isNotBlank(performance.getHighValue()) ? performance.getHighValue() : "");
performanceInfoReq.setPerformanceName(StringUtils.isNotBlank(performance.getPerformanceName()) ? performance.getPerformanceName() : "");
performanceInfoReq.setMethod(StringUtils.isNotBlank(performance.getMethod()) ? performance.getMethod() : "");
performanceInfoReq.setUnit(StringUtils.isNotBlank(performance.getUnit()) ? performance.getUnit() : "");
allPerformanceInfoJson.put(performanceInfoReq.getEnglishName(),performanceInfoReq);
}
allPerformanceInfoJson.put("type","insert");
// exportPerformanceList.add(jsonObject);
String jsonString = JSON.toJSONString(allPerformanceInfoJson);
FileOutputStream performanceOutputStream = null;
try {
performanceOutputStream = new FileOutputStream(TEMP_REPORT_PATH + randomId + File.separator + "performance.json");
performanceOutputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
performanceOutputStream.flush();
performanceOutputStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 调用脚本
log.info("调用脚本中。。。。。。");
log.info("command:" + commands);
List<String> result = new ArrayList<>();
int runningStatus = -1;
try {
log.info("开始同步执行脚本");
Process process = Runtime.getRuntime().exec(commands);
log.info("准备获取脚本输出");
log.info("开始获取脚本输出");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
log.info("executePython" + line);
result.add(line);
}
log.info("脚本执行完成");
runningStatus = process.waitFor();
log.info("脚本运行状态:" + runningStatus);
} catch (IOException | InterruptedException e) {
log.error("执行脚本失败:" + e);
return;
}
if (runningStatus != 0) {
log.error("执行脚本失败");
return;
} else {
log.info(commands + "执行脚本完成!");
}
try {
// 获取临时路径中脚本生成的报告
FileInputStream fileInputStream = new FileInputStream(TEMP_REPORT_PATH + randomId + File.separator + "report" + File.separator + "report.docx");
byte[] fileData = fileInputStream.readAllBytes();
// 设置响应头
response.reset();
response.setContentType("application/octet-stream;charset=UTF-8");
response.addHeader("Content-Length", String.valueOf(fileData.length));
// 写入响应流
OutputStream outputStream = response.getOutputStream();
outputStream.write(fileData);
outputStream.flush();
outputStream.close();
fileInputStream.close();
}catch (Exception ex) {
log.error("生成自动化报告失败:{}",ex.getMessage());
throw new RuntimeException("生成自动化报告失败");
}
// 删除临时路径
log.info("删除临时路径:{},中。。。。。。",randomId);
deleteFolder(new File(TEMP_REPORT_PATH + randomId));
}
log.info("临时路径为:{}", randomId);
String commands = "python /opt/script/exportWord.py " + TEMP_REPORT_PATH + randomId + File.separator + TEMPLATE_PATH + projecInfoReq.getLoadcaseName() + "Analyse";
// 生成projectInfo.json
projecInfoReq.setReportCommand(commands);
FileOutputStream projectInfoOutputStream = null;
try {
projectInfoOutputStream = new FileOutputStream(TEMP_REPORT_PATH + randomId + File.separator + "projectInfo.json");
projectInfoOutputStream.write(JSON.toJSONString(projecInfoReq).getBytes(StandardCharsets.UTF_8));
projectInfoOutputStream.flush();
projectInfoOutputStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
// 生成performance.json
List<SimulationPerformance> performanceList = req.getPerformanceList();
if (CollectionUtils.isNotEmpty(performanceList)) {
JSONObject allPerformanceInfoJson = new JSONObject();
for (SimulationPerformance performance : performanceList) {
PerformanceInfoReq performanceInfoReq = new PerformanceInfoReq();
performanceInfoReq.setValue(StringUtils.isNotBlank(performance.getTargetValue()) ? performance.getTargetValue() : "");
performanceInfoReq.setEnglishName(StringUtils.isNotBlank(performance.getEnglishName()) ? performance.getEnglishName() : "");
performanceInfoReq.setHighValue(StringUtils.isNotBlank(performance.getHighValue()) ? performance.getHighValue() : "");
performanceInfoReq.setPerformanceName(StringUtils.isNotBlank(performance.getPerformanceName()) ? performance.getPerformanceName() : "");
performanceInfoReq.setMethod(StringUtils.isNotBlank(performance.getMethod()) ? performance.getMethod() : "");
performanceInfoReq.setUnit(StringUtils.isNotBlank(performance.getUnit()) ? performance.getUnit() : "");
allPerformanceInfoJson.put(performanceInfoReq.getEnglishName(), performanceInfoReq);
}
allPerformanceInfoJson.put("type", "insert");
FileOutputStream performanceOutputStream = null;
try {
performanceOutputStream = new FileOutputStream(TEMP_REPORT_PATH + randomId + File.separator + "performance.json");
performanceOutputStream.write(JSON.toJSONString(allPerformanceInfoJson).getBytes(StandardCharsets.UTF_8));
performanceOutputStream.flush();
performanceOutputStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 调用脚本
log.info("调用脚本中。。。。。。");
log.info("command:" + commands);
List<String> result = new ArrayList<>();
int runningStatus = -1;
try {
log.info("开始同步执行脚本");
Process process = Runtime.getRuntime().exec(commands);
log.info("准备获取脚本输出");
log.info("开始获取脚本输出");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
log.info("executePython" + line);
result.add(line);
}
log.info("脚本执行完成");
runningStatus = process.waitFor();
log.info("脚本运行状态:" + runningStatus);
} catch (IOException | InterruptedException e) {
log.error("执行脚本失败:" + e);
return;
}
if (runningStatus != 0) {
log.error("执行脚本失败");
return;
} else {
log.info(commands + "执行脚本完成!");
}
try {
// 获取临时路径中脚本生成的报告
FileInputStream fileInputStream = new FileInputStream(TEMP_REPORT_PATH + randomId + File.separator + "report" + File.separator + "report.docx");
byte[] fileData = fileInputStream.readAllBytes();
// 设置响应头
response.reset();
response.setContentType("application/octet-stream;charset=UTF-8");
response.addHeader("Content-Length", String.valueOf(fileData.length));
// 写入响应流
OutputStream outputStream = response.getOutputStream();
outputStream.write(fileData);
outputStream.flush();
outputStream.close();
fileInputStream.close();
} catch (Exception ex) {
log.error("生成自动化报告失败:{}", ex.getMessage());
throw new RuntimeException("生成自动化报告失败");
}
// 删除临时路径
log.info("删除临时路径:{},中。。。。。。", randomId);
deleteFolder(new File(TEMP_REPORT_PATH + randomId));
}
@Override
@@ -1218,7 +1205,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
@Override
public SdmResponse saveNodeParams(SpdmNodeParamReq req) {
SimulationRun simulationRun = this.lambdaQuery().eq(SimulationRun::getUuid, req.getRunId()).one();
SimulationRun simulationRun = this.lambdaQuery().eq(SimulationRun::getUuid, req.getRunId()).one();
SdmResponse<FlowTemplateResp> flowTemplateResp = flowFeignClient.queryFlowTemplateInfo(simulationRun.getFlowTemplate());
if (flowTemplateResp.getData() != null) {
ProcessDefinitionDTO definitionDTO = JSON.parseObject(flowTemplateResp.getData().getTemplateContent(), ProcessDefinitionDTO.class);