Merge remote-tracking branch 'origin/main'

This commit is contained in:
2025-12-04 14:26:42 +08:00
24 changed files with 520 additions and 214 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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 "";
}
}
}