Merge branch 'main' of http://carsafe.uicp.cn/toolchaintechnologycenter/spdm-backend
This commit is contained in:
@@ -525,7 +525,7 @@ public class DataFileController implements IDataFeignClient {
|
||||
|
||||
@GetMapping("/getMinioPresignedUrl")
|
||||
@Operation(summary = "获取MinIO文件下载的预签名URL", description = "获取MinIO文件的预签名URL")
|
||||
public SdmResponse<MinioDownloadUrlResp> getMinioPresignedUrl(@Parameter(description = "文件id") @RequestParam("fileId") Long fileId, @RequestParam("skipPermissionCheck") Boolean skipPermissionCheck) {
|
||||
public SdmResponse<MinioDownloadUrlResp> getMinioPresignedUrl(@Parameter(description = "文件id") @RequestParam("fileId") Long fileId, @RequestParam(value = "skipPermissionCheck", required = false, defaultValue = "false") Boolean skipPermissionCheck) {
|
||||
return IDataFileService.getDownloadUrlWithPermission(fileId, skipPermissionCheck);
|
||||
}
|
||||
|
||||
@@ -608,7 +608,7 @@ public class DataFileController implements IDataFeignClient {
|
||||
*/
|
||||
@GetMapping("/downloadFileForEdit")
|
||||
@Operation(summary = "根据fileId下载文件到指定目录并返回该文件的系统路径", description = "根据fileId下载文件到指定目录并返回该文件的系统路径")
|
||||
public SdmResponse downloadFileForEdit(@RequestParam(value = "fileId") @Validated Long fileId,@RequestParam("skipPermissionCheck") Boolean skipPermissionCheck) {
|
||||
public SdmResponse downloadFileForEdit(@RequestParam(value = "fileId") @Validated Long fileId,@RequestParam(value = "skipPermissionCheck", required = false, defaultValue = "false") Boolean skipPermissionCheck) {
|
||||
return IDataFileService.downloadFileForEdit(fileId,skipPermissionCheck);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ import java.nio.file.StandardCopyOption;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -1832,126 +1833,218 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
|
||||
|
||||
@Override
|
||||
public SdmResponse editReport(EditReportReq req) {
|
||||
Long userId = ThreadLocalContext.getUserId();
|
||||
log.info("编辑报告参数为:{}", req);
|
||||
Long userId = ThreadLocalContext.getUserId();
|
||||
String reportContent = req.getReportContent();
|
||||
|
||||
// 1. 更新报告绑定,获取任务名称
|
||||
String taskName = updateReportBinding(req, userId);
|
||||
|
||||
// 2. 创建临时文件夹
|
||||
String randomId = createTempReportFolder();
|
||||
log.info("临时路径为:{}", randomId);
|
||||
|
||||
// 3. 准备报告模板
|
||||
String originalName = prepareReportTemplate(req.getReportTemplate(), randomId);
|
||||
if (originalName == null) {
|
||||
return SdmResponse.failed("获取报告模板失败");
|
||||
}
|
||||
|
||||
// 4. 生成报告名称(使用任务名称作为前缀)
|
||||
String reportName = generateReportName(taskName);
|
||||
|
||||
// 5. 构建并执行Python脚本
|
||||
String commands = buildModifyReportCommand(randomId, originalName, reportName);
|
||||
writeReportContentJson(randomId, reportContent);
|
||||
|
||||
SdmResponse executeResult = executePythonScriptWithTimeout(commands);
|
||||
if (!executeResult.isSuccess()) {
|
||||
return SdmResponse.failed(executeResult.getMessage());
|
||||
}
|
||||
|
||||
// 6. 归档报告和图片
|
||||
archiveGeneratedReport(reportName, req.getTaskId(), req.getRunId(), randomId, reportContent);
|
||||
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
// ==================== 报告编辑相关私有方法 ====================
|
||||
|
||||
/**
|
||||
* 更新报告绑定(任务或算例),返回任务名称
|
||||
*/
|
||||
private String updateReportBinding(EditReportReq req, Long userId) {
|
||||
String reportContent = req.getReportContent();
|
||||
String taskName = "";
|
||||
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);
|
||||
|
||||
// 读取前端传入的指标表格数据,实现更新/替换/新增
|
||||
archivePerformances(reportContent, simulationTask.getUuid(), null, userId);
|
||||
taskName = simulationTask.getTaskName();
|
||||
}
|
||||
} 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 taskUuid = simulationRun.getTaskId();
|
||||
SimulationTask task = simulationTaskService.lambdaQuery().eq(SimulationTask::getUuid, taskUuid).one();
|
||||
if (task != null) {
|
||||
taskName = task.getTaskName();
|
||||
}
|
||||
archivePerformances(reportContent, simulationRun.getTaskId(), simulationRun.getUuid(), userId);
|
||||
}
|
||||
}
|
||||
return taskName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建临时报告文件夹
|
||||
*/
|
||||
private String createTempReportFolder() {
|
||||
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);
|
||||
log.error("创建临时文件夹:{}失败", TEMP_REPORT_PATH + randomId);
|
||||
throw new RuntimeException("生成报告失败,原因为:创建临时文件夹失败");
|
||||
}
|
||||
}
|
||||
log.info("临时路径为:{}", randomId);
|
||||
return 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);
|
||||
/**
|
||||
* 准备报告模板(获取模板信息并下载到临时目录)
|
||||
*/
|
||||
private String prepareReportTemplate(String reportTemplateId, String randomId) {
|
||||
SdmResponse<ReportTemplateResp> reportResponse = reportFeignClient.queryReportTemplateInfo(reportTemplateId);
|
||||
if (!reportResponse.isSuccess()) {
|
||||
return null;
|
||||
}
|
||||
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);
|
||||
return originalName;
|
||||
}
|
||||
|
||||
String reportName = "report_" +
|
||||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) +
|
||||
".docx";
|
||||
/**
|
||||
* 生成报告文件名
|
||||
* @param taskName 任务名称,用作报告文件名前缀
|
||||
*/
|
||||
private String generateReportName(String taskName) {
|
||||
String prefix = StringUtils.isNotEmpty(taskName) ? taskName : "report";
|
||||
return prefix + "_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".docx";
|
||||
}
|
||||
|
||||
// 构建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);
|
||||
command.add(reportName);
|
||||
String commands = String.join(" ", command);
|
||||
/**
|
||||
* 构建修改报告的Python命令
|
||||
*/
|
||||
private String buildModifyReportCommand(String randomId, String originalName, String reportName) {
|
||||
List<String> command = new ArrayList<>();
|
||||
command.add("python");
|
||||
command.add("/opt/script/modifyReport.py");
|
||||
command.add(TEMP_REPORT_PATH + randomId);
|
||||
command.add(TEMP_REPORT_PATH + randomId + File.separator + originalName);
|
||||
command.add(reportName);
|
||||
return 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 SdmResponse.failed("执行脚本失败");
|
||||
/**
|
||||
* 写入报告内容JSON到临时目录
|
||||
*/
|
||||
private void writeReportContentJson(String randomId, String reportContent) {
|
||||
try (FileOutputStream outputStream = new FileOutputStream(TEMP_REPORT_PATH + randomId + File.separator + "reportContent.json")) {
|
||||
outputStream.write(reportContent.getBytes(StandardCharsets.UTF_8));
|
||||
outputStream.flush();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("写入报告内容失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Python脚本(带5秒超时)
|
||||
*/
|
||||
private SdmResponse executePythonScriptWithTimeout(String commands) {
|
||||
log.info("执行 Python 命令: {}", commands);
|
||||
Process process = null;
|
||||
try {
|
||||
log.info("开始同步执行脚本");
|
||||
process = Runtime.getRuntime().exec(commands);
|
||||
boolean finished = process.waitFor(5, TimeUnit.SECONDS);
|
||||
if (!finished) {
|
||||
log.error("脚本执行超时,超过5秒未完成");
|
||||
process.destroyForcibly();
|
||||
return SdmResponse.failed("脚本执行超时,请稍后重试");
|
||||
}
|
||||
int runningStatus = process.exitValue();
|
||||
log.info("脚本运行状态:" + runningStatus);
|
||||
if (runningStatus != 0) {
|
||||
log.error("执行脚本失败");
|
||||
return SdmResponse.failed("执行脚本失败");
|
||||
} else {
|
||||
log.info(commands + "执行脚本完成!");
|
||||
}
|
||||
|
||||
// 读取脚本生成的报告并归档
|
||||
archiveReportAndImage(reportName, req.getTaskId(), req.getRunId(), randomId, FileBizTypeEnum.REPORT_FILE, null, null);
|
||||
|
||||
// 读取脚本生成的图片并按顺序归档
|
||||
List<String> imageNames = extractPicNames(reportContent);
|
||||
if (CollectionUtils.isNotEmpty(imageNames)) {
|
||||
int sortOrder = 1;
|
||||
for (String imageName : imageNames) {
|
||||
archiveReportAndImage(null, req.getTaskId(), req.getRunId(), randomId, FileBizTypeEnum.CLOUD_FILE, imageName, sortOrder++);
|
||||
}
|
||||
}
|
||||
log.info(commands + " 执行脚本完成!");
|
||||
return SdmResponse.success();
|
||||
// 删除临时路径
|
||||
// log.info("删除临时路径:{},中。。。。。。", randomId);
|
||||
// deleteFolder(new File(TEMP_REPORT_PATH + randomId));
|
||||
} catch (IOException e) {
|
||||
log.error("执行脚本失败:" + e);
|
||||
return SdmResponse.failed("执行脚本失败");
|
||||
} catch (InterruptedException e) {
|
||||
log.error("脚本执行被中断:" + e);
|
||||
Thread.currentThread().interrupt();
|
||||
return SdmResponse.failed("脚本执行被中断");
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
return SdmResponse.failed("生成自动化报告失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 归档生成的报告和图片
|
||||
*/
|
||||
private void archiveGeneratedReport(String reportName, String taskId, String runId, String randomId, String reportContent) {
|
||||
// 归档报告文件
|
||||
archiveReportAndImage(reportName, taskId, runId, randomId, FileBizTypeEnum.REPORT_FILE, null, null);
|
||||
|
||||
// 归档图片
|
||||
List<String> imageNames = extractPicNames(reportContent);
|
||||
if (CollectionUtils.isNotEmpty(imageNames)) {
|
||||
int sortOrder = 1;
|
||||
for (String imageName : imageNames) {
|
||||
archiveReportAndImage(null, taskId, runId, randomId, FileBizTypeEnum.CLOUD_FILE, imageName, sortOrder++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载报告文件到响应流
|
||||
*/
|
||||
private void downloadReportFile(String reportName, String randomId, HttpServletResponse response) {
|
||||
try (FileInputStream fileInputStream = new FileInputStream(TEMP_REPORT_PATH + randomId + File.separator + reportName)) {
|
||||
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();
|
||||
} catch (Exception ex) {
|
||||
log.error("下载报告文件失败:{}", ex.getMessage());
|
||||
throw new RuntimeException("下载报告文件失败");
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 原有私有方法 ====================
|
||||
|
||||
private void archiveReportAndImage(String reportName, String taskId, String runId, String randomId, FileBizTypeEnum fileBizTypeEnum, String imageName, Integer sortOrder) {
|
||||
byte[] fileData = null;
|
||||
try {
|
||||
@@ -2161,144 +2254,40 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
|
||||
|
||||
@Override
|
||||
public void editReportAndDownload(EditReportReq req, HttpServletResponse response) {
|
||||
Long userId = ThreadLocalContext.getUserId();
|
||||
log.info("编辑报告参数为:{}", req);
|
||||
Long userId = ThreadLocalContext.getUserId();
|
||||
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);
|
||||
|
||||
// 读取前端传入的指标表格数据,实现更新/替换/新增
|
||||
archivePerformances(reportContent, simulationTask.getUuid(), null, userId);
|
||||
}
|
||||
} else {
|
||||
SimulationRun simulationRun = this.lambdaQuery().eq(SimulationRun::getUuid, req.getRunId()).one();
|
||||
if (simulationRun != null) {
|
||||
// 算例绑定报告模板
|
||||
simulationRun.setReportTemplate(req.getReportTemplate());
|
||||
simulationRun.setReportContent(reportContent);
|
||||
this.updateById(simulationRun);
|
||||
// 1. 更新报告绑定,获取任务名称
|
||||
String taskName = updateReportBinding(req, userId);
|
||||
|
||||
// 读取前端传入的指标表格数据,实现更新/替换/新增
|
||||
archivePerformances(reportContent, simulationRun.getTaskId(), simulationRun.getUuid(), userId);
|
||||
}
|
||||
}
|
||||
|
||||
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("生成报告失败,原因为:创建临时文件夹失败");
|
||||
}
|
||||
}
|
||||
// 2. 创建临时文件夹
|
||||
String randomId = createTempReportFolder();
|
||||
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);
|
||||
|
||||
String reportName = "report_" +
|
||||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) +
|
||||
".docx";
|
||||
|
||||
// 构建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);
|
||||
command.add(reportName);
|
||||
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 {
|
||||
// 读取脚本生成的报告并归档
|
||||
archiveReportAndImage(reportName, req.getTaskId(), req.getRunId(), randomId, FileBizTypeEnum.REPORT_FILE, null, null);
|
||||
|
||||
// 读取脚本生成的图片并按顺序归档
|
||||
List<String> imageNames = extractPicNames(reportContent);
|
||||
if (CollectionUtils.isNotEmpty(imageNames)) {
|
||||
int sortOrder = 1;
|
||||
for (String imageName : imageNames) {
|
||||
archiveReportAndImage(null, req.getTaskId(), req.getRunId(), randomId, FileBizTypeEnum.CLOUD_FILE, imageName, sortOrder++);
|
||||
}
|
||||
}
|
||||
|
||||
FileInputStream fileInputStream = new FileInputStream(TEMP_REPORT_PATH + randomId + File.separator + reportName);
|
||||
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));
|
||||
// 3. 准备报告模板
|
||||
String originalName = prepareReportTemplate(req.getReportTemplate(), randomId);
|
||||
if (originalName == null) {
|
||||
throw new RuntimeException("获取报告模板失败");
|
||||
}
|
||||
|
||||
// 4. 生成报告名称(使用任务名称作为前缀)
|
||||
String reportName = generateReportName(taskName);
|
||||
|
||||
// 5. 构建并执行Python脚本
|
||||
String commands = buildModifyReportCommand(randomId, originalName, reportName);
|
||||
writeReportContentJson(randomId, reportContent);
|
||||
|
||||
SdmResponse executeResult = executePythonScriptWithTimeout(commands);
|
||||
if (!executeResult.isSuccess()) {
|
||||
throw new RuntimeException(executeResult.getMessage());
|
||||
}
|
||||
|
||||
// 6. 归档报告和图片
|
||||
archiveGeneratedReport(reportName, req.getTaskId(), req.getRunId(), randomId, reportContent);
|
||||
|
||||
// 7. 下载报告文件
|
||||
downloadReportFile(reportName, randomId, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3166,6 +3166,7 @@ public class TaskServiceImpl implements ITaskService {
|
||||
}
|
||||
taskVo.setNodeName(taskVo.getTaskName());
|
||||
taskVo.setNodeType("task");
|
||||
taskVo.setNodeCode(taskVo.getTaskCode());
|
||||
List<SpdmTaskMemberVo> memberList = mapper.getMemberList(Collections.singletonList(taskVo.getUuid()), null);
|
||||
if (CollectionUtils.isNotEmpty(memberList)) {
|
||||
List<Long> userIdList = memberList.stream().map(SpdmTaskMemberVo::getUserId).toList();
|
||||
|
||||
Reference in New Issue
Block a user