新增:hpc动态命令参数替换逻辑新增
This commit is contained in:
@@ -12,15 +12,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@Slf4j
|
||||
@@ -35,6 +31,29 @@ public class TaskAdapter implements ITaskFeignClient {
|
||||
@Autowired
|
||||
private TaskController taskController;
|
||||
|
||||
|
||||
@Value("${testEnStr:}")
|
||||
private String enStr;
|
||||
@Value("${testEnStr2:}")
|
||||
private String testEnStr2;
|
||||
|
||||
@Value("${pbs.task.impl}")
|
||||
private String pbsImpl;
|
||||
|
||||
@GetMapping("/testEn")
|
||||
@Operation(summary = "作业提交")
|
||||
public SdmResponse<Map<String,Object>> testEn() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("enStr", enStr);
|
||||
map.put("pbsImpl", pbsImpl);
|
||||
map.put("testEnStr2", testEnStr2);
|
||||
return SdmResponse.success(map);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@PostMapping("/adapterSubmitHpcJob")
|
||||
@Operation(summary = "作业提交")
|
||||
public SdmResponse<String> adapterSubmitHpcJob(@RequestBody SubmitHpcTaskRemoteReq req) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import com.sdm.common.utils.HpcCommandExcuteUtil;
|
||||
import com.sdm.pbs.model.bo.HpcJobStatusInfo;
|
||||
import com.sdm.pbs.model.bo.HpcResouceInfo;
|
||||
import com.sdm.pbs.model.entity.SimulationJob;
|
||||
import com.sdm.pbs.model.entity.SimulationSoftConfig;
|
||||
import com.sdm.pbs.model.entity.SimulationHpcCommand;
|
||||
import com.sdm.pbs.model.req.JobFileCallBackReq;
|
||||
import com.sdm.pbs.model.req.QueryJobReq;
|
||||
import com.sdm.pbs.model.req.SubmitHpcTaskReq;
|
||||
@@ -114,8 +114,8 @@ public class TaskController {
|
||||
|
||||
@GetMapping("/querySoftConfig")
|
||||
@Operation(summary = "spdm系统查询hpc求解器指令配置")
|
||||
SdmResponse<Map<String, List<SimulationSoftConfig>>> querySoftConfig (@RequestParam String softName) {
|
||||
return pbsServiceDecorator.querySoftConfig(softName);
|
||||
SdmResponse<SimulationHpcCommand> querySoftConfig (@RequestParam String appUuid) {
|
||||
return pbsServiceDecorator.querySoftConfig(appUuid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.sdm.pbs.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sdm.pbs.model.entity.SimulationCommandPlaceholder;
|
||||
import com.sdm.pbs.model.entity.SimulationHpcCommandPlaceholder;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -11,6 +11,6 @@ import com.sdm.pbs.model.entity.SimulationCommandPlaceholder;
|
||||
* @author author
|
||||
* @since 2025-11-05
|
||||
*/
|
||||
public interface SimulationCommandPlaceholderMapper extends BaseMapper<SimulationCommandPlaceholder> {
|
||||
public interface SimulationCommandPlaceholderMapper extends BaseMapper<SimulationHpcCommandPlaceholder> {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.sdm.pbs.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sdm.pbs.model.entity.SimulationSoftConfig;
|
||||
import com.sdm.pbs.model.entity.SimulationHpcCommand;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -11,6 +11,6 @@ import com.sdm.pbs.model.entity.SimulationSoftConfig;
|
||||
* @author author
|
||||
* @since 2025-11-05
|
||||
*/
|
||||
public interface SimulationSoftConfigMapper extends BaseMapper<SimulationSoftConfig> {
|
||||
public interface SimulationSoftConfigMapper extends BaseMapper<SimulationHpcCommand> {
|
||||
|
||||
}
|
||||
|
||||
11
pbs/src/main/java/com/sdm/pbs/model/bo/CommandResult.java
Normal file
11
pbs/src/main/java/com/sdm/pbs/model/bo/CommandResult.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package com.sdm.pbs.model.bo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class CommandResult {
|
||||
private String command;
|
||||
private String formatCommand;
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package com.sdm.pbs.model.entity;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 仿真工具命令占位符配置表
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2025-12-01
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@TableName("simulation_command_placeholder")
|
||||
@Schema(description = "仿真工具命令占位符配置表")
|
||||
public class SimulationCommandPlaceholder implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "自增主键")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "占位符英文名称")
|
||||
@TableField("keyEnName")
|
||||
private String keyEnName;
|
||||
|
||||
@Schema(description = "占位符中文名称")
|
||||
@TableField("keyCnName")
|
||||
private String keyCnName;
|
||||
|
||||
@Schema(description = "占位符值的类型(file_exact_match:文件完全匹配;file_regex_match:文件正则匹配," +
|
||||
"hpc_file_select:Hpc节点文件选择,hpc_file_regex_match:Hpc节点目录正则,local_file_select:本地文件选择,custom_input:用户自定义输入值")
|
||||
@TableField("valueType")
|
||||
private String valueType;
|
||||
|
||||
@Schema(description = "占位符的值,用户输入后赋值传递")
|
||||
@TableField(exist = false)
|
||||
private String inputValue="";
|
||||
|
||||
@Schema(description = "创建者ID")
|
||||
@TableField("creatorId")
|
||||
@JsonIgnore
|
||||
private Long creatorId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@TableField(value = "createTime", fill = FieldFill.INSERT)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonIgnore
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新者ID")
|
||||
@TableField("updaterId")
|
||||
@JsonIgnore
|
||||
private Long updaterId;
|
||||
|
||||
@Schema(description = "修改时间")
|
||||
@TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonIgnore
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.sdm.pbs.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -9,6 +10,7 @@ import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -22,9 +24,9 @@ import java.util.Map;
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@TableName("simulation_soft_config")
|
||||
@Schema(description = "仿真软件命令配置表")
|
||||
public class SimulationSoftConfig implements Serializable {
|
||||
@TableName("simulation_hpc_command")
|
||||
@Schema(description = "仿真软件hpc命令配置表")
|
||||
public class SimulationHpcCommand implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -32,42 +34,55 @@ public class SimulationSoftConfig implements Serializable {
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "软件名称")
|
||||
@TableField("softName")
|
||||
@Schema(description = "app注册的Id")
|
||||
@TableField(value = "appUuid",select = true)
|
||||
private String appUuid;
|
||||
|
||||
@Schema(description = "软件名称,对应的simulation_app_repository的appName,名字建议格式appName_v1")
|
||||
@TableField(value = "softName",select = true)
|
||||
private String softName;
|
||||
|
||||
@Schema(description = "软件版本号")
|
||||
@TableField("softVersion")
|
||||
@TableField(value = "softVersion",select = true)
|
||||
private String softVersion;
|
||||
|
||||
@Schema(description = "功能描述(如:电池仿真)")
|
||||
@TableField("functionDsc")
|
||||
@TableField(value = "functionDsc",select = true)
|
||||
private String functionDsc;
|
||||
|
||||
@Schema(description = "功能对应的CMD命令")
|
||||
@TableField("command")
|
||||
@TableField(value = "command",select = true)
|
||||
private String command;
|
||||
|
||||
@Schema(description = "预留-软件执行完成后筛选回传文件正则,用于过滤回传文件")
|
||||
@TableField(value = "postFileRegular",select = true)
|
||||
@JsonIgnore
|
||||
private String postFileRegular;
|
||||
|
||||
@Schema(description = "创建者ID")
|
||||
@TableField("creatorId")
|
||||
@TableField(value = "creatorId",select = true)
|
||||
@JsonIgnore
|
||||
private Long creatorId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@TableField(value = "createTime", fill = FieldFill.INSERT)
|
||||
@TableField(value = "createTime", fill = FieldFill.INSERT,select = true)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonIgnore
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新者ID")
|
||||
@TableField("updaterId")
|
||||
@TableField(value = "updaterId",select = false)
|
||||
@JsonIgnore
|
||||
private Long updaterId;
|
||||
|
||||
@Schema(description = "修改时间")
|
||||
@TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE)
|
||||
@TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE,select = false)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonIgnore
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description= "自定义占位符,只有列表展示使用,key 就是占位符")
|
||||
@TableField(value = "commandExpand", insertStrategy = FieldStrategy.NEVER,select = false,updateStrategy = FieldStrategy.NEVER)
|
||||
private Map<String,SimulationCommandPlaceholder> commandExpand;
|
||||
@Schema(description = "命令动态扩展的数据,SimulationHpcCommandPlaceholder对象")
|
||||
@TableField(exist = false)
|
||||
private Map<String,Object>commandExpand = new HashMap<>();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.sdm.pbs.model.entity;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 仿真工具命令占位符配置表
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2025-12-01
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@TableName("simulation_hpc_command_placeholder")
|
||||
@Schema(description = "仿真工具hpc命令占位符配置表")
|
||||
public class SimulationHpcCommandPlaceholder implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "自增主键")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@JsonIgnore
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "app注册的Id")
|
||||
@TableField(value = "appUuid",select = true)
|
||||
private String appUuid;
|
||||
|
||||
@Schema(description = "占位符英文名称")
|
||||
@TableField(value = "keyEnName",select = true)
|
||||
private String keyEnName;
|
||||
|
||||
@Schema(description = "占位符中文名称")
|
||||
@TableField(value = "keyCnName",select = true)
|
||||
private String keyCnName;
|
||||
|
||||
@Schema(description = "占位符值的类型(file:共享云盘文件;input:用户自定义输入)")
|
||||
@TableField(value = "valueType",select = true)
|
||||
private String valueType;
|
||||
|
||||
@Schema(description = "是否展示(Y:是,N:否),N时必须填写默认值")
|
||||
@TableField(value = "isDisplay",select = true)
|
||||
@JsonIgnore
|
||||
private String isDisplay;
|
||||
|
||||
@Schema(description = "是否拼接(Y:是,N:否),N时不用拼接到命令")
|
||||
@TableField(value = "featchType",select = true)
|
||||
@JsonIgnore
|
||||
private String featchType;
|
||||
|
||||
@Schema(description = "默认值:valueType为file且isDisplay为N时必填")
|
||||
@TableField(value = "defaultValue",select = true)
|
||||
@JsonIgnore
|
||||
private String defaultValue;
|
||||
|
||||
@Schema(description = "文件正则表达式:valueType为file时必填,用于过滤对应的求解文件")
|
||||
@TableField(value = "fileRegular",select = true)
|
||||
@JsonIgnore
|
||||
private String fileRegular;
|
||||
|
||||
@Schema(description = "创建者ID")
|
||||
@TableField(value = "creatorId",select = false)
|
||||
@JsonIgnore
|
||||
private Long creatorId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@TableField(value = "createTime", fill = FieldFill.INSERT,select = false)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonIgnore
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新者ID")
|
||||
@TableField(value = "updaterId",select = false)
|
||||
@JsonIgnore
|
||||
private Long updaterId;
|
||||
|
||||
@Schema(description = "修改时间")
|
||||
@TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE,select = false)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonIgnore
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description = "占位符的值,显示给用户的字段,用户输入后赋值传递")
|
||||
@TableField(exist = false)
|
||||
private String inputValue = "";
|
||||
|
||||
}
|
||||
@@ -77,7 +77,7 @@ public class SimulationJob implements Serializable {
|
||||
|
||||
@Schema(description = "使用软件的id")
|
||||
@TableField("softwareId")
|
||||
private Long softwareId;
|
||||
private String softwareId;
|
||||
|
||||
@Schema(description = "求解文件对应的文件Id")
|
||||
@TableField("inputFileId")
|
||||
|
||||
@@ -7,6 +7,8 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class SubmitHpcTaskReq {
|
||||
|
||||
@@ -64,7 +66,7 @@ public class SubmitHpcTaskReq {
|
||||
public String projectname;
|
||||
|
||||
@Schema(description = "软件的id")
|
||||
public Long softwareId;
|
||||
public String softwareId;
|
||||
|
||||
@Schema(description = "计算任务回传minio的路径")
|
||||
public String stdoutSpdmMinoFilePath;
|
||||
@@ -78,5 +80,7 @@ public class SubmitHpcTaskReq {
|
||||
@Schema(description = "求解文件本地路径,spdm工作流引擎会传递过来")
|
||||
public List<String> inputFileLocalPaths = new ArrayList<>();
|
||||
|
||||
@Schema(description = "任务流用户传递的参数,用于动态替换命令")
|
||||
private Map<String,Object> params;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.sdm.pbs.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sdm.pbs.model.entity.SimulationCommandPlaceholder;
|
||||
import com.sdm.pbs.model.entity.SimulationHpcCommandPlaceholder;
|
||||
|
||||
public interface ISimulationCommandPlaceholderService extends IService<SimulationCommandPlaceholder> {
|
||||
public interface ISimulationCommandPlaceholderService extends IService<SimulationHpcCommandPlaceholder> {
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.sdm.pbs.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sdm.pbs.model.entity.SimulationSoftConfig;
|
||||
import com.sdm.pbs.model.entity.SimulationHpcCommand;
|
||||
|
||||
public interface ISimulationSoftConfigService extends IService<SimulationSoftConfig> {
|
||||
public interface ISimulationSoftConfigService extends IService<SimulationHpcCommand> {
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ package com.sdm.pbs.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sdm.pbs.dao.SimulationCommandPlaceholderMapper;
|
||||
import com.sdm.pbs.model.entity.SimulationCommandPlaceholder;
|
||||
import com.sdm.pbs.model.entity.SimulationHpcCommandPlaceholder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SimulationCommandPlaceholderServiceImpl extends ServiceImpl<SimulationCommandPlaceholderMapper, SimulationCommandPlaceholder> implements ISimulationCommandPlaceholderService {
|
||||
public class SimulationCommandPlaceholderServiceImpl extends ServiceImpl<SimulationCommandPlaceholderMapper, SimulationHpcCommandPlaceholder> implements ISimulationCommandPlaceholderService {
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.sdm.pbs.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
@@ -15,17 +16,20 @@ 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;
|
||||
import com.sdm.common.log.CoreLogger;
|
||||
import com.sdm.common.utils.CommandReplaceUtil;
|
||||
import com.sdm.common.utils.HpcCommandExcuteUtil;
|
||||
import com.sdm.common.utils.PageUtils;
|
||||
import com.sdm.pbs.model.bo.CommandResult;
|
||||
import com.sdm.pbs.model.bo.HpcJobStatusInfo;
|
||||
import com.sdm.pbs.model.bo.HpcResouceInfo;
|
||||
import com.sdm.pbs.model.entity.SimulationCommandPlaceholder;
|
||||
import com.sdm.pbs.model.entity.SimulationHpcCommand;
|
||||
import com.sdm.pbs.model.entity.SimulationHpcCommandPlaceholder;
|
||||
import com.sdm.pbs.model.entity.SimulationJob;
|
||||
import com.sdm.pbs.model.entity.SimulationSoftConfig;
|
||||
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 lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -37,11 +41,14 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@Qualifier("decoratorPbsService")
|
||||
@ConditionalOnProperty(name = "pbs.task.impl", havingValue = "hpc")
|
||||
@@ -89,46 +96,139 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
public SdmResponse<String> submitHpcJob(SubmitHpcTaskReq req) {
|
||||
//1. 上传hpc主文件 及 其他文件
|
||||
MultipartFile masterFile = req.getMasterFile();
|
||||
// hpc共享机器+ subDir 这个就确定是工作目录了
|
||||
String subDir = req.getJobName()+"\\"+System.currentTimeMillis();
|
||||
// 获取hpc的工作目录
|
||||
String subDir = generateHpcSubDir(req);
|
||||
// webClient 调用上传,这个是主文件,求解算出的文件,及stdout文件都指定这个文件夹下面
|
||||
String masterFilePath = hpcCommandExcuteUtil.uploaHpcFile(masterFile,subDir);
|
||||
dealInputFiles(req,subDir);
|
||||
String masterFilePath = hpcCommandExcuteUtil.uploaHpcFile(masterFile, subDir);
|
||||
req.setMasterFilePath(masterFilePath);
|
||||
// 上传从文件
|
||||
dealInputFiles(req, subDir);
|
||||
// 任务输出的文件夹
|
||||
String hpcOutPutDir = extractDirectory(masterFilePath);
|
||||
req.setWorkDir(hpcOutPutDir);
|
||||
// 前置处理 替换求解文件
|
||||
String command="";
|
||||
if(StringUtils.isNotBlank(req.getCommand())) {
|
||||
command=req.getCommand();
|
||||
}else {
|
||||
SimulationSoftConfig simulationSoftConfig = simulationSoftConfigService.lambdaQuery().
|
||||
eq(SimulationSoftConfig::getSoftName,req.getSoftware()).one();
|
||||
command = simulationSoftConfig.getCommand();
|
||||
// 2.处理命令拼接和参数替换
|
||||
CommandResult commandResult = buildAndReplaceHpcCommand(req, masterFilePath);
|
||||
if (StringUtils.isBlank(commandResult.getCommand())) {
|
||||
log.error("Hpc执行失败,command命令不能为空{}",JSONObject.toJSONString(req));
|
||||
throw new RuntimeException("Hpc执行失败,command命令不能为空");
|
||||
}
|
||||
if(StringUtils.isBlank(command)) {
|
||||
return SdmResponse.failed("command命令不能为空,软件名称:"+req.getSoftware());
|
||||
}
|
||||
// 处理 拼接命令 \\CARSAFE\share\solver\RLithium\reta.exe -i %s
|
||||
String formatCommand = String.format(command, masterFilePath);
|
||||
req.setCommand(formatCommand);
|
||||
req.setMasterFilePath(masterFilePath);
|
||||
req.setCommand(commandResult.getFormatCommand());
|
||||
|
||||
// 3. 提交
|
||||
SdmResponse<String> response = pbsService.submitHpcJob(req);
|
||||
String jobId="";
|
||||
if(response.isSuccess()&&StringUtils.isNotEmpty(response.getData())) {
|
||||
String jobId = "";
|
||||
if (response.isSuccess() && StringUtils.isNotEmpty(response.getData())) {
|
||||
jobId = response.getData();
|
||||
}
|
||||
if(StringUtils.isNotEmpty(jobId)) {
|
||||
if(StringUtils.isNotEmpty(jobId)){
|
||||
log.error("Hpc执行失败返回结果:{}",JSONObject.toJSONString(response));
|
||||
throw new RuntimeException("Hpc执行失败,返回jobId空");
|
||||
}
|
||||
// 4. 保存任务信息到数据库
|
||||
saveSimulationJobToDb(req, jobId, hpcOutPutDir, commandResult.getCommand());
|
||||
return SdmResponse.success(jobId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成HPC任务的工作子目录路径(简化版)
|
||||
* 目录规则:用户ID(非空时)\任务名称\时间戳
|
||||
* @param req 提交HPC任务的请求参数
|
||||
* @return 拼接好的子目录字符串
|
||||
*/
|
||||
private String generateHpcSubDir(SubmitHpcTaskReq req) {
|
||||
Long userId = ThreadLocalContext.getUserId();
|
||||
log.info("Hpc任务执行开始,用户id:{}", userId);
|
||||
// 拼接逻辑
|
||||
String subDirPrefix = Objects.isNull(userId) ? "" : (String.valueOf(userId) + "\\");
|
||||
String subDir = subDirPrefix + req.getJobName() + "\\" + System.currentTimeMillis();
|
||||
return subDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建并替换HPC命令中的动态参数
|
||||
* @param req 任务请求参数
|
||||
* @param masterFilePath 主文件路径
|
||||
* @return 包含原始命令和格式化命令的结果对象
|
||||
*/
|
||||
private CommandResult buildAndReplaceHpcCommand(SubmitHpcTaskReq req, String masterFilePath) {
|
||||
String command = "";
|
||||
String formatCommand = "";
|
||||
|
||||
// 优先使用传递的command,然后替换求解文件即可
|
||||
if (StringUtils.isNotBlank(req.getCommand())) {
|
||||
command = req.getCommand();
|
||||
// 处理 拼接命令 \\CARSAFE\share\solver\RLithium\reta.exe -i %s
|
||||
formatCommand = String.format(command, masterFilePath);
|
||||
} else {
|
||||
// 命令
|
||||
SimulationHpcCommand simulationHpcCommand = simulationSoftConfigService.lambdaQuery()
|
||||
.eq(SimulationHpcCommand::getAppUuid, req.getSoftwareId()).one();
|
||||
// 动态参数
|
||||
List<SimulationHpcCommandPlaceholder> placeholders = simulationCommandPlaceholderService.lambdaQuery()
|
||||
.eq(SimulationHpcCommandPlaceholder::getAppUuid, req.getSoftwareId())
|
||||
.list();
|
||||
// 配置在表中的包含动态参数的命令
|
||||
if (ObjectUtil.isNull(simulationHpcCommand) || StringUtils.isBlank(simulationHpcCommand.getCommand())) {
|
||||
throw new RuntimeException("该应用没有初始化配置command");
|
||||
}
|
||||
command = simulationHpcCommand.getCommand();
|
||||
|
||||
// 命令中动态参数的处理替换
|
||||
for (SimulationHpcCommandPlaceholder placeholder : placeholders) {
|
||||
String keyEnName = placeholder.getKeyEnName();
|
||||
Object replaceValue = null;
|
||||
|
||||
// 用户手动输入
|
||||
if (Objects.equals(placeholder.getFeatchType(), "input")) {
|
||||
replaceValue = req.getParams().get(keyEnName);
|
||||
// 用户输入是空就使用配置的默认值
|
||||
if (ObjectUtil.isNull(replaceValue)) { // 修复原代码的判断逻辑错误
|
||||
log.warn("Hpc命令动态参数替换,用户输入是空,参数名:{}", keyEnName);
|
||||
replaceValue = placeholder.getDefaultValue();
|
||||
}
|
||||
}
|
||||
// 入参
|
||||
else if (Objects.equals(placeholder.getFeatchType(), "param")) {
|
||||
replaceValue = CommandReplaceUtil.getFieldValue(req, keyEnName);
|
||||
if (ObjectUtil.isNull(replaceValue)) { // 修复原代码的判断逻辑错误
|
||||
log.warn("Hpc命令动态参数替换,入参反射是空,参数名:{}", keyEnName);
|
||||
replaceValue = placeholder.getDefaultValue();
|
||||
}
|
||||
}
|
||||
// 默认兜底,比如从文件 就是null,最后命令就不拼接从文件
|
||||
else if (Objects.equals(placeholder.getFeatchType(), "default")) {
|
||||
replaceValue = placeholder.getDefaultValue();
|
||||
if (ObjectUtil.isNull(replaceValue)) { // 修复原代码的判断逻辑错误
|
||||
log.warn("Hpc命令动态参数替换,默认值是空,参数名:{}", keyEnName);
|
||||
}
|
||||
}
|
||||
|
||||
command = CommandReplaceUtil.replaceCommandPlaceholder(command, keyEnName, replaceValue);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandResult(command, formatCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存模拟任务信息到数据库
|
||||
* @param req 任务请求参数
|
||||
* @param jobId 任务ID
|
||||
* @param hpcOutPutDir 输出目录
|
||||
* @param command 执行命令
|
||||
*/
|
||||
private void saveSimulationJobToDb(SubmitHpcTaskReq req, String jobId, String hpcOutPutDir, String command) {
|
||||
if (StringUtils.isNotEmpty(jobId)) {
|
||||
// 数据入库
|
||||
SimulationJob simulationJob = new SimulationJob();
|
||||
// 基础字段
|
||||
// simulationJob.setId(1L);
|
||||
// simulationJob.setId(1L);
|
||||
simulationJob.setJobName(req.getJobName());
|
||||
simulationJob.setCoreNum(req.getCoreNum());
|
||||
simulationJob.setSoftware(req.getSoftware());
|
||||
simulationJob.setJobType(req.getJobType());
|
||||
simulationJob.setIndependence(req.isIndependence());
|
||||
// simulationJob.setInputFiles(JSONObject.toJSONString(req.getInputFiles()));
|
||||
// simulationJob.setInputFiles(JSONObject.toJSONString(req.getInputFiles()));
|
||||
// 主文件位置
|
||||
simulationJob.setMasterFile(req.getMasterFilePath());
|
||||
// 求解文件集合
|
||||
@@ -140,20 +240,20 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
// 软件及文件关联
|
||||
simulationJob.setSoftwareId(req.getSoftwareId());
|
||||
// 下面的待定
|
||||
// simulationJob.setInputFileId(null);
|
||||
// simulationJob.setInputFileId(null);
|
||||
simulationJob.setJobId(jobId);
|
||||
// 没必要要
|
||||
// simulationJob.setJobDetailId("");
|
||||
// simulationJob.setJobDetailId("");
|
||||
// 文件路径 共享目录+jobName(文件回传)+uuid,下面可能有多个文件
|
||||
simulationJob.setStdoutHpcFilePath(hpcOutPutDir);
|
||||
simulationJob.setStdoutSpdmMinoFilePath(req.getStdoutSpdmMinoFilePath());
|
||||
simulationJob.setStdoutSpdmNasFilePath(req.getStdoutSpdmNasFilePath());
|
||||
// 执行信息 定时任务回传的时候修改
|
||||
// simulationJob.setNodeName("");
|
||||
// simulationJob.setNodeName("");
|
||||
simulationJob.setExecutCommand(command);
|
||||
// 执行信息 定时任务回传的时候修改
|
||||
// simulationJob.setStartTime("2025-11-30 10:00:00");
|
||||
// simulationJob.setEndTime("2025-11-30 12:30:00");
|
||||
// simulationJob.setStartTime("2025-11-30 10:00:00");
|
||||
// simulationJob.setEndTime("2025-11-30 12:30:00");
|
||||
simulationJob.setJobStatus("Configuring");
|
||||
// 求解器名称
|
||||
simulationJob.setSolverName(req.getSoftware());
|
||||
@@ -162,12 +262,12 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
simulationJob.setTotalUserTime(null);
|
||||
simulationJob.setTotalElapsedTime(null);
|
||||
// 标识及状态
|
||||
// simulationJob.setUuid(null);
|
||||
// simulationJob.setUuid(null);
|
||||
simulationJob.setFileStatus("generating");
|
||||
// 审计字段
|
||||
Long userId = ThreadLocalContext.getUserId();
|
||||
Long tenantId = ThreadLocalContext.getTenantId();
|
||||
CoreLogger.info("submitHpcJob save db userId:{},tenantId:{}",userId,tenantId);
|
||||
CoreLogger.info("submitHpcJob save db userId:{},tenantId:{}", userId, tenantId);
|
||||
simulationJob.setCreatorId(userId);
|
||||
simulationJob.setTenantId(tenantId);
|
||||
simulationJob.setCreateTime(LocalDateTime.now());
|
||||
@@ -175,9 +275,147 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
simulationJob.setUpdateTime(LocalDateTime.now());
|
||||
simulationJobService.save(simulationJob);
|
||||
}
|
||||
return SdmResponse.success(jobId);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public SdmResponse<String> submitHpcJob(SubmitHpcTaskReq req) {
|
||||
// //1. 上传hpc主文件 及 其他文件
|
||||
// MultipartFile masterFile = req.getMasterFile();
|
||||
// // hpc共享机器+ subDir 这个就确定是工作目录了 todo 加上用户目录
|
||||
// String subDir = req.getJobName()+"\\"+System.currentTimeMillis();
|
||||
// // webClient 调用上传,这个是主文件,求解算出的文件,及stdout文件都指定这个文件夹下面
|
||||
// String masterFilePath = hpcCommandExcuteUtil.uploaHpcFile(masterFile,subDir);
|
||||
// req.setMasterFilePath(masterFilePath);
|
||||
// // 上传从文件
|
||||
// dealInputFiles(req,subDir);
|
||||
// // 任务输出的文件夹
|
||||
// String hpcOutPutDir = extractDirectory(masterFilePath);
|
||||
// req.setWorkDir(hpcOutPutDir);
|
||||
// // 前置处理 替换求解文件
|
||||
// String command="";
|
||||
// String formatCommand="";
|
||||
// // 优先使用传递的command,然后替换求解文件即可
|
||||
// if(StringUtils.isNotBlank(req.getCommand())) {
|
||||
// command=req.getCommand();
|
||||
// // 处理 拼接命令 \\CARSAFE\share\solver\RLithium\reta.exe -i %s
|
||||
// formatCommand = String.format(command, masterFilePath);
|
||||
// }else {
|
||||
// // 命令
|
||||
// SimulationHpcCommand simulationHpcCommand = simulationSoftConfigService.lambdaQuery().
|
||||
// eq(SimulationHpcCommand::getAppRepositoryId,req.getAppRepositoryId()).one();
|
||||
// // 动态参数
|
||||
// List<SimulationHpcCommandPlaceholder> placeholders = simulationCommandPlaceholderService.lambdaQuery()
|
||||
// .eq(SimulationHpcCommandPlaceholder::getAppRepositoryId, req.getAppRepositoryId())
|
||||
// .list();
|
||||
// // 配置在表中的包含动态参数的命令
|
||||
// if(ObjectUtil.isNull(simulationHpcCommand)||StringUtils.isBlank(simulationHpcCommand.getCommand())) {
|
||||
// throw new RuntimeException("该应用没有初始化配置command");
|
||||
// }
|
||||
// command = simulationHpcCommand.getCommand();
|
||||
// // 命令中动态参数的处理替换
|
||||
// for(SimulationHpcCommandPlaceholder placeholder : placeholders) {
|
||||
// String keyEnName = placeholder.getKeyEnName();
|
||||
// // 用户手动输入
|
||||
// if(Objects.equals(placeholder.getFeatchType(),"input")) {
|
||||
// Object value = req.getParams().get(keyEnName);
|
||||
// // 用户输入是空就使用配置的默认值
|
||||
// if(ObjectUtil.isNotNull(value)) {
|
||||
// log.warn("Hpc命令动态参数替换,用户输入是空,参数名:{}",keyEnName);
|
||||
// value=placeholder.getDefaultValue();
|
||||
// }
|
||||
// command = CommandReplaceUtil.replaceCommandPlaceholder(command, keyEnName, value);
|
||||
// }
|
||||
// // 入参
|
||||
// if(Objects.equals(placeholder.getFeatchType(),"param")) {
|
||||
// Object fieldValue = CommandReplaceUtil.getFieldValue(req, keyEnName);
|
||||
// if(ObjectUtil.isNotNull(fieldValue)) {
|
||||
// log.warn("Hpc命令动态参数替换,入参反射是空,参数名:{}",keyEnName);
|
||||
// fieldValue=placeholder.getDefaultValue();
|
||||
// }
|
||||
// command = CommandReplaceUtil.replaceCommandPlaceholder(command, keyEnName, fieldValue);
|
||||
// }
|
||||
// // 默认兜底,比如从文件 就是null,最后命令就不拼接从文件
|
||||
// if(Objects.equals(placeholder.getFeatchType(),"default")) {
|
||||
// Object defaultValue = placeholder.getDefaultValue();
|
||||
// if(ObjectUtil.isNotNull(defaultValue)) {
|
||||
// log.warn("Hpc命令动态参数替换,默认值是空,参数名:{}",keyEnName);
|
||||
// }
|
||||
// command = CommandReplaceUtil.replaceCommandPlaceholder(command, keyEnName, defaultValue);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(StringUtils.isBlank(command)) {
|
||||
// return SdmResponse.failed("command命令不能为空,软件名称:"+req.getSoftware());
|
||||
// }
|
||||
//
|
||||
// req.setCommand(formatCommand);
|
||||
// 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();
|
||||
// // 基础字段
|
||||
//// simulationJob.setId(1L);
|
||||
// simulationJob.setJobName(req.getJobName());
|
||||
// simulationJob.setCoreNum(req.getCoreNum());
|
||||
// simulationJob.setSoftware(req.getSoftware());
|
||||
// simulationJob.setJobType(req.getJobType());
|
||||
// simulationJob.setIndependence(req.isIndependence());
|
||||
//// simulationJob.setInputFiles(JSONObject.toJSONString(req.getInputFiles()));
|
||||
// // 主文件位置
|
||||
// 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());
|
||||
// // 下面的待定
|
||||
//// simulationJob.setInputFileId(null);
|
||||
// simulationJob.setJobId(jobId);
|
||||
// // 没必要要
|
||||
//// simulationJob.setJobDetailId("");
|
||||
// // 文件路径 共享目录+jobName(文件回传)+uuid,下面可能有多个文件
|
||||
// simulationJob.setStdoutHpcFilePath(hpcOutPutDir);
|
||||
// simulationJob.setStdoutSpdmMinoFilePath(req.getStdoutSpdmMinoFilePath());
|
||||
// simulationJob.setStdoutSpdmNasFilePath(req.getStdoutSpdmNasFilePath());
|
||||
// // 执行信息 定时任务回传的时候修改
|
||||
//// simulationJob.setNodeName("");
|
||||
// simulationJob.setExecutCommand(command);
|
||||
// // 执行信息 定时任务回传的时候修改
|
||||
//// simulationJob.setStartTime("2025-11-30 10:00:00");
|
||||
//// simulationJob.setEndTime("2025-11-30 12:30:00");
|
||||
// simulationJob.setJobStatus("Configuring");
|
||||
// // 求解器名称
|
||||
// simulationJob.setSolverName(req.getSoftware());
|
||||
// // 执行信息 定时任务回传的时候修改
|
||||
// simulationJob.setTotalKernelTime(null);
|
||||
// simulationJob.setTotalUserTime(null);
|
||||
// simulationJob.setTotalElapsedTime(null);
|
||||
// // 标识及状态
|
||||
//// simulationJob.setUuid(null);
|
||||
// simulationJob.setFileStatus("generating");
|
||||
// // 审计字段
|
||||
// Long userId = ThreadLocalContext.getUserId();
|
||||
// Long tenantId = ThreadLocalContext.getTenantId();
|
||||
// CoreLogger.info("submitHpcJob save db userId:{},tenantId:{}",userId,tenantId);
|
||||
// simulationJob.setCreatorId(userId);
|
||||
// simulationJob.setTenantId(tenantId);
|
||||
// simulationJob.setCreateTime(LocalDateTime.now());
|
||||
// simulationJob.setUpdaterId(userId);
|
||||
// simulationJob.setUpdateTime(LocalDateTime.now());
|
||||
// simulationJobService.save(simulationJob);
|
||||
// }
|
||||
// return SdmResponse.success(jobId);
|
||||
// }
|
||||
|
||||
private void dealInputFiles(SubmitHpcTaskReq req, String subDir) {
|
||||
if(req.getInputFiles()==null|| CollectionUtils.isEmpty(req.getInputFiles())) {
|
||||
return;
|
||||
@@ -276,35 +514,24 @@ public class PbsServiceDecorator implements IPbsServiceDecorator {
|
||||
return PageUtils.getJsonObjectSdmResponse(results, page);
|
||||
}
|
||||
|
||||
public SdmResponse<Map<String, List<SimulationSoftConfig>>> querySoftConfig(String softName) {
|
||||
List<SimulationSoftConfig> configs = simulationSoftConfigService.lambdaQuery()
|
||||
.eq(SimulationSoftConfig::getSoftName, softName)
|
||||
.orderByDesc(SimulationSoftConfig::getCreateTime)
|
||||
public SdmResponse<SimulationHpcCommand> querySoftConfig(String appUuid) {
|
||||
// app对应hpc命令,一个只会有一个
|
||||
SimulationHpcCommand hpcCommand = simulationSoftConfigService.lambdaQuery()
|
||||
.eq(SimulationHpcCommand::getAppUuid, appUuid).one();
|
||||
// 查询显示用户的动态参数
|
||||
List<SimulationHpcCommandPlaceholder> placeholders = simulationCommandPlaceholderService.lambdaQuery()
|
||||
.eq(SimulationHpcCommandPlaceholder::getAppUuid, appUuid)
|
||||
.eq(SimulationHpcCommandPlaceholder::getValueType,"input")
|
||||
.list();
|
||||
List<SimulationCommandPlaceholder> placeholders = simulationCommandPlaceholderService.lambdaQuery().list();
|
||||
Map<String, SimulationCommandPlaceholder> placeholderMap = placeholders.stream()
|
||||
.collect(Collectors.toMap(
|
||||
SimulationCommandPlaceholder::getKeyEnName, // 键:keyEnName
|
||||
placeholder -> placeholder,
|
||||
(existing, replacement) -> existing
|
||||
));
|
||||
configs.forEach(config -> {
|
||||
HashMap<String, SimulationCommandPlaceholder> map = new HashMap<>();
|
||||
String command = config.getCommand();
|
||||
List<String> placeholderKeys = extractPlaceholders(command);
|
||||
placeholderKeys.stream().forEach(placeholderKey -> {
|
||||
SimulationCommandPlaceholder simulationCommandPlaceholder = placeholderMap.get(placeholderKey);
|
||||
if (simulationCommandPlaceholder != null) {
|
||||
map.put(placeholderKey, simulationCommandPlaceholder);
|
||||
}
|
||||
});
|
||||
config.setCommandExpand(placeholderMap);
|
||||
});
|
||||
// 一个softName --》一个版本--》有多个命令
|
||||
Map<String, List<SimulationSoftConfig>> softConfigs = configs.stream()
|
||||
.collect(Collectors.groupingBy(SimulationSoftConfig::getSoftVersion));
|
||||
return SdmResponse.success(softConfigs);
|
||||
|
||||
if(Objects.isNull(hpcCommand)){
|
||||
return SdmResponse.failed("该应用未配置hpc命令!");
|
||||
}
|
||||
for(SimulationHpcCommandPlaceholder placeholder : placeholders){
|
||||
Map<String, Object> commandExpandMap = hpcCommand.getCommandExpand();
|
||||
String keyEnName = placeholder.getKeyEnName();
|
||||
commandExpandMap.put(keyEnName,placeholder);
|
||||
}
|
||||
return SdmResponse.success(hpcCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,10 +2,10 @@ package com.sdm.pbs.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sdm.pbs.dao.SimulationSoftConfigMapper;
|
||||
import com.sdm.pbs.model.entity.SimulationSoftConfig;
|
||||
import com.sdm.pbs.model.entity.SimulationHpcCommand;
|
||||
import com.sdm.pbs.service.ISimulationSoftConfigService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SimulationSoftConfigServiceImpl extends ServiceImpl<SimulationSoftConfigMapper, SimulationSoftConfig> implements ISimulationSoftConfigService {
|
||||
public class SimulationSoftConfigServiceImpl extends ServiceImpl<SimulationSoftConfigMapper, SimulationHpcCommand> implements ISimulationSoftConfigService {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user