Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package com.sdm.common.entity.req.pbs;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class HpcTaskFileDownReq {
|
||||
|
||||
@Schema(description = "任务ID")
|
||||
public String jobId;
|
||||
|
||||
@Schema(description = "文件名称")
|
||||
public String fileName;
|
||||
|
||||
@Schema(description = "文件大小")
|
||||
public Long fileSize;
|
||||
|
||||
}
|
||||
@@ -1,17 +1,15 @@
|
||||
package com.sdm.common.entity.req.pbs;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.sdm.common.entity.flowable.executeConfig.BaseExecuteConfig;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class SubmitHpcTaskRemoteReq extends BaseExecuteConfig {
|
||||
public class SubmitHpcTaskRemoteReq {
|
||||
|
||||
@Schema(description = "配置时的mm时间戳")
|
||||
public String timesmap;
|
||||
@@ -31,11 +29,13 @@ public class SubmitHpcTaskRemoteReq extends BaseExecuteConfig {
|
||||
@Schema(description = "计算任务是否独立存在 0:非独立任务 1:独立任务")
|
||||
public int independence;
|
||||
|
||||
@Schema(description = "求解文件,featchFileType =beforeNode 时传递")
|
||||
public List<String> inputFiles = new ArrayList<>();
|
||||
@Schema(description = "求解文件")
|
||||
@JSONField(serialize = false)
|
||||
public List<MultipartFile> inputFiles = new ArrayList<>();
|
||||
|
||||
@Schema(description = "计算主文件")
|
||||
public String masterFile;
|
||||
@JSONField(serialize = false)
|
||||
public MultipartFile masterFile;
|
||||
|
||||
@Schema(description = "计算任务所属任务ID")
|
||||
public String taskId;
|
||||
@@ -52,16 +52,19 @@ public class SubmitHpcTaskRemoteReq extends BaseExecuteConfig {
|
||||
@Schema(description = "执行的命令")
|
||||
public String command;
|
||||
|
||||
@Schema(description = "命令执行输出文件名xx.out")
|
||||
public String stdout;
|
||||
|
||||
@Schema(description = "任务所属项目")
|
||||
public String projectname;
|
||||
|
||||
@Schema(description = "获取文件的方式:上一节点:beforeNode,hpc节点(文件提前上传工作目录):hpcNode")
|
||||
public String featchFileType;
|
||||
// @Schema(description = "获取文件的方式:上一节点:beforeNode,hpc节点(文件提前上传工作目录):hpcNode")
|
||||
// public String featchFileType;
|
||||
//
|
||||
// @Schema(description = "上一节点Id,featchFileType:beforeNode时传递 ")
|
||||
// public String beforeNodeId;
|
||||
|
||||
@Schema(description = "上一节点Id,featchFileType:beforeNode时传递 ")
|
||||
public String beforeNodeId;
|
||||
|
||||
@Schema(description= "自定义占位符,只有列表展示使用,key 就是占位符")
|
||||
private Map<String,SimulationCommandPlaceholderReq> commandExpand;
|
||||
// @Schema(description= "自定义占位符,只有列表展示使用,key 就是占位符")
|
||||
// private Map<String,SimulationCommandPlaceholderReq> commandExpand;
|
||||
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.config.LongTimeRespFeignConfig;
|
||||
import com.sdm.common.entity.req.pbs.SubmitHpcTaskRemoteReq;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
|
||||
@FeignClient(
|
||||
@@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
public interface ITaskFeignClient {
|
||||
|
||||
// "作业提交"
|
||||
@PostMapping("/pbs/submitHpcJob")
|
||||
SdmResponse<String> submitHpcJob(@RequestBody SubmitHpcTaskRemoteReq req);
|
||||
@PostMapping(value = "/pbs/submitHpcJob", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
SdmResponse<String> submitHpcJob( SubmitHpcTaskRemoteReq req);
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,6 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
@FeignClient(name = "system",contextId = "systemMessageClient")
|
||||
public interface IMessageFeignClient {
|
||||
|
||||
@PostMapping("/systemMsg//sendMessage")
|
||||
@PostMapping("/systemMsg/sendMessage")
|
||||
SdmResponse sendMessage(@RequestBody SendMsgReq req);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.sdm.common.entity.req.system.UserQueryReq;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.common.feign.inter.system.ISysUserFeignClient;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -25,17 +26,18 @@ public class UserNameCacheService {
|
||||
@Cacheable(value = "userNames", key = "#userIds.toString()")
|
||||
public Map<Long, String> batchGetUserNames(Set<Long> userIds) {
|
||||
log.info("【缓存未命中】批量查询用户名,用户数量: {}", userIds.size());
|
||||
|
||||
Map<Long, String> userMap = new HashMap<>();
|
||||
// 批量调用用户服务
|
||||
SdmResponse<List<CIDUserResp>> response = sysUserFeignClient.listUserByIds(
|
||||
UserQueryReq.builder().userIds(new ArrayList<>(userIds)).build()
|
||||
);
|
||||
|
||||
Map<Long, String> userMap = response.getData().stream()
|
||||
.collect(Collectors.toMap(
|
||||
CIDUserResp::getUserId,
|
||||
CIDUserResp::getNickname
|
||||
));
|
||||
if (CollectionUtils.isNotEmpty(response.getData())) {
|
||||
userMap = response.getData().stream()
|
||||
.collect(Collectors.toMap(
|
||||
CIDUserResp::getUserId,
|
||||
CIDUserResp::getNickname
|
||||
));
|
||||
}
|
||||
|
||||
return userMap;
|
||||
}
|
||||
|
||||
@@ -9,12 +9,16 @@ 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.io.ByteArrayResource;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.MultipartBodyBuilder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
@@ -44,6 +48,9 @@ public class HpcCommandExcuteUtil {
|
||||
@Value("${hpc.remoteDownLoadFileUrl:}")
|
||||
private String remoteDownLoadFileUrl;
|
||||
|
||||
@Value("${hpc.remoteUploadFileUrl:}")
|
||||
private String remoteUploadFileUrl;
|
||||
|
||||
@Value("${hpc.callHpcUpload:}")
|
||||
private String callHpcUpload;
|
||||
|
||||
@@ -137,29 +144,31 @@ public class HpcCommandExcuteUtil {
|
||||
}
|
||||
|
||||
public ResponseEntity<StreamingResponseBody> hpcDownloadFile(String path, Long fileSize) {
|
||||
// 从 path 中提取文件名
|
||||
String fileName = extractFileName(path);
|
||||
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
|
||||
|
||||
StreamingResponseBody body = outputStream -> {
|
||||
// 构建完整 URL,并安全编码 path
|
||||
String url = remoteDownLoadFileUrl + "?path=" + URLEncoder.encode(path, StandardCharsets.UTF_8);
|
||||
|
||||
// 调用 B 服务并流式写出
|
||||
DataBufferUtils.write(
|
||||
webClient.get()
|
||||
.uri(remoteDownLoadFileUrl, path)
|
||||
.uri(url)
|
||||
.retrieve()
|
||||
.bodyToFlux(DataBuffer.class),
|
||||
Channels.newChannel(outputStream)
|
||||
).blockLast(); // 阻塞直到写完
|
||||
).blockLast();
|
||||
};
|
||||
|
||||
// 构建 ResponseEntity
|
||||
ResponseEntity.BodyBuilder builder = ResponseEntity.ok()
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
"attachment; filename*=UTF-8''" + encodedFileName)
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedFileName)
|
||||
.contentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||
|
||||
// 只有在 fileSize 合法时才设置 Content-Length
|
||||
if (fileSize != null && fileSize > 0) {
|
||||
builder.contentLength(fileSize);
|
||||
}
|
||||
|
||||
return builder.body(body);
|
||||
}
|
||||
|
||||
@@ -195,6 +204,31 @@ public class HpcCommandExcuteUtil {
|
||||
return lastSlash >= 0 ? path.substring(lastSlash + 1) : path;
|
||||
}
|
||||
|
||||
|
||||
// 调用工具上传hpc文件
|
||||
public String uploaHpcFile(MultipartFile file, String subDir) {
|
||||
try {
|
||||
// 3. Multipart body 构建
|
||||
MultipartBodyBuilder builder = new MultipartBodyBuilder();
|
||||
builder.part("file", new ByteArrayResource(file.getBytes()) {
|
||||
@Override
|
||||
public String getFilename() {
|
||||
return file.getOriginalFilename();
|
||||
}
|
||||
});
|
||||
builder.part("subDir", subDir);
|
||||
// 4. 调用 B 服务上传接口
|
||||
String uploadResult = webClient.post()
|
||||
.uri(remoteUploadFileUrl)
|
||||
.contentType(MediaType.MULTIPART_FORM_DATA)
|
||||
.body(BodyInserters.fromMultipartData(builder.build()))
|
||||
.retrieve()
|
||||
.bodyToMono(String.class)
|
||||
.block();
|
||||
return uploadResult;
|
||||
} catch (Exception e) {
|
||||
System.out.println("上传失败");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package com.sdm.flowable.delegate.handler;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.flowable.executeConfig.HPCExecuteConfig;
|
||||
import com.sdm.common.entity.req.pbs.SimulationCommandPlaceholderReq;
|
||||
import com.sdm.common.entity.req.pbs.SubmitHpcTaskRemoteReq;
|
||||
import com.sdm.common.feign.inter.pbs.ITaskFeignClient;
|
||||
import com.sdm.common.log.CoreLogger;
|
||||
import com.sdm.flowable.service.IAsyncTaskRecordService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -12,14 +17,14 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
// HPC(executeType=HPC)
|
||||
@Slf4j
|
||||
@Component("HPC")
|
||||
public class HpcHandler implements ExecutionHandler<SubmitHpcTaskRemoteReq,HPCExecuteConfig> {
|
||||
public class HpcHandler implements ExecutionHandler<Map<String, Object>,HPCExecuteConfig> {
|
||||
|
||||
@Autowired
|
||||
private IAsyncTaskRecordService asyncTaskRecordService;
|
||||
@@ -27,14 +32,19 @@ public class HpcHandler implements ExecutionHandler<SubmitHpcTaskRemoteReq,HPCEx
|
||||
@Autowired
|
||||
private ITaskFeignClient taskFeignClient;
|
||||
|
||||
/*
|
||||
* params:业务参数
|
||||
* config:框架属性
|
||||
* */
|
||||
@Override
|
||||
public void execute(DelegateExecution execution, SubmitHpcTaskRemoteReq params, HPCExecuteConfig config) {
|
||||
params.setBeforeNodeId(config.getBeforeNodeId());
|
||||
public void execute(DelegateExecution execution, Map<String, Object> params, HPCExecuteConfig config) {
|
||||
SubmitHpcTaskRemoteReq submitHpcTaskRemoteReq = convertParamsToReq(params);
|
||||
// submitHpcTaskRemoteReq.setBeforeNodeId(config.getBeforeNodeId());
|
||||
// 实现HPC处理逻辑...
|
||||
// INIT(初始化)/RUNNING(执行中)/SUCCESS(执行成功)/FAIL(执行失败)
|
||||
String status = "INIT";
|
||||
// 1. 调用 HPC 平台提交任务
|
||||
SdmResponse<String> submitResp = taskFeignClient.submitHpcJob(params);
|
||||
SdmResponse<String> submitResp = taskFeignClient.submitHpcJob(submitHpcTaskRemoteReq);
|
||||
if(!submitResp.isSuccess()|| StringUtils.isBlank(submitResp.getData())){
|
||||
log.error("HpcHandler submit failed,jobName:{}",params);
|
||||
status = "FAIL";
|
||||
@@ -53,17 +63,107 @@ public class HpcHandler implements ExecutionHandler<SubmitHpcTaskRemoteReq,HPCEx
|
||||
log.info("HPC 任务 {} 已提交", hpcTaskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将参数Map转换为SubmitHpcTaskRemoteReq对象的工具方法
|
||||
*/
|
||||
private SubmitHpcTaskRemoteReq convertParamsToReq(Map<String, Object> params) {
|
||||
SubmitHpcTaskRemoteReq req = new SubmitHpcTaskRemoteReq();
|
||||
if (params == null) {
|
||||
return req;
|
||||
}
|
||||
ObjectMapper objectMapper = new ObjectMapper(); // 需确保ObjectMapper已配置或注入
|
||||
// 基础字段映射
|
||||
req.setTimesmap(params.get("timesmap").toString());
|
||||
req.setJobName(params.get("jobName").toString());
|
||||
// 处理int类型字段,包含空值和非数字的异常处理
|
||||
try {
|
||||
req.setCoreNum(params.get("coreNum") != null ? Integer.parseInt(params.get("coreNum").toString()) : 0);
|
||||
} catch (NumberFormatException e) {
|
||||
CoreLogger.error("coreNum parse error:{},coreNum:{}",e.getMessage(),params.get("coreNum"));
|
||||
req.setCoreNum(0);
|
||||
}
|
||||
req.setSoftware(params.get("software").toString());
|
||||
req.setJobType(params.get("jobType").toString());
|
||||
try {
|
||||
req.setIndependence(params.get("independence") != null ? Integer.parseInt(params.get("independence").toString()) : 0);
|
||||
} catch (NumberFormatException e) {
|
||||
req.setIndependence(0);
|
||||
}
|
||||
req.setTaskId(params.get("taskId").toString());
|
||||
req.setTaskName(params.get("taskName").toString());
|
||||
req.setRunId(params.get("runId").toString());
|
||||
req.setRunName(params.get("runName").toString());
|
||||
req.setCommand(params.get("command").toString());
|
||||
req.setProjectname(params.get("projectname").toString());
|
||||
// req.setFeatchFileType(params.get("featchFileType").toString());
|
||||
// req.setBeforeNodeId(params.get("beforeNodeId").toString());
|
||||
// 处理commandExpand字段(JSON字符串转Map)
|
||||
String commandExpandJson = params.get("commandExpand").toString();
|
||||
if (StringUtils.isNotBlank(commandExpandJson)) {
|
||||
try {
|
||||
// 将JSON字符串转换为Map<String, SimulationCommandPlaceholderReq>
|
||||
Map<String, SimulationCommandPlaceholderReq> commandExpand = objectMapper.readValue(
|
||||
commandExpandJson,
|
||||
new TypeReference<Map<String, SimulationCommandPlaceholderReq>>() {}
|
||||
);
|
||||
// req.setCommandExpand(commandExpand);
|
||||
} catch (Exception e) {
|
||||
CoreLogger.error("convertParamsToReq error:{},params:{}",e.getMessage(), JSONObject.toJSONString(params));
|
||||
// 如设为null或空Map
|
||||
// req.setCommandExpand(new HashMap<>());
|
||||
}
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
|
||||
public String mockinit(){
|
||||
SubmitHpcTaskRemoteReq mockReq = mockSubmitHpcTaskReq();
|
||||
SdmResponse<String> submitResp = taskFeignClient.submitHpcJob(mockReq);
|
||||
if(!submitResp.isSuccess()|| StringUtils.isBlank(submitResp.getData())){
|
||||
log.error("HpcHandler submit failed,jobName:{}",mockReq.getJobName());
|
||||
System.out.println("失败");
|
||||
return "失败";
|
||||
}
|
||||
String hpcTaskId = submitResp.getData();
|
||||
return hpcTaskId;
|
||||
// SubmitHpcTaskRemoteReq mockReq = mockSubmitHpcTaskReq();
|
||||
// SdmResponse<String> submitResp = taskFeignClient.submitHpcJob(mockReq);
|
||||
// if(!submitResp.isSuccess()|| StringUtils.isBlank(submitResp.getData())){
|
||||
// log.error("HpcHandler submit failed,jobName:{}",mockReq.getJobName());
|
||||
// System.out.println("失败");
|
||||
// return "失败";
|
||||
// }
|
||||
// String hpcTaskId = submitResp.getData();
|
||||
Map<String, Object> params = getParams();
|
||||
HPCExecuteConfig hpcExecuteConfig = new HPCExecuteConfig();
|
||||
// todo `flowable`.`process_node_param`
|
||||
hpcExecuteConfig.setBeforeNodeId("uuid-node-8d3e61e7-1374-419c-9e46-210cb88c1113");
|
||||
execute(null,params,hpcExecuteConfig);
|
||||
return "ok";
|
||||
}
|
||||
|
||||
private Map<String,Object> getParams() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
// 基础字段
|
||||
params.put("timesmap", String.valueOf(System.currentTimeMillis())); // 示例时间戳(2025-07-29 00:00:00)
|
||||
params.put("jobName", "HPC-数据处理作业-"+ System.currentTimeMillis());
|
||||
params.put("coreNum", 32);
|
||||
params.put("software", "reta.exe");
|
||||
params.put("jobType", "流体动力学仿真");
|
||||
params.put("independence", 1);
|
||||
params.put("taskId", "123456");
|
||||
params.put("taskName", "锂电池热管理系统研发");
|
||||
params.put("runId", "55555");
|
||||
params.put("runName", "HPC-电池");
|
||||
// params.put("command", "\\\\CARSAFE\\share\\solver\\RLithium\\reta.exe -i %retaFile");
|
||||
params.put("command", "\\\\CARSAFE\\share\\solver\\RLithium\\reta.exe -i .\\model\\aa.xml");
|
||||
params.put("projectname", "新能源汽车锂电池安全性能优化项目");
|
||||
params.put("featchFileType", "hpcNode"); // 补充示例值
|
||||
params.put("beforeNodeId", null); // 示例空值
|
||||
// commandExpand去掉outName后的JSON字符串
|
||||
String commandExpandJson = "{\n" +
|
||||
" \"retaFile\": {\n" +
|
||||
" \"id\": 1,\n" +
|
||||
" \"keyEnName\": \"retaFile\",\n" +
|
||||
" \"keyCnName\": \"电池求解文件\",\n" +
|
||||
" \"valueType\": \"file_regex_match\",\n" +
|
||||
" \"inputValue\": \"*.jpg\"\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
params.put("commandExpand", commandExpandJson);
|
||||
return params;
|
||||
}
|
||||
|
||||
private SubmitHpcTaskRemoteReq mockSubmitHpcTaskReq() {
|
||||
@@ -76,8 +176,8 @@ public class HpcHandler implements ExecutionHandler<SubmitHpcTaskRemoteReq,HPCEx
|
||||
req.software = "reta.exe";
|
||||
req.jobType = "仿真计算";
|
||||
req.independence = 1; // 独立任务
|
||||
req.inputFiles = Arrays.asList("input1.dat", "input2.dat", "input3.dat");
|
||||
req.masterFile = "master.dat";
|
||||
// req.inputFiles = Arrays.asList("input1.dat", "input2.dat", "input3.dat");
|
||||
// req.masterFile = "master.dat";
|
||||
req.taskId = "TASKID_" + timestamp;
|
||||
req.taskName = "测试任务_" + timestamp;
|
||||
req.runId = "RUNID_" + timestamp;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: local
|
||||
active: yang
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.sdm.pbs.controller;
|
||||
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.req.pbs.HpcTaskFileDownReq;
|
||||
import com.sdm.common.entity.req.pbs.HpcTaskFileReq;
|
||||
import com.sdm.common.entity.req.pbs.SubmitHpcTaskRemoteReq;
|
||||
import com.sdm.common.entity.req.pbs.hpc.*;
|
||||
@@ -28,6 +29,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -71,9 +73,9 @@ public class TaskController implements ITaskFeignClient {
|
||||
return pbsService.queryHpcResource();
|
||||
}
|
||||
|
||||
@PostMapping("/submitHpcJob")
|
||||
@PostMapping(value = "/submitHpcJob", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
@Operation(summary = "作业提交")
|
||||
public SdmResponse<String> submitHpcJob(@RequestBody SubmitHpcTaskRemoteReq req) {
|
||||
public SdmResponse<String> submitHpcJob(SubmitHpcTaskRemoteReq req) {
|
||||
SubmitHpcTaskReq submitHpcTaskReq = new SubmitHpcTaskReq();
|
||||
BeanUtils.copyProperties(req,submitHpcTaskReq);
|
||||
return pbsService.submitHpcJob(submitHpcTaskReq);
|
||||
@@ -97,10 +99,10 @@ public class TaskController implements ITaskFeignClient {
|
||||
return pbsService.getJobResultFiles(req.getJobId(),req.getTargetDir());
|
||||
}
|
||||
|
||||
@GetMapping("/hpcDownloadFile")
|
||||
@PostMapping("/hpcDownloadFile")
|
||||
@Operation(summary = "作业下文件下载")
|
||||
ResponseEntity<StreamingResponseBody> hpcDownloadFile(@RequestParam String jobId,@RequestParam String fileName,@RequestParam Long fileSize) {
|
||||
return pbsService.downloadFile(jobId,fileName,fileSize);
|
||||
ResponseEntity<StreamingResponseBody> hpcDownloadFile(@RequestBody HpcTaskFileDownReq req) {
|
||||
return pbsService.downloadFile(req.getJobId(),req.getFileName(),req.getFileSize());
|
||||
}
|
||||
|
||||
@PostMapping("/queryJobs")
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.sdm.pbs.model.req;
|
||||
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -24,10 +26,18 @@ public class SubmitHpcTaskReq {
|
||||
public boolean independence;
|
||||
|
||||
@Schema(description = "求解文件")
|
||||
public List<String> inputFiles = new ArrayList<>();
|
||||
@JSONField(serialize = false)
|
||||
public List<MultipartFile> inputFiles = new ArrayList<>();
|
||||
|
||||
@Schema(description = "求解文件路径")
|
||||
public List<String> inputFilePaths = new ArrayList<>();
|
||||
|
||||
@Schema(description = "计算主文件")
|
||||
public String masterFile;
|
||||
@JSONField(serialize = false)
|
||||
public MultipartFile masterFile;
|
||||
|
||||
@Schema(description = "主文件上传后的路径")
|
||||
public String masterFilePath;
|
||||
|
||||
@Schema(description = "计算任务所属任务ID")
|
||||
public String taskId;
|
||||
@@ -44,6 +54,12 @@ public class SubmitHpcTaskReq {
|
||||
@Schema(description = "执行的命令")
|
||||
public String command;
|
||||
|
||||
@Schema(description = "命令执行输出文件名xx.out")
|
||||
public String stdout;
|
||||
|
||||
@Schema(description = "工作目录,代码逻辑生成,和求解主文件平级")
|
||||
public String workDir;
|
||||
|
||||
@Schema(description = "任务所属项目")
|
||||
public String projectname;
|
||||
|
||||
|
||||
@@ -34,12 +34,18 @@ public class HpcJobStatusScheduleExcutor implements Runnable{
|
||||
// Configuring,Queued,Running,Canceled,Finished,Failed
|
||||
// 查询 jobId非空, jobStatus非 Canceled,Failed 数据, Finished,文件可能传完,可能没有传递完
|
||||
List<SimulationJob> list = simulationJobService.lambdaQuery()
|
||||
.select(SimulationJob::getId,
|
||||
SimulationJob::getJobName,
|
||||
SimulationJob::getTaskId,
|
||||
SimulationJob::getRunId,
|
||||
SimulationJob::getJobId,
|
||||
SimulationJob::getJobStatus)
|
||||
.isNotNull(SimulationJob::getJobId)
|
||||
.notIn(SimulationJob::getJobStatus, "Canceled", "Failed")
|
||||
// 回传文件状态
|
||||
.notIn(SimulationJob::getFileStatus, "generating", "uploading")
|
||||
// 非上传中的,非回传结束的。JobStatus 结束 通知 uploading 只会有一次,回传失败后,人工改表修复
|
||||
.notIn(SimulationJob::getFileStatus, "uploading","finished")
|
||||
.list();
|
||||
if(CollectionUtils.isNotEmpty(list)){
|
||||
if(CollectionUtils.isEmpty(list)){
|
||||
log.info("HpcJobStatus query db data null");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class FinishedStatusHandler implements JobStatusHandler {
|
||||
try {
|
||||
// 过程结束修改
|
||||
SimulationJob newDbJob = simulationJobService.lambdaQuery().eq(SimulationJob::getId, simJob.getId()).one();
|
||||
newDbJob.setFileStatus(statusInfo.getJobStatus());
|
||||
newDbJob.setJobStatus(statusInfo.getJobStatus());
|
||||
newDbJob.setStartTime(statusInfo.getStartTime());
|
||||
newDbJob.setEndTime(statusInfo.getEndTime());
|
||||
newDbJob.setNodeName(statusInfo.getAllocatedNodes());
|
||||
|
||||
@@ -24,7 +24,8 @@ public class ProcessStatusHandler implements JobStatusHandler{
|
||||
try {
|
||||
// 过程中状态修改
|
||||
SimulationJob newDbJob = simulationJobService.lambdaQuery().eq(SimulationJob::getId, simJob.getId()).one();
|
||||
newDbJob.setFileStatus(statusInfo.getJobStatus());
|
||||
newDbJob.setJobStatus(statusInfo.getJobStatus());
|
||||
newDbJob.setFileStatus("generating");
|
||||
newDbJob.setStartTime(statusInfo.getStartTime());
|
||||
newDbJob.setEndTime(statusInfo.getEndTime());
|
||||
newDbJob.setNodeName(statusInfo.getAllocatedNodes());
|
||||
|
||||
@@ -118,7 +118,8 @@ public class HpcInstructionServiceImpl implements HpcInstructionService {
|
||||
String prefixStr = HpcCommandBuilderUtil.initAddJobPrefixStr(req.getJobId());
|
||||
AddJobParam addJobParam = new AddJobParam();
|
||||
BeanUtils.copyProperties(req, addJobParam);
|
||||
String targetWorkDir = addJobParam.getWorkdir() + "\\" + req.getJobId();
|
||||
// String targetWorkDir = addJobParam.getWorkdir() + "\\" + req.getJobId();
|
||||
String targetWorkDir = addJobParam.getWorkdir();
|
||||
Pair<Boolean, String> workDirPair = createDirIfNotExist(targetWorkDir);
|
||||
if(!workDirPair.getLeft()){
|
||||
AddJobResp addJobResp=new AddJobResp();
|
||||
|
||||
@@ -65,11 +65,8 @@ public class IPbsHpcServiceImpl implements IPbsService {
|
||||
newJobReq.setProjectname(req.getProjectname());
|
||||
AddJobReq addJobReq = new AddJobReq();
|
||||
addJobReq.setName(req.getRunName());
|
||||
// todo
|
||||
addJobReq.setStdout("1126.out");
|
||||
// todo
|
||||
addJobReq.setWorkdir("\\\\CARSAFE\\share\\spdm");
|
||||
// todo
|
||||
addJobReq.setStdout(req.getStdout());
|
||||
addJobReq.setWorkdir(req.getWorkDir());
|
||||
addJobReq.setCommand(req.getCommand());
|
||||
SubmitHpcJobReq submitHpcJobReq = new SubmitHpcJobReq();
|
||||
mergeSubmitHpcJobReq.setNewJobReq(newJobReq);
|
||||
|
||||
@@ -7,6 +7,8 @@ import com.github.pagehelper.PageInfo;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.common.entity.resp.pbs.hpc.FileNodeInfo;
|
||||
import com.sdm.common.log.CoreLogger;
|
||||
import com.sdm.common.utils.HpcCommandExcuteUtil;
|
||||
import com.sdm.common.utils.PageUtils;
|
||||
import com.sdm.pbs.model.bo.HpcJobStatusInfo;
|
||||
import com.sdm.pbs.model.bo.HpcResouceInfo;
|
||||
@@ -17,12 +19,14 @@ import com.sdm.pbs.model.req.JobFileCallBackReq;
|
||||
import com.sdm.pbs.model.req.QueryJobReq;
|
||||
import com.sdm.pbs.model.req.SubmitHpcTaskReq;
|
||||
import com.sdm.pbs.service.*;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -36,6 +40,9 @@ import java.util.stream.Collectors;
|
||||
@ConditionalOnProperty(name = "pbs.task.impl", havingValue = "hpc")
|
||||
public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
|
||||
@Autowired
|
||||
private HpcCommandExcuteUtil hpcCommandExcuteUtil;
|
||||
|
||||
// 正则匹配%后的单词(\w+ 匹配字母、数字、下划线)
|
||||
private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("%(\\w+)");
|
||||
|
||||
@@ -67,9 +74,24 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
|
||||
@Override
|
||||
public SdmResponse<String> submitHpcJob(SubmitHpcTaskReq req) {
|
||||
// SdmResponse<String> response = pbsService.submitHpcJob(req);
|
||||
// if(response.isSuccess()&&StringUtils.isNotEmpty(response.getData())) {
|
||||
String jobId = "8848";
|
||||
//1. 上传hpc主文件 及 其他文件
|
||||
MultipartFile masterFile = req.getMasterFile();
|
||||
String subDir = req.getJobName()+"\\"+System.currentTimeMillis();
|
||||
// webClient 调用上传,这个是主文件,求解算出的文件,及stdout文件都指定这个文件夹下面
|
||||
String masterFilePath = hpcCommandExcuteUtil.uploaHpcFile(masterFile,subDir);
|
||||
dealInputFiles(req,subDir);
|
||||
// 任务输出的文件夹
|
||||
String hpcOutPutDir = extractDirectory(masterFilePath);
|
||||
req.setWorkDir(hpcOutPutDir);
|
||||
// 前置处理 替换求解文件
|
||||
String formatCommand = String.format(req.getCommand(), masterFilePath);
|
||||
req.setCommand(formatCommand);
|
||||
req.setMasterFilePath(masterFilePath);
|
||||
SdmResponse<String> response = pbsService.submitHpcJob(req);
|
||||
String jobId="";
|
||||
if(response.isSuccess()&&StringUtils.isNotEmpty(response.getData())) {
|
||||
jobId = response.getData();
|
||||
}
|
||||
if(StringUtils.isNotEmpty(jobId)) {
|
||||
// 数据入库
|
||||
SimulationJob simulationJob = new SimulationJob();
|
||||
@@ -80,13 +102,15 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
simulationJob.setSoftware(req.getSoftware());
|
||||
simulationJob.setJobType(req.getJobType());
|
||||
simulationJob.setIndependence(req.isIndependence());
|
||||
simulationJob.setInputFiles(JSONObject.toJSONString(req.getInputFiles()));
|
||||
simulationJob.setMasterFile(req.getMasterFile());
|
||||
// simulationJob.setInputFiles(JSONObject.toJSONString(req.getInputFiles()));
|
||||
// 主文件位置 todo
|
||||
simulationJob.setMasterFile(req.getMasterFilePath());
|
||||
// 求解文件集合
|
||||
simulationJob.setInputFiles(JSONObject.toJSONString(req.getInputFilePaths()));
|
||||
simulationJob.setTaskId(req.getTaskId());
|
||||
simulationJob.setTaskName(req.getTaskName());
|
||||
simulationJob.setRunId(req.getRunId());
|
||||
simulationJob.setRunName(req.getRunName());
|
||||
|
||||
// 软件及文件关联
|
||||
simulationJob.setSoftwareId(req.getSoftwareId());
|
||||
// 下面的待定 todo
|
||||
@@ -94,11 +118,9 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
simulationJob.setJobId(jobId);
|
||||
// 没必要要
|
||||
simulationJob.setJobDetailId("todo");
|
||||
|
||||
// 文件路径 todo 共享目录+jobName(文件回传)+uuid,下面可能有多个文件
|
||||
simulationJob.setStdoutHpcFilePath("/hpc/shared/job001/uuid-123");
|
||||
simulationJob.setStdoutHpcFilePath(hpcOutPutDir);
|
||||
simulationJob.setStdoutSpdmFilePath("/minio/base/job001/uuid-123");
|
||||
|
||||
// todo 执行信息 定时任务回传的时候修改
|
||||
simulationJob.setNodeName("todo");
|
||||
simulationJob.setExecutCommand("ansys -b -input input.dat -output output.log");
|
||||
@@ -108,11 +130,10 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
simulationJob.setJobStatus("Configuring");
|
||||
// ? todo 没比要
|
||||
simulationJob.setSolverName("LS-DYNA");
|
||||
|
||||
// todo 执行信息 定时任务回传的时候修改
|
||||
simulationJob.setTotalKernelTime(3600000L);
|
||||
simulationJob.setTotalUserTime(7200000L);
|
||||
simulationJob.setTotalElapsedTime(9000L);
|
||||
simulationJob.setTotalKernelTime(null);
|
||||
simulationJob.setTotalUserTime(null);
|
||||
simulationJob.setTotalElapsedTime(null);
|
||||
|
||||
// 标识及状态
|
||||
simulationJob.setUuid("f81d4fae7dec11d0a76500a0c91e6bf6");
|
||||
@@ -129,6 +150,41 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
return SdmResponse.success(jobId);
|
||||
}
|
||||
|
||||
private void dealInputFiles(SubmitHpcTaskReq req, String subDir) {
|
||||
if(req.getInputFiles()==null|| CollectionUtils.isEmpty(req.getInputFiles())) {
|
||||
return;
|
||||
}
|
||||
List<MultipartFile> inputFiles = req.getInputFiles();
|
||||
List<String> list = new ArrayList<>();
|
||||
for (MultipartFile inputFile : inputFiles) {
|
||||
String inputFilePath = hpcCommandExcuteUtil.uploaHpcFile(inputFile,subDir);
|
||||
list.add(inputFilePath);
|
||||
}
|
||||
req.setInputFilePaths(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件路径中提取目录部分(包含最后一个路径分隔符)
|
||||
* @param fullPath 完整的文件路径
|
||||
* @return 目录路径(包含最后一个反斜杠),若路径为空或无分隔符则返回原路径
|
||||
*/
|
||||
private String extractDirectory(String fullPath) {
|
||||
// 校验参数
|
||||
if (fullPath == null || fullPath.isEmpty()) {
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
// 找到最后一个反斜杠的位置
|
||||
int lastSeparatorIndex = fullPath.lastIndexOf("\\");
|
||||
|
||||
// 若没有找到分隔符,返回原路径;否则截取到最后一个分隔符(包含)
|
||||
if (lastSeparatorIndex == -1) {
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
return fullPath.substring(0, lastSeparatorIndex + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse<Boolean> stopHpcJob(String jobId) {
|
||||
return pbsService.stopHpcJob(jobId);
|
||||
@@ -142,9 +198,22 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
|
||||
@Override
|
||||
public SdmResponse<List<FileNodeInfo>> getJobResultFiles(String jobId,String targetDir) {
|
||||
// todo 根据jobId 获取工作目录,共享目录+jobName(文件回传)+uuid,下面可能有多个文件
|
||||
String workDir = StringUtils.isNotBlank(targetDir) ? targetDir :"D:\\需求";
|
||||
SdmResponse<List<FileNodeInfo>> nodeInfos = pbsService.getJobResultFiles("", workDir);
|
||||
// 根据 jobId 获取工作信息
|
||||
SimulationJob simulationJob = simulationJobService.lambdaQuery()
|
||||
.eq(SimulationJob::getJobId, jobId)
|
||||
.one();
|
||||
// 选择 queryPath
|
||||
String queryPath;
|
||||
if (targetDir != null && !targetDir.isEmpty()) {
|
||||
queryPath = targetDir;
|
||||
} else if (simulationJob!=null&&simulationJob.getStdoutHpcFilePath() != null && !simulationJob.getStdoutHpcFilePath().isEmpty()) {
|
||||
queryPath = simulationJob.getStdoutHpcFilePath();
|
||||
} else {
|
||||
return SdmResponse.failed("查询路径为空,无法获取文件");
|
||||
}
|
||||
|
||||
// 调用 PBS 服务获取文件列表
|
||||
SdmResponse<List<FileNodeInfo>> nodeInfos = pbsService.getJobResultFiles("", queryPath);
|
||||
return nodeInfos;
|
||||
}
|
||||
|
||||
@@ -221,6 +290,7 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
|
||||
|
||||
public SdmResponse<Boolean> jobFileCallback(JobFileCallBackReq req) {
|
||||
CoreLogger.info("hpc jobFileCallback params:{}",JSONObject.toJSONString(req));
|
||||
if(!Objects.isNull(req)&&Objects.equals(req.getUploadResult(),"Y")) {
|
||||
// 回传成功
|
||||
SimulationJob newDbJob = simulationJobService.lambdaQuery().eq(SimulationJob::getJobId, req.getJobId()).one();
|
||||
|
||||
@@ -9,6 +9,17 @@ spring:
|
||||
password: mysql
|
||||
jdbc-url: jdbc:mysql://192.168.65.161:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
# 设置连接池能够容纳的最大连接数。建议值:CPU核心数 * 2 + 有效磁盘I/O数。一个常见的经验值是 10-20。
|
||||
maximum-pool-size: 20
|
||||
# 连接池在空闲时保持的最小连接数。
|
||||
minimum-idle: 5
|
||||
# 一个连接在被标记为空闲之前可以保持空闲状态的最长时间(毫秒)。当连接的空闲时间超过此值后,它可能会被连接池 evict(驱逐)。
|
||||
idle-timeout: 60000 # 1 min
|
||||
# 一个连接从被创建开始,其生命周期的最大时长(毫秒)。HikariCP的默认值就是30分钟,这是一个非常合理的设置。
|
||||
max-lifetime: 1800000 # 30 min(Hikari 默认)
|
||||
# 应用程序尝试从连接池获取一个连接时,等待的最长时间(毫秒)。建议值:30-60秒。
|
||||
connection-timeout: 30000 # 30s
|
||||
master:
|
||||
username: root
|
||||
password: mysql
|
||||
@@ -108,6 +119,8 @@ hpc:
|
||||
remoteCreateDirUrl: http://192.168.65.55:9097/createDir
|
||||
remoteScanDirUrl: http://192.168.65.55:9097/scanDir
|
||||
remoteDownLoadFileUrl: http://192.168.65.55:9097/hpcDownload
|
||||
# remoteDownLoadFileUrl: http://127.0.0.1:9097/hpcDownload
|
||||
remoteUploadFileUrl: http://192.168.65.55:9097/uploadHpcFile
|
||||
callHpcUpload: http://192.168.65.55:9097/addJobQueue
|
||||
|
||||
|
||||
|
||||
@@ -86,4 +86,6 @@ public interface SimulationNodeMapper extends BaseMapper<SimulationNode> {
|
||||
|
||||
List<WorkstationApproveStatusVo> getWorkstationApproveStatus(@Param("req") GetWorkstationApproveStatusReq req);
|
||||
|
||||
SpdmNodeVo getNodeByProjectIdAndName(@Param("projectId") String projectId, @Param("projectName") String projectName);
|
||||
|
||||
}
|
||||
|
||||
@@ -71,6 +71,9 @@ public class KeyResultReq extends BaseReq {
|
||||
@Schema(description = "文件")
|
||||
private MultipartFile file;
|
||||
|
||||
@Schema(description = "是否仅曲线上传文件")
|
||||
private boolean onlyFile;
|
||||
|
||||
/**
|
||||
* -------------------------------------------------上传交付物使用参数------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -158,7 +158,7 @@ public class DemandServiceImpl extends BaseService implements IDemandService {
|
||||
SdmResponse response = dataClientFeignClient.createDir(createDirReq);
|
||||
log.info("创建需求时,调用创建文件夹的返回值为:{}", response);
|
||||
|
||||
return SdmResponse.success(demandId);
|
||||
return SdmResponse.success(req.getUuid());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
|
||||
@@ -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,6 +126,8 @@ 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 ";
|
||||
|
||||
// 临时文件存储目录
|
||||
private final String tempFileDir = System.getProperty("user.dir") + "/csv_uploads/";
|
||||
|
||||
@@ -562,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();
|
||||
@@ -714,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();
|
||||
}
|
||||
@@ -744,7 +736,7 @@ public class SimulationRunServiceImpl extends ServiceImpl<SimulationRunMapper, S
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public SdmResponse addSimulationKeyResult(KeyResultReq req) {
|
||||
if (KeyResultTypeEnum.CURVE.getKeyResultType().equals(req.getKeyResultType())) {
|
||||
if (KeyResultTypeEnum.CURVE.getKeyResultType().equals(req.getKeyResultType()) && req.isOnlyFile()) {
|
||||
CurveParamDto curveParamDto = getCurveParamsFromUpload(req.getFile(), 2);
|
||||
return SdmResponse.success(curveParamDto);
|
||||
}
|
||||
@@ -907,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());
|
||||
@@ -947,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("发起评审失败");
|
||||
}
|
||||
@@ -960,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);
|
||||
@@ -983,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;
|
||||
@@ -994,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)
|
||||
@@ -1048,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);
|
||||
@@ -1077,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)) {
|
||||
@@ -1091,112 +1081,110 @@ 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);
|
||||
for (Long fileId : imageFileIdList) {
|
||||
dataFeignClient.downloadFileToLocal(fileId, TEMP_REPORT_PATH + randomId);
|
||||
}
|
||||
// 生成projectInfo.json
|
||||
// 父节点信息
|
||||
ProjecInfoReq projecInfoReq = req.getProjecInfoReq();
|
||||
if (ObjectUtils.isNotEmpty(projecInfoReq)) {
|
||||
projecInfoReq.setReportCommand("python /opt/script/exportWord.py /opt/script/project/dynamics1 /opt/script/template dynamics");
|
||||
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<PerformanceInfoReq> exportPerformanceList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(performanceList)) {
|
||||
PerformanceInfoReq performanceInfoReq = new PerformanceInfoReq();
|
||||
for (SimulationPerformance performance : performanceList) {
|
||||
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() : "");
|
||||
exportPerformanceList.add(performanceInfoReq);
|
||||
}
|
||||
String jsonString = JSON.toJSONString(exportPerformanceList);
|
||||
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("调用脚本中。。。。。。");
|
||||
String commands = "python /opt/script/exportWord.py " + TEMP_REPORT_PATH + randomId + File.separator;
|
||||
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));
|
||||
|
||||
}
|
||||
|
||||
@@ -1217,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);
|
||||
|
||||
@@ -1258,16 +1258,60 @@ public class TaskServiceImpl implements ITaskService {
|
||||
@Transactional
|
||||
@Override
|
||||
public BosimSaveProjectTaskRsp syncCidTask(SyncCidTaskReq req) {
|
||||
BosimSaveProjectTaskRsp resp = new BosimSaveProjectTaskRsp();
|
||||
String projectId = req.getProjectId();
|
||||
String projectName = req.getProjectName();
|
||||
if (StringUtils.isEmpty(projectId) || StringUtils.isEmpty(projectName)) {
|
||||
log.error("同步cid任务时,projectId或projectName为空");
|
||||
resp.setCode(String.valueOf(ResultCode.FAILED.getCode()));
|
||||
resp.setMessage(ResultCode.FAILED.getMessage());
|
||||
return resp;
|
||||
}
|
||||
String curDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
||||
// 查询是否已同步过项目
|
||||
SpdmNodeVo spdmNodeVo = nodeMapper.getNodeByProjectIdAndName(projectId,projectName);
|
||||
if (ObjectUtils.isNotEmpty(spdmNodeVo)) {
|
||||
SpdmProjectNodeEditReq spdmProjectNodeEditReq = new SpdmProjectNodeEditReq();
|
||||
spdmProjectNodeEditReq.setNodeName(req.getProjectName());
|
||||
spdmProjectNodeEditReq.setNodeType(NodeTypeEnum.PROJECT.getValue());
|
||||
spdmProjectNodeEditReq.setUuid(req.getProjectId());
|
||||
spdmProjectNodeEditReq.setPid(req.getProjectId());
|
||||
spdmProjectNodeEditReq.setTag1(req.getProjectId());
|
||||
spdmProjectNodeEditReq.setCreateTime(curDateStr);
|
||||
spdmProjectNodeEditReq.setTenantId(ThreadLocalContext.getTenantId());
|
||||
if (nodeMapper.addNodeBatch(Collections.singletonList(spdmProjectNodeEditReq)) <= 0) {
|
||||
log.error("同步CID项目:{}失败",req.getProjectId() + " " + req.getProjectName());
|
||||
resp.setCode(String.valueOf(ResultCode.FAILED.getCode()));
|
||||
resp.setMessage(ResultCode.FAILED.getMessage());
|
||||
return resp;
|
||||
}
|
||||
try {
|
||||
// 创建项目节点的文件夹
|
||||
SdmResponse response = createDir(spdmProjectNodeEditReq.getUuid(), spdmProjectNodeEditReq.getNodeType(), null, spdmProjectNodeEditReq.getNodeName());
|
||||
if (ObjectUtils.isEmpty(response) || response.getCode() != ResultCode.SUCCESS.getCode()) {
|
||||
log.error("同步CID项目:{}时,创建文件夹失败,原因为:{}",req.getProjectId() + " " + req.getProjectName(),response.getMessage());
|
||||
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||
resp.setCode(String.valueOf(ResultCode.FAILED.getCode()));
|
||||
resp.setMessage(ResultCode.FAILED.getMessage());
|
||||
return resp;
|
||||
}
|
||||
}catch (Exception ex) {
|
||||
log.error("同步CID项目:{}时,创建文件夹异常,原因为:{}",req.getProjectId() + " " + req.getProjectName(),ex.getMessage());
|
||||
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||
resp.setCode(String.valueOf(ResultCode.FAILED.getCode()));
|
||||
resp.setMessage(ResultCode.FAILED.getMessage());
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
|
||||
log.info("syncCidTask参数为:{}", req);
|
||||
List<ProjectTaskInfo> taskInfoList = req.getTaskInfoList();
|
||||
BosimSaveProjectTaskRsp resp = new BosimSaveProjectTaskRsp();
|
||||
if (CollectionUtils.isEmpty(taskInfoList)) {
|
||||
log.error("同步cid任务时,任务为空");
|
||||
resp.setCode(String.valueOf(ResultCode.FAILED.getCode()));
|
||||
resp.setMessage(ResultCode.FAILED.getMessage());
|
||||
return resp;
|
||||
}
|
||||
String curDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
||||
List<CidTaskNode> taskNodeList = new ArrayList<>();
|
||||
for (ProjectTaskInfo projectTaskInfo : taskInfoList) {
|
||||
CidTaskNode taskNode = new CidTaskNode();
|
||||
|
||||
@@ -578,4 +578,9 @@
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getNodeByProjectIdAndName" resultType="com.sdm.project.model.vo.SpdmNodeVo">
|
||||
select * from simulation_node where uuid = #{projectId} and nodeName = #{projectName} and nodeType = 'project' limit 1
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -53,7 +53,8 @@
|
||||
#{it.tag3,typeHandler=com.sdm.project.handler.ListStringTypeHandler},#{it.tag4,typeHandler=com.sdm.project.handler.ListStringTypeHandler},
|
||||
#{it.tag5,typeHandler=com.sdm.project.handler.ListStringTypeHandler},#{it.tag6,typeHandler=com.sdm.project.handler.ListStringTypeHandler},
|
||||
#{it.tag7,typeHandler=com.sdm.project.handler.ListStringTypeHandler},#{it.tag8,typeHandler=com.sdm.project.handler.ListStringTypeHandler},
|
||||
#{it.tag9,typeHandler=com.sdm.project.handler.ListStringTypeHandler},#{it.tag10,typeHandler=com.sdm.project.handler.ListStringTypeHandler}),#{it.imageFileId}
|
||||
#{it.tag9,typeHandler=com.sdm.project.handler.ListStringTypeHandler},#{it.tag10,typeHandler=com.sdm.project.handler.ListStringTypeHandler},
|
||||
#{it.imageFileId})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user