Merge branch 'main' of http://carsafe.uicp.cn/toolchaintechnologycenter/spdm-backend
This commit is contained in:
2
1-sql/2026-02-10/simulation_task.sql
Normal file
2
1-sql/2026-02-10/simulation_task.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE spdm_baseline.simulation_task ADD reportTemplate varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '报告模板uuid';
|
||||
ALTER TABLE spdm_baseline.simulation_task ADD reportContent mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '报告模板填充内容';
|
||||
@@ -1,18 +1,25 @@
|
||||
package com.sdm.common.entity.req.project;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class EditReportReq {
|
||||
|
||||
@Schema(description= "算例uuid")
|
||||
private String runId;
|
||||
|
||||
@Schema(description= "报告模板uuid")
|
||||
private String reportTemplate;
|
||||
|
||||
@Schema(description= "报告模板内容")
|
||||
private String reportContent;
|
||||
|
||||
@Schema(description= "任务uuid")
|
||||
private String taskId;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.sdm.common.entity.resp.pbs.hpc;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class DelHpcJobsResult implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<String> succJobIds;
|
||||
|
||||
private List<String> failedJobIds;
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.sdm.common.entity.pojo.BaseEntity;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
@@ -224,4 +225,10 @@ public class SpdmTaskVo extends BaseEntity {
|
||||
*/
|
||||
private String eUserId;
|
||||
|
||||
@Schema(description= "报告模板内容")
|
||||
private String reportContent;
|
||||
|
||||
@Schema(description= "报告模板uuid")
|
||||
private String reportTemplate;
|
||||
|
||||
}
|
||||
|
||||
@@ -4,12 +4,15 @@ import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.alibaba.fastjson2.TypeReference;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.req.pbs.DelHpcJobsFileToolReq;
|
||||
import com.sdm.common.entity.resp.pbs.hpc.DelHpcJobsResult;
|
||||
import com.sdm.common.entity.resp.pbs.hpc.FileNodeInfo;
|
||||
import com.sdm.common.log.CoreLogger;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
@@ -55,6 +58,9 @@ public class HpcCommandExcuteUtil {
|
||||
@Value("${hpc.callHpcUpload:}")
|
||||
private String callHpcUpload;
|
||||
|
||||
@Value("${hpc.delHpcJobsUrl:}")
|
||||
private String delHpcJobsUrl;
|
||||
|
||||
@Autowired
|
||||
private HttpClientUtil httpClientUtil;
|
||||
|
||||
@@ -174,7 +180,7 @@ public class HpcCommandExcuteUtil {
|
||||
|
||||
public SdmResponse<Boolean> callHpcUploadToTarget(String jobId, String workDir,String minioBucket,
|
||||
String callBackMinioDir,String callBackNasDir,
|
||||
Long dirId,Long userId,Long tenantId) {
|
||||
Long dirId,Long userId,Long tenantId,String outputFormat) {
|
||||
com.alibaba.fastjson2.JSONObject paramJson = new com.alibaba.fastjson2.JSONObject();
|
||||
paramJson.put("jobId", jobId);
|
||||
paramJson.put("jobWorkDir", workDir);
|
||||
@@ -184,6 +190,7 @@ public class HpcCommandExcuteUtil {
|
||||
paramJson.put("dirId", dirId);
|
||||
paramJson.put("userId", userId);
|
||||
paramJson.put("tenantId", tenantId);
|
||||
paramJson.put("outputFormat", outputFormat);
|
||||
Boolean call = false;
|
||||
String resultString = "";
|
||||
try {
|
||||
@@ -239,4 +246,20 @@ public class HpcCommandExcuteUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public SdmResponse<DelHpcJobsResult> batchDeleteHpcJobs(List<DelHpcJobsFileToolReq> reqs,WebClient pbsWebClient) {
|
||||
// 发起POST请求,同步阻塞获取响应
|
||||
try {
|
||||
SdmResponse<DelHpcJobsResult> response = pbsWebClient.post()
|
||||
.uri(delHpcJobsUrl)
|
||||
.bodyValue(reqs) // 传入请求体对象
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<SdmResponse<DelHpcJobsResult>>() {}) // 泛型类型指定
|
||||
.block(); // 阻塞等待响应
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
log.error("batchDeleteHpcJobs post error:{}",e.getMessage());
|
||||
return SdmResponse.failed("发起批量删除hpc节点工作目录异常");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
44
flowable/src/main/resources/application-yang.yml
Normal file
44
flowable/src/main/resources/application-yang.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
server:
|
||||
port: 7106
|
||||
spring:
|
||||
application:
|
||||
name: flowable
|
||||
datasource:
|
||||
url: jdbc:mysql://127.0.0.1:3306/flowable?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: mysql
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
flowable:
|
||||
# ?????????
|
||||
database-schema-update: true
|
||||
# ??????JOB
|
||||
async-executor-activate: true
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 127.0.0.1:8848
|
||||
group: YANG_GROUP
|
||||
enabled: true
|
||||
username: nacos
|
||||
password: nacos
|
||||
|
||||
logging:
|
||||
level:
|
||||
org:
|
||||
flowable: INFO
|
||||
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath*:/mapper/**/*.xml
|
||||
type-aliases-package: com.sdm.flowable.model.entity
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: auto
|
||||
|
||||
security:
|
||||
whitelist:
|
||||
paths:
|
||||
- /process/testHpc
|
||||
- /process/testHpc2
|
||||
- /process/asyncCallback
|
||||
@@ -248,7 +248,7 @@ public class TaskController {
|
||||
return hpcInstructionService.callHpcUploadToTarget(paramMap.get("jobId").toString(), paramMap.get("jobWorkDir").toString(),
|
||||
paramMap.get("minioBucket").toString(), paramMap.get("callBackMinioDir").toString()
|
||||
,paramMap.get("callBackNasDir").toString(), Long.valueOf(paramMap.get("dirId").toString()),
|
||||
Long.valueOf(paramMap.get("userId").toString()),Long.valueOf(paramMap.get("tenantId").toString()));
|
||||
Long.valueOf(paramMap.get("userId").toString()),Long.valueOf(paramMap.get("tenantId").toString()),paramMap.get("outputFormat").toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -95,9 +95,10 @@ public class FinishedStatusHandler implements JobStatusHandler {
|
||||
String minioBucket = minioBucketPrefix + newDbJob.getTenantId();
|
||||
Long userId=newDbJob.getCreatorId();
|
||||
Long tenantId = newDbJob.getTenantId();
|
||||
String outputFormat = newDbJob.getOutputFormat();
|
||||
// 通知工具回传文件 minio 或者 nas
|
||||
SdmResponse<Boolean> callResponse = hpcInstructionService.callHpcUploadToTarget(newDbJob.getJobId(), newDbJob.getStdoutHpcFilePath(),minioBucket,
|
||||
newDbJob.getStdoutSpdmMinoFilePath(),newDbJob.getStdoutSpdmNasFilePath(),newDbJob.getDirId(),userId,tenantId);
|
||||
newDbJob.getStdoutSpdmMinoFilePath(),newDbJob.getStdoutSpdmNasFilePath(),newDbJob.getDirId(),userId,tenantId,outputFormat);
|
||||
if (!callResponse.isSuccess()||!callResponse.getData()) {
|
||||
CoreLogger.error("callHpcUploadToTarget failed,jobId:{},workDir:{}",newDbJob.getJobId(),newDbJob.getStdoutHpcFilePath());
|
||||
return;
|
||||
|
||||
@@ -57,6 +57,6 @@ public interface HpcInstructionService {
|
||||
// 通知hpc回传文件
|
||||
SdmResponse<Boolean> callHpcUploadToTarget(String jobId,String workDir,String minioBucket,
|
||||
String callBackMinioDir,String callBackNasDir,Long dirId,
|
||||
Long userId,Long tenantId);
|
||||
Long userId,Long tenantId,String outputFormat);
|
||||
|
||||
}
|
||||
|
||||
@@ -501,9 +501,9 @@ public class HpcInstructionServiceImpl implements HpcInstructionService {
|
||||
@Override
|
||||
public SdmResponse<Boolean> callHpcUploadToTarget(String jobId,String workDir,String minioBucket,
|
||||
String callBackMinioDir,String callBackNasDir,Long dirId,
|
||||
Long userId,Long tenantId) {
|
||||
Long userId,Long tenantId,String outputFormat) {
|
||||
return hpcCommandExcuteUtil.callHpcUploadToTarget(jobId,workDir,minioBucket,callBackMinioDir,
|
||||
callBackNasDir,dirId,userId,tenantId);
|
||||
callBackNasDir,dirId,userId,tenantId,outputFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,9 +10,11 @@ import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.common.ThreadLocalContext;
|
||||
import com.sdm.common.entity.enums.MessageTemplateEnum;
|
||||
import com.sdm.common.entity.req.flowable.AsyncCallbackRequest;
|
||||
import com.sdm.common.entity.req.pbs.DelHpcJobsFileToolReq;
|
||||
import com.sdm.common.entity.req.pbs.DelHpcJobsReq;
|
||||
import com.sdm.common.entity.req.system.SendMsgReq;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.common.entity.resp.pbs.hpc.DelHpcJobsResult;
|
||||
import com.sdm.common.entity.resp.pbs.hpc.FileNodeInfo;
|
||||
import com.sdm.common.feign.impl.system.MessageFeignClientImpl;
|
||||
import com.sdm.common.feign.inter.flowable.IFlowableFeignClient;
|
||||
@@ -55,6 +57,7 @@ import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@@ -579,7 +582,7 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
List<SimulationJob> jobList = simulationJobService.lambdaQuery()
|
||||
.in(SimulationJob::getJobId, req.getHpcJobIds())
|
||||
.list();
|
||||
if (jobList.isEmpty()) {
|
||||
if (CollectionUtils.isEmpty(jobList)) {
|
||||
throw new RuntimeException("未查询到待删除的HPC任务");
|
||||
}
|
||||
// 2. 校验任务状态(非进行中、文件非上传中)
|
||||
@@ -589,20 +592,59 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
throw new RuntimeException("删除的任务状态和文件状态不能是未完成");
|
||||
}
|
||||
|
||||
// 2. 调用HPC批量删除接口 todo
|
||||
// boolean hpcDelSuccess = batchDeleteHpcJobs(req.getHpcJobIds());
|
||||
// if (!hpcDelSuccess) {
|
||||
// return SdmResponse.fail("调用HPC批量删除接口失败");
|
||||
// }
|
||||
|
||||
// 5. 逻辑删除simulation_job表数据
|
||||
boolean logicDelSuccess = logicDeleteSimulationJob(jobList);
|
||||
if (!logicDelSuccess) {
|
||||
return SdmResponse.failed("逻辑删除任务数据失败");
|
||||
// 3. 调用HPC批量删除接口
|
||||
SdmResponse<DelHpcJobsResult> response = batchDeleteHpcJobs(jobList);
|
||||
if (!response.isSuccess()) {
|
||||
return SdmResponse.failed("调用HPC文件工具服务批量删除工作目录失败:{}",JSONObject.toJSONString(response));
|
||||
}
|
||||
DelHpcJobsResult data = response.getData();
|
||||
if(!Objects.isNull(data)&&CollectionUtils.isNotEmpty(data.getSuccJobIds())){
|
||||
List<String> succJobIds = data.getSuccJobIds();
|
||||
List<SimulationJob> newJobs = filterSuccessJobs(jobList, succJobIds);
|
||||
// 5. 逻辑删除simulation_job表数据
|
||||
boolean logicDelSuccess = logicDeleteSimulationJob(newJobs);
|
||||
if (!logicDelSuccess) {
|
||||
return SdmResponse.failed("逻辑删除任务数据失败");
|
||||
}
|
||||
}
|
||||
return SdmResponse.success("批量删除HPC任务成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 筛选出jobId在succJobIds中的SimulationJob集合
|
||||
* @param jobList 原始任务集合
|
||||
* @param succJobIds 成功的jobId集合
|
||||
* @return 筛选后的新任务集合
|
||||
*/
|
||||
private List<SimulationJob> filterSuccessJobs(List<SimulationJob> jobList, List<String> succJobIds) {
|
||||
// 2. 使用Stream流筛选:jobId存在于succJobIds中的元素
|
||||
List<SimulationJob> newJobList = jobList.stream()
|
||||
// 核心筛选逻辑:判断当前job的jobId是否在succJobIds中
|
||||
.filter(job -> succJobIds.contains(job.getJobId()))
|
||||
// 收集筛选结果到新集合
|
||||
.collect(Collectors.toList());
|
||||
return newJobList;
|
||||
}
|
||||
|
||||
private SdmResponse<DelHpcJobsResult> batchDeleteHpcJobs(List<SimulationJob> jobList) {
|
||||
// 远程请求filetool工具
|
||||
List<DelHpcJobsFileToolReq> reqs = new ArrayList<>();
|
||||
for (SimulationJob job : jobList) {
|
||||
if(StringUtils.isNotBlank(job.getJobId())&&StringUtils.isNotBlank(job.getStdoutHpcFilePath())){
|
||||
DelHpcJobsFileToolReq req = new DelHpcJobsFileToolReq();
|
||||
req.setJobId(job.getJobId());
|
||||
req.setStdoutHpcFilePath(job.getStdoutHpcFilePath());
|
||||
reqs.add(req);
|
||||
}
|
||||
}
|
||||
if(CollectionUtils.isEmpty(reqs)){
|
||||
log.error("batchDeleteHpcJobs get reqs null");
|
||||
return SdmResponse.failed("请求参数是null");
|
||||
}
|
||||
SdmResponse<DelHpcJobsResult> response = hpcCommandExcuteUtil.batchDeleteHpcJobs(reqs, pbsWebClient);
|
||||
return response;
|
||||
}
|
||||
|
||||
private boolean logicDeleteSimulationJob(List<SimulationJob> jobList) {
|
||||
for (SimulationJob job : jobList) {
|
||||
job.setDelFlag("Y");
|
||||
|
||||
@@ -121,6 +121,7 @@ hpc:
|
||||
remoteDownLoadFileUrl: http://192.168.190.164:9098/hpcDownload
|
||||
remoteUploadFileUrl: http://192.168.190.164:9098/uploadHpcFile
|
||||
callHpcUpload: http://192.168.190.164:9098/addJobQueue
|
||||
delHpcJobsUrl: http://192.168.190.164:9098/delHpcJobs
|
||||
# 上传头节点文件相关的配置
|
||||
fileToHpc:
|
||||
http:
|
||||
|
||||
@@ -122,6 +122,7 @@ hpc:
|
||||
# remoteDownLoadFileUrl: http://127.0.0.1:9097/hpcDownload
|
||||
remoteUploadFileUrl: http://192.168.65.55:9097/uploadHpcFile
|
||||
callHpcUpload: http://192.168.65.55:9097/addJobQueue
|
||||
delHpcJobsUrl: http://192.168.65.55:9098/delHpcJobs
|
||||
# 上传头节点文件相关的配置
|
||||
fileToHpc:
|
||||
http:
|
||||
|
||||
@@ -122,6 +122,7 @@ hpc:
|
||||
# remoteDownLoadFileUrl: http://127.0.0.1:9097/hpcDownload
|
||||
remoteUploadFileUrl: http://10.122.38.200:9098/uploadHpcFile
|
||||
callHpcUpload: http://10.122.38.200:9098/addJobQueue
|
||||
delHpcJobsUrl: http://10.122.38.200:9098/delHpcJobs
|
||||
# 上传头节点文件相关的配置
|
||||
fileToHpc:
|
||||
http:
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import java.io.Serializable;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
@@ -210,5 +211,13 @@ public class SimulationTask implements Serializable {
|
||||
@TableField("discipline")
|
||||
private String discipline;
|
||||
|
||||
@Schema(description= "报告模板uuid")
|
||||
@TableField("reportTemplate")
|
||||
private String reportTemplate;
|
||||
|
||||
@Schema(description= "报告模板填充内容")
|
||||
@TableField("reportContent")
|
||||
private String reportContent;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -915,6 +915,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
|
||||
if (StringUtils.isEmpty(req.getFileTypeDictValue())) {
|
||||
req.setFileTypeDictClass(FileDictTagEnum.FILE_TYPE.getDictClass());
|
||||
req.setFileTypeDictValue(String.valueOf(req.getFileType()));
|
||||
req.setDictTags(Arrays.asList(FileDictTagEnum.FILE_TYPE.getDictClassFieldName(), FileDictTagEnum.FILE_TYPE.getDictValueFieldName()));
|
||||
}
|
||||
SdmResponse response = uploadKeyResultFiles(filesReq);
|
||||
if (response.isSuccess() && response.getData() != null) {
|
||||
@@ -1526,7 +1527,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
|
||||
MockMultipartFile multipartFile = new MockMultipartFile(
|
||||
reportName,
|
||||
reportName,
|
||||
"application/json",
|
||||
"application/octet-stream",
|
||||
fileData);
|
||||
resultReq.setFile(multipartFile);
|
||||
resultReq.setFileName(reportName);
|
||||
@@ -1626,83 +1627,245 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
|
||||
@Override
|
||||
public SdmResponse editReport(EditReportReq req) {
|
||||
log.info("编辑报告参数为:{}", req);
|
||||
SimulationRun simulationRun = this.lambdaQuery().eq(SimulationRun::getUuid, req.getRunId()).one();
|
||||
if (simulationRun != null) {
|
||||
String reportContent = req.getReportContent();
|
||||
// 算例绑定报告模板
|
||||
simulationRun.setReportTemplate(req.getReportTemplate());
|
||||
simulationRun.setReportContent(reportContent);
|
||||
this.updateById(simulationRun);
|
||||
|
||||
String randomId = RandomUtil.generateString(16);
|
||||
// 创建临时文件夹
|
||||
Path folder = Paths.get(TEMP_REPORT_PATH + randomId);
|
||||
if (!Files.exists(folder) || !Files.isDirectory(folder)) {
|
||||
if (!new File(TEMP_REPORT_PATH + randomId).mkdir()) {
|
||||
log.error("创建临时文件夹:{}失败",TEMP_REPORT_PATH + randomId);
|
||||
throw new RuntimeException("生成报告失败,原因为:创建临时文件夹失败");
|
||||
}
|
||||
String reportContent = req.getReportContent();
|
||||
if (StringUtils.isNotEmpty(req.getTaskId())) {
|
||||
SimulationTask simulationTask = simulationTaskService.lambdaQuery().eq(SimulationTask::getUuid, req.getTaskId()).one();
|
||||
if (simulationTask != null) {
|
||||
// 任务绑定报告模板
|
||||
simulationTask.setReportTemplate(req.getReportTemplate());
|
||||
simulationTask.setReportContent(reportContent);
|
||||
simulationTaskService.updateById(simulationTask);
|
||||
}
|
||||
log.info("临时路径为:{}", randomId);
|
||||
} else {
|
||||
SimulationRun simulationRun = this.lambdaQuery().eq(SimulationRun::getUuid, req.getRunId()).one();
|
||||
if (simulationRun != null) {
|
||||
// 算例绑定报告模板
|
||||
simulationRun.setReportTemplate(req.getReportTemplate());
|
||||
simulationRun.setReportContent(reportContent);
|
||||
this.updateById(simulationRun);
|
||||
}
|
||||
}
|
||||
|
||||
// 根据文件id下载文件到临时目录
|
||||
SdmResponse<ReportTemplateResp> reportResponse = reportFeignClient.queryReportTemplateInfo(req.getReportTemplate());
|
||||
if (reportResponse.isSuccess()) {
|
||||
Long reportTemplateFileId = reportResponse.getData().getFileId();
|
||||
// 获取报告模板名称
|
||||
GetFileBaseInfoReq getFileBaseInfoReq = new GetFileBaseInfoReq();
|
||||
getFileBaseInfoReq.setFileId(reportTemplateFileId);
|
||||
SdmResponse<FileMetadataInfoResp> fileBaseInfoResp = dataFeignClient.getFileBaseInfo(getFileBaseInfoReq);
|
||||
String originalName = fileBaseInfoResp.getData().getOriginalName();
|
||||
// 下载到本地临时目录
|
||||
dataFeignClient.downloadFileToLocal(reportTemplateFileId, TEMP_REPORT_PATH + randomId);
|
||||
String randomId = RandomUtil.generateString(16);
|
||||
// 创建临时文件夹
|
||||
Path folder = Paths.get(TEMP_REPORT_PATH + randomId);
|
||||
if (!Files.exists(folder) || !Files.isDirectory(folder)) {
|
||||
if (!new File(TEMP_REPORT_PATH + randomId).mkdir()) {
|
||||
log.error("创建临时文件夹:{}失败",TEMP_REPORT_PATH + randomId);
|
||||
throw new RuntimeException("生成报告失败,原因为:创建临时文件夹失败");
|
||||
}
|
||||
}
|
||||
log.info("临时路径为:{}", randomId);
|
||||
|
||||
// 构建python命令
|
||||
List<String> command = new ArrayList<>();
|
||||
command.add("python");
|
||||
command.add("/opt/script/modifyReport.py");
|
||||
// 根据文件id下载文件到临时目录
|
||||
SdmResponse<ReportTemplateResp> reportResponse = reportFeignClient.queryReportTemplateInfo(req.getReportTemplate());
|
||||
if (reportResponse.isSuccess()) {
|
||||
Long reportTemplateFileId = reportResponse.getData().getFileId();
|
||||
// 获取报告模板名称
|
||||
GetFileBaseInfoReq getFileBaseInfoReq = new GetFileBaseInfoReq();
|
||||
getFileBaseInfoReq.setFileId(reportTemplateFileId);
|
||||
SdmResponse<FileMetadataInfoResp> fileBaseInfoResp = dataFeignClient.getFileBaseInfo(getFileBaseInfoReq);
|
||||
String originalName = fileBaseInfoResp.getData().getOriginalName();
|
||||
// 下载到本地临时目录
|
||||
dataFeignClient.downloadFileToLocal(reportTemplateFileId, TEMP_REPORT_PATH + randomId);
|
||||
|
||||
// 构建python命令
|
||||
List<String> command = new ArrayList<>();
|
||||
command.add("python");
|
||||
command.add("/opt/script/modifyReport.py");
|
||||
// command.add(TEMP_REPORT_PATH + File.separator +"modifyReport.py");
|
||||
command.add(TEMP_REPORT_PATH + randomId);
|
||||
command.add(TEMP_REPORT_PATH + randomId + File.separator + originalName);
|
||||
String commands = String.join(" ", command);
|
||||
command.add(TEMP_REPORT_PATH + randomId);
|
||||
command.add(TEMP_REPORT_PATH + randomId + File.separator + originalName);
|
||||
String commands = String.join(" ", command);
|
||||
|
||||
// 前端参数写入临时目录
|
||||
FileOutputStream projectInfoOutputStream = null;
|
||||
try {
|
||||
projectInfoOutputStream = new FileOutputStream(TEMP_REPORT_PATH + randomId + File.separator + "reportContent.json");
|
||||
projectInfoOutputStream.write(reportContent.getBytes(StandardCharsets.UTF_8));
|
||||
projectInfoOutputStream.flush();
|
||||
projectInfoOutputStream.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
// 前端参数写入临时目录
|
||||
FileOutputStream projectInfoOutputStream = null;
|
||||
try {
|
||||
projectInfoOutputStream = new FileOutputStream(TEMP_REPORT_PATH + randomId + File.separator + "reportContent.json");
|
||||
projectInfoOutputStream.write(reportContent.getBytes(StandardCharsets.UTF_8));
|
||||
projectInfoOutputStream.flush();
|
||||
projectInfoOutputStream.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// 调用脚本
|
||||
log.info("执行 Python 命令: {}", commands);
|
||||
int runningStatus = -1;
|
||||
try {
|
||||
log.info("开始同步执行脚本");
|
||||
Process process = Runtime.getRuntime().exec(commands);
|
||||
log.info("开始获取脚本输出");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
log.info("executePython:" + line);
|
||||
}
|
||||
log.info("脚本执行完成");
|
||||
runningStatus = process.waitFor();
|
||||
log.info("脚本运行状态:" + runningStatus);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
log.error("执行脚本失败:" + e);
|
||||
return SdmResponse.failed("执行脚本失败");
|
||||
}
|
||||
if (runningStatus != 0) {
|
||||
log.error("执行脚本失败");
|
||||
return SdmResponse.failed("执行脚本失败");
|
||||
} else {
|
||||
log.info(commands + "执行脚本完成!");
|
||||
}
|
||||
byte[] fileData = null;
|
||||
try {
|
||||
// 获取临时路径中脚本生成的报告
|
||||
String reportName = "report_" +
|
||||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) +
|
||||
".docx";
|
||||
FileInputStream fileInputStream = new FileInputStream(TEMP_REPORT_PATH + randomId + File.separator + reportName);
|
||||
fileData = fileInputStream.readAllBytes();
|
||||
|
||||
// 调用脚本
|
||||
log.info("执行 Python 命令: {}", commands);
|
||||
int runningStatus = -1;
|
||||
try {
|
||||
log.info("开始同步执行脚本");
|
||||
Process process = Runtime.getRuntime().exec(commands);
|
||||
log.info("开始获取脚本输出");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
log.info("executePython:" + line);
|
||||
// 创建临时MultipartFile
|
||||
MockMultipartFile multipartFile = new MockMultipartFile(
|
||||
reportName,
|
||||
reportName,
|
||||
"application/octet-stream",
|
||||
fileData);
|
||||
if (StringUtils.isNotEmpty(req.getTaskId())) {
|
||||
// 上传到任务下的交付物文件夹的报告文件夹下
|
||||
Long parentId = getParentDirId(req.getTaskId(), FileBizTypeEnum.REPORT_FILE.getDirName());
|
||||
UploadFilesReq filesReq = new UploadFilesReq();
|
||||
filesReq.setFile(multipartFile);
|
||||
filesReq.setFileName(reportName);
|
||||
filesReq.setFileType(FileBizTypeEnum.REPORT_FILE.getValue());
|
||||
filesReq.setUuid(null);
|
||||
filesReq.setDirId(parentId);
|
||||
filesReq.setFileTypeDictClass(FileDictTagEnum.FILE_TYPE.getDictClass());
|
||||
filesReq.setFileTypeDictValue(String.valueOf(FileBizTypeEnum.REPORT_FILE.getValue()));
|
||||
filesReq.setDictTags(Arrays.asList(FileDictTagEnum.FILE_TYPE.getDictClassFieldName(), FileDictTagEnum.FILE_TYPE.getDictValueFieldName()));
|
||||
SdmResponse sdmResponse = uploadKeyResultFiles(filesReq);
|
||||
if (!sdmResponse.isSuccess()) {
|
||||
throw new RuntimeException("生成自动化报告上传任务报告结果目录失败");
|
||||
}
|
||||
log.info("脚本执行完成");
|
||||
runningStatus = process.waitFor();
|
||||
log.info("脚本运行状态:" + runningStatus);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
log.error("执行脚本失败:" + e);
|
||||
return SdmResponse.failed("执行脚本失败");
|
||||
}
|
||||
if (runningStatus != 0) {
|
||||
log.error("执行脚本失败");
|
||||
return SdmResponse.failed("执行脚本失败");
|
||||
} else {
|
||||
log.info(commands + "执行脚本完成!");
|
||||
// 上传到算例下的报告文件夹下
|
||||
KeyResultReq resultReq = new KeyResultReq();
|
||||
resultReq.setKeyResultType(KeyResultTypeEnum.DOCUMENT.getKeyResultType());
|
||||
resultReq.setRunId(req.getRunId());
|
||||
resultReq.setName(reportName);
|
||||
|
||||
resultReq.setFile(multipartFile);
|
||||
resultReq.setFileName(reportName);
|
||||
resultReq.setFileType(FileBizTypeEnum.REPORT_FILE.getValue());
|
||||
SdmResponse sdmResponse = addSimulationKeyResult(resultReq);
|
||||
if (!sdmResponse.isSuccess()) {
|
||||
throw new RuntimeException("生成自动化报告上传算例报告结果目录失败");
|
||||
}
|
||||
}
|
||||
byte[] fileData = null;
|
||||
|
||||
fileInputStream.close();
|
||||
// 删除临时路径
|
||||
log.info("删除临时路径:{},中。。。。。。", randomId);
|
||||
deleteFolder(new File(TEMP_REPORT_PATH + randomId));
|
||||
return SdmResponse.success();
|
||||
} catch (Exception ex) {
|
||||
log.error("生成自动化报告失败:{}", ex.getMessage());
|
||||
throw new RuntimeException("生成自动化报告失败");
|
||||
}
|
||||
}
|
||||
return SdmResponse.failed("生成自动化报告失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editReportAndDownload(EditReportReq req, HttpServletResponse response) {
|
||||
log.info("编辑报告参数为:{}", req);
|
||||
String reportContent = req.getReportContent();
|
||||
if (StringUtils.isNotEmpty(req.getTaskId())) {
|
||||
SimulationTask simulationTask = simulationTaskService.lambdaQuery().eq(SimulationTask::getUuid, req.getTaskId()).one();
|
||||
if (simulationTask != null) {
|
||||
// 任务绑定报告模板
|
||||
simulationTask.setReportTemplate(req.getReportTemplate());
|
||||
simulationTask.setReportContent(reportContent);
|
||||
simulationTaskService.updateById(simulationTask);
|
||||
}
|
||||
} else {
|
||||
SimulationRun simulationRun = this.lambdaQuery().eq(SimulationRun::getUuid, req.getRunId()).one();
|
||||
if (simulationRun != null) {
|
||||
// 算例绑定报告模板
|
||||
simulationRun.setReportTemplate(req.getReportTemplate());
|
||||
simulationRun.setReportContent(reportContent);
|
||||
this.updateById(simulationRun);
|
||||
}
|
||||
}
|
||||
|
||||
String randomId = RandomUtil.generateString(16);
|
||||
// 创建临时文件夹
|
||||
Path folder = Paths.get(TEMP_REPORT_PATH + randomId);
|
||||
if (!Files.exists(folder) || !Files.isDirectory(folder)) {
|
||||
if (!new File(TEMP_REPORT_PATH + randomId).mkdir()) {
|
||||
log.error("创建临时文件夹:{}失败",TEMP_REPORT_PATH + randomId);
|
||||
throw new RuntimeException("生成报告失败,原因为:创建临时文件夹失败");
|
||||
}
|
||||
}
|
||||
log.info("临时路径为:{}", randomId);
|
||||
|
||||
// 根据文件id下载文件到临时目录
|
||||
SdmResponse<ReportTemplateResp> reportResponse = reportFeignClient.queryReportTemplateInfo(req.getReportTemplate());
|
||||
if (reportResponse.isSuccess()) {
|
||||
Long reportTemplateFileId = reportResponse.getData().getFileId();
|
||||
// 获取报告模板名称
|
||||
GetFileBaseInfoReq getFileBaseInfoReq = new GetFileBaseInfoReq();
|
||||
getFileBaseInfoReq.setFileId(reportTemplateFileId);
|
||||
SdmResponse<FileMetadataInfoResp> fileBaseInfoResp = dataFeignClient.getFileBaseInfo(getFileBaseInfoReq);
|
||||
String originalName = fileBaseInfoResp.getData().getOriginalName();
|
||||
// 下载到本地临时目录
|
||||
dataFeignClient.downloadFileToLocal(reportTemplateFileId, TEMP_REPORT_PATH + randomId);
|
||||
|
||||
// 构建python命令
|
||||
List<String> command = new ArrayList<>();
|
||||
command.add("python");
|
||||
command.add("/opt/script/modifyReport.py");
|
||||
// command.add(TEMP_REPORT_PATH + File.separator +"modifyReport.py");
|
||||
command.add(TEMP_REPORT_PATH + randomId);
|
||||
command.add(TEMP_REPORT_PATH + randomId + File.separator + originalName);
|
||||
String commands = String.join(" ", command);
|
||||
|
||||
// 前端参数写入临时目录
|
||||
FileOutputStream projectInfoOutputStream = null;
|
||||
try {
|
||||
projectInfoOutputStream = new FileOutputStream(TEMP_REPORT_PATH + randomId + File.separator + "reportContent.json");
|
||||
projectInfoOutputStream.write(reportContent.getBytes(StandardCharsets.UTF_8));
|
||||
projectInfoOutputStream.flush();
|
||||
projectInfoOutputStream.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// 调用脚本
|
||||
log.info("执行 Python 命令: {}", commands);
|
||||
int runningStatus = -1;
|
||||
try {
|
||||
log.info("开始同步执行脚本");
|
||||
Process process = Runtime.getRuntime().exec(commands);
|
||||
log.info("开始获取脚本输出");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
log.info("executePython:" + 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 + "执行脚本完成!");
|
||||
}
|
||||
byte[] fileData = null;
|
||||
if (response != null) {
|
||||
try {
|
||||
// 获取临时路径中脚本生成的报告
|
||||
String reportName = "report_" +
|
||||
@@ -1711,166 +1874,63 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
|
||||
FileInputStream fileInputStream = new FileInputStream(TEMP_REPORT_PATH + randomId + File.separator + reportName);
|
||||
fileData = fileInputStream.readAllBytes();
|
||||
|
||||
// 上传到算例下的报告文件夹下
|
||||
KeyResultReq resultReq = new KeyResultReq();
|
||||
resultReq.setKeyResultType(KeyResultTypeEnum.DOCUMENT.getKeyResultType());
|
||||
resultReq.setRunId(req.getRunId());
|
||||
resultReq.setName(reportName);
|
||||
// 创建临时MultipartFile
|
||||
MockMultipartFile multipartFile = new MockMultipartFile(
|
||||
reportName,
|
||||
reportName,
|
||||
"application/json",
|
||||
"application/octet-stream",
|
||||
fileData);
|
||||
resultReq.setFile(multipartFile);
|
||||
resultReq.setFileName(reportName);
|
||||
resultReq.setFileType(FileBizTypeEnum.REPORT_FILE.getValue());
|
||||
SdmResponse sdmResponse = addSimulationKeyResult(resultReq);
|
||||
if (!sdmResponse.isSuccess()) {
|
||||
throw new RuntimeException("生成自动化报告上传报告结果目录失败");
|
||||
}
|
||||
fileInputStream.close();
|
||||
// 删除临时路径
|
||||
log.info("删除临时路径:{},中。。。。。。", randomId);
|
||||
deleteFolder(new File(TEMP_REPORT_PATH + randomId));
|
||||
return SdmResponse.success();
|
||||
} catch (Exception ex) {
|
||||
log.error("生成自动化报告失败:{}", ex.getMessage());
|
||||
throw new RuntimeException("生成自动化报告失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
return SdmResponse.failed("算例不存在");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editReportAndDownload(EditReportReq req, HttpServletResponse response) {
|
||||
log.info("编辑报告参数为:{}", req);
|
||||
SimulationRun simulationRun = this.lambdaQuery().eq(SimulationRun::getUuid, req.getRunId()).one();
|
||||
if (simulationRun != null) {
|
||||
String reportContent = req.getReportContent();
|
||||
// 算例绑定报告模板
|
||||
simulationRun.setReportTemplate(req.getReportTemplate());
|
||||
simulationRun.setReportContent(reportContent);
|
||||
this.updateById(simulationRun);
|
||||
|
||||
String randomId = RandomUtil.generateString(16);
|
||||
// 创建临时文件夹
|
||||
Path folder = Paths.get(TEMP_REPORT_PATH + randomId);
|
||||
if (!Files.exists(folder) || !Files.isDirectory(folder)) {
|
||||
if (!new File(TEMP_REPORT_PATH + randomId).mkdir()) {
|
||||
log.error("创建临时文件夹:{}失败",TEMP_REPORT_PATH + randomId);
|
||||
throw new RuntimeException("生成报告失败,原因为:创建临时文件夹失败");
|
||||
}
|
||||
}
|
||||
log.info("临时路径为:{}", randomId);
|
||||
|
||||
// 根据文件id下载文件到临时目录
|
||||
SdmResponse<ReportTemplateResp> reportResponse = reportFeignClient.queryReportTemplateInfo(req.getReportTemplate());
|
||||
if (reportResponse.isSuccess()) {
|
||||
Long reportTemplateFileId = reportResponse.getData().getFileId();
|
||||
// 获取报告模板名称
|
||||
GetFileBaseInfoReq getFileBaseInfoReq = new GetFileBaseInfoReq();
|
||||
getFileBaseInfoReq.setFileId(reportTemplateFileId);
|
||||
SdmResponse<FileMetadataInfoResp> fileBaseInfoResp = dataFeignClient.getFileBaseInfo(getFileBaseInfoReq);
|
||||
String originalName = fileBaseInfoResp.getData().getOriginalName();
|
||||
// 下载到本地临时目录
|
||||
dataFeignClient.downloadFileToLocal(reportTemplateFileId, TEMP_REPORT_PATH + randomId);
|
||||
|
||||
// 构建python命令
|
||||
List<String> command = new ArrayList<>();
|
||||
command.add("python");
|
||||
command.add("/opt/script/modifyReport.py");
|
||||
// command.add(TEMP_REPORT_PATH + File.separator +"modifyReport.py");
|
||||
command.add(TEMP_REPORT_PATH + randomId);
|
||||
command.add(TEMP_REPORT_PATH + randomId + File.separator + originalName);
|
||||
String commands = String.join(" ", command);
|
||||
|
||||
// 前端参数写入临时目录
|
||||
FileOutputStream projectInfoOutputStream = null;
|
||||
try {
|
||||
projectInfoOutputStream = new FileOutputStream(TEMP_REPORT_PATH + randomId + File.separator + "reportContent.json");
|
||||
projectInfoOutputStream.write(reportContent.getBytes(StandardCharsets.UTF_8));
|
||||
projectInfoOutputStream.flush();
|
||||
projectInfoOutputStream.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// 调用脚本
|
||||
log.info("执行 Python 命令: {}", commands);
|
||||
int runningStatus = -1;
|
||||
try {
|
||||
log.info("开始同步执行脚本");
|
||||
Process process = Runtime.getRuntime().exec(commands);
|
||||
log.info("开始获取脚本输出");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
log.info("executePython:" + 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 + "执行脚本完成!");
|
||||
}
|
||||
byte[] fileData = null;
|
||||
if (response != null) {
|
||||
try {
|
||||
// 获取临时路径中脚本生成的报告
|
||||
String reportName = "report_" +
|
||||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) +
|
||||
".docx";
|
||||
FileInputStream fileInputStream = new FileInputStream(TEMP_REPORT_PATH + randomId + File.separator + reportName);
|
||||
fileData = fileInputStream.readAllBytes();
|
||||
|
||||
if (StringUtils.isNotEmpty(req.getTaskId())) {
|
||||
// 上传到任务下的交付物文件夹的报告文件夹下
|
||||
Long parentId = getParentDirId(req.getTaskId(), FileBizTypeEnum.REPORT_FILE.getDirName());
|
||||
UploadFilesReq filesReq = new UploadFilesReq();
|
||||
filesReq.setFile(multipartFile);
|
||||
filesReq.setFileName(reportName);
|
||||
filesReq.setFileType(FileBizTypeEnum.REPORT_FILE.getValue());
|
||||
filesReq.setUuid(null);
|
||||
filesReq.setDirId(parentId);
|
||||
filesReq.setFileTypeDictClass(FileDictTagEnum.FILE_TYPE.getDictClass());
|
||||
filesReq.setFileTypeDictValue(String.valueOf(FileBizTypeEnum.REPORT_FILE.getValue()));
|
||||
filesReq.setDictTags(Arrays.asList(FileDictTagEnum.FILE_TYPE.getDictClassFieldName(), FileDictTagEnum.FILE_TYPE.getDictValueFieldName()));
|
||||
SdmResponse sdmResponse = uploadKeyResultFiles(filesReq);
|
||||
if (!sdmResponse.isSuccess()) {
|
||||
throw new RuntimeException("生成自动化报告上传任务报告结果目录失败");
|
||||
}
|
||||
} else {
|
||||
// 上传到算例下的报告文件夹下
|
||||
KeyResultReq resultReq = new KeyResultReq();
|
||||
resultReq.setKeyResultType(KeyResultTypeEnum.DOCUMENT.getKeyResultType());
|
||||
resultReq.setRunId(req.getRunId());
|
||||
resultReq.setName(reportName);
|
||||
// 创建临时MultipartFile
|
||||
MockMultipartFile multipartFile = new MockMultipartFile(
|
||||
reportName,
|
||||
reportName,
|
||||
"application/json",
|
||||
fileData);
|
||||
|
||||
resultReq.setFile(multipartFile);
|
||||
resultReq.setFileName(reportName);
|
||||
resultReq.setFileType(FileBizTypeEnum.REPORT_FILE.getValue());
|
||||
SdmResponse sdmResponse = addSimulationKeyResult(resultReq);
|
||||
if (!sdmResponse.isSuccess()) {
|
||||
throw new RuntimeException("生成自动化报告上传报告结果目录失败");
|
||||
throw new RuntimeException("生成自动化报告上传算例报告结果目录失败");
|
||||
}
|
||||
|
||||
// 下载到本地
|
||||
// 设置响应头
|
||||
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("生成自动化报告失败");
|
||||
}
|
||||
|
||||
// 下载到本地
|
||||
// 设置响应头
|
||||
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);
|
||||
deleteFolder(new File(TEMP_REPORT_PATH + randomId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user