李春阳 1 년 전
부모
커밋
b9741d68ce
26개의 변경된 파일490개의 추가작업 그리고 21개의 파일을 삭제
  1. 24 0
      api-common/src/main/java/api/common/pojo/param/group/SimulationMageGroupParam.java
  2. 2 0
      api-common/src/main/java/api/common/pojo/param/project/MultiSimulationProjectKafkaParam.java
  3. 2 0
      api-common/src/main/java/api/common/pojo/param/project/MultiSimulationProjectParam.java
  4. 1 0
      api-common/src/main/java/api/common/pojo/param/project/SimulationManualProjectKafkaParam.java
  5. 1 0
      api-common/src/main/java/api/common/pojo/param/project/SimulationManualProjectParam.java
  6. 33 0
      api-common/src/main/java/api/common/pojo/po/group/SimulationMageGroupPO.java
  7. 2 0
      api-common/src/main/java/api/common/pojo/po/project/MultiSimulationProjectPO.java
  8. 2 0
      api-common/src/main/java/api/common/pojo/po/project/SimulationManualProjectPO.java
  9. 3 0
      api-common/src/main/java/api/common/pojo/vo/project/MultiSimulationProjectVO.java
  10. 3 0
      api-common/src/main/java/api/common/pojo/vo/project/ProjectDetailsVO.java
  11. 2 0
      api-common/src/main/java/api/common/pojo/vo/project/SimulationManualProjectSingleVo.java
  12. 3 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/adapter/entity/ProjectStartMessageEntity.java
  13. 5 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/app/entity/MultiProjectWaitQueueEntity.java
  14. 32 2
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/app/service/ProjectApplicationService.java
  15. 18 2
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/domain/service/ProjectDomainService.java
  16. 1 1
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/infra/db/mysql/mapper/MultiSimulationProjectMapper.java
  17. 12 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/infra/db/mysql/mapper/SimulationMageGroupMapper.java
  18. 55 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/adapter/controller/job_manage/SimulationMageGroupController.java
  19. 37 3
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/impl/MultiSimulationProjectServiceImpl.java
  20. 149 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/impl/SimulationMageGroupServiceImpl.java
  21. 33 1
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/impl/SimulationProjectServiceImpl.java
  22. 23 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/job_manage/SimulationMageGroupService.java
  23. 4 4
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/db/mysql/mapper/MultiSimulationProjectMapper.java
  24. 37 0
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/db/mysql/mapper/SimulationMageGroupMapper.java
  25. 2 8
      simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/util/ProjectUtil.java
  26. 4 0
      simulation-resource-server/src/main/resources/mysql/mapper/SimulationManualProjectMapper.xml

+ 24 - 0
api-common/src/main/java/api/common/pojo/param/group/SimulationMageGroupParam.java

@@ -0,0 +1,24 @@
+package api.common.pojo.param.group;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.sql.Timestamp;
+
+@Getter
+@Setter
+public class SimulationMageGroupParam {
+    private Integer pageNum;
+    private Integer pageSize;
+    private String id;
+    private String groupName;
+
+    private String softwarePath;
+
+    private String controllerPath;
+
+    private String connectorPath;
+
+    private String groupDescription;
+
+}

+ 2 - 0
api-common/src/main/java/api/common/pojo/param/project/MultiSimulationProjectKafkaParam.java

@@ -15,6 +15,8 @@ import java.util.List;
 public class MultiSimulationProjectKafkaParam {
     private String projectId;
 
+    private String simulationMageGroupId;
+
     private Integer defaultTime;
     private List<MultiSimulationSceneKafkaParam> kafkaParamList;
 }

+ 2 - 0
api-common/src/main/java/api/common/pojo/param/project/MultiSimulationProjectParam.java

@@ -28,6 +28,8 @@ public class MultiSimulationProjectParam {
 
     private String projectUserId;
 
+    private String simulationMageGroupId;
+
     /**
      * project的主键id
      */

+ 1 - 0
api-common/src/main/java/api/common/pojo/param/project/SimulationManualProjectKafkaParam.java

@@ -14,6 +14,7 @@ public class SimulationManualProjectKafkaParam {
     private String algorithmId; // 算法 id
     private String vehicleConfigId; // 车辆配置 id
     private String scenePackageId;  // 场景测试包 id
+    private String simulationMageGroupId;// 仿真镜像组id
     private Long maxSimulationTime; //  最大仿真时间
     private Integer parallelism;    // 并行度
     private String type;    // 项目类型

+ 1 - 0
api-common/src/main/java/api/common/pojo/param/project/SimulationManualProjectParam.java

@@ -23,6 +23,7 @@ public class SimulationManualProjectParam extends PageVO {
     private String algorithmName;   //算法名称
     private String vehicle; //车辆
     private String scene;   //场景
+    private String simulationMageGroupId;// 仿真镜像组id
     private String operationCycle;  //运行周期
     private String parallelism; //并行度
     private String ruleView;    //规则查看

+ 33 - 0
api-common/src/main/java/api/common/pojo/po/group/SimulationMageGroupPO.java

@@ -0,0 +1,33 @@
+package api.common.pojo.po.group;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+/**
+ * 多模式仿真
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SimulationMageGroupPO implements Serializable {
+    private String id;
+    private String groupName;
+
+    private String softwarePath;
+
+    private String controllerPath;
+
+    private String connectorPath;
+
+    private String groupDescription;
+    private Integer deleted;
+
+    private Timestamp createTime;
+    private Timestamp updateTime;
+}

+ 2 - 0
api-common/src/main/java/api/common/pojo/po/project/MultiSimulationProjectPO.java

@@ -23,6 +23,8 @@ public class MultiSimulationProjectPO implements Serializable {
 
     private String projectUserId;
 
+    private String simulationMageGroupId;
+
     private String projectDescription;
 
     private Integer projectMaxSeconds;

+ 2 - 0
api-common/src/main/java/api/common/pojo/po/project/SimulationManualProjectPO.java

@@ -21,6 +21,8 @@ public class SimulationManualProjectPO extends BasePO {
     private String algorithm;   //算法
     private String vehicle; //车辆 id
     private String scene;    //场景(包)
+    private String simulationMageGroupId;
+
     private String operationCycle;  //运行周期
     private String parallelism; //并行度
     private String ruleView;     //规则查看

+ 3 - 0
api-common/src/main/java/api/common/pojo/vo/project/MultiSimulationProjectVO.java

@@ -23,6 +23,9 @@ public class MultiSimulationProjectVO implements Serializable {
 
     private String projectUserId;
 
+    private String simulationMageGroupId;
+    private String simulationMageGroupName;
+
     private String projectDescription;
 
     private Integer projectMaxSeconds;

+ 3 - 0
api-common/src/main/java/api/common/pojo/vo/project/ProjectDetailsVO.java

@@ -38,4 +38,7 @@ public class ProjectDetailsVO {
     private String packageName; //场景包名
     private List<AlgorithmScoreVO> algorithmScoreList; //算法测试得分
     private boolean reportForReferenceLib; // 是否有基准场景库专用报告
+
+    private String simulationMageGroupId;// 仿真镜像组id
+    private String simulationMageGroupName;// 仿真镜像组id
 }

+ 2 - 0
api-common/src/main/java/api/common/pojo/vo/project/SimulationManualProjectSingleVo.java

@@ -29,6 +29,8 @@ public class SimulationManualProjectSingleVo {
     //场景
     private String scene;
 
+    private String simulationMageGroupId;
+
     //最大仿真时间(秒)
     private Long maxSimulationTime;
 

+ 3 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/adapter/entity/ProjectStartMessageEntity.java

@@ -24,6 +24,9 @@ public class ProjectStartMessageEntity {
     private String algorithmId;// 算法 id
     private String vehicleConfigId;// 车辆配置 id
     private String scenePackageId;// 场景包 id
+
+    private String simulationMageGroupId;// 仿真镜像组id
+
     private Integer maxSimulationTime;// 最大仿真时间(秒)
     private Integer parallelism = 1;// 期望并行度,页面上创建项目时指定的并行度
     private String modelType;// vtd carsim

+ 5 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/app/entity/MultiProjectWaitQueueEntity.java

@@ -23,6 +23,11 @@ public class MultiProjectWaitQueueEntity {
 
     private String projectId;
 
+    private String controllerPath;
+    private String connectorPath;
+
+    private String softwarePath;
+
     private List<MultiTaskMessageEntity> multiTaskMessageEntityList;
 
     private List<MultiSimulationSceneKafkaParam> kafkaParamList;

+ 32 - 2
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/app/service/ProjectApplicationService.java

@@ -7,6 +7,7 @@ import api.common.pojo.param.project.MultiCreateYamlRet;
 import api.common.pojo.param.project.MultiSimulationProjectKafkaParam;
 import api.common.pojo.param.project.MultiSimulationProjectParam;
 import api.common.pojo.param.project.MultiSimulationSceneKafkaParam;
+import api.common.pojo.po.group.SimulationMageGroupPO;
 import api.common.pojo.po.project.MultiSimulationProjectTaskRecordPO;
 import api.common.pojo.vo.map.SimulationMapVO;
 import api.common.pojo.vo.project.MultiSimulationProjectVO;
@@ -39,6 +40,7 @@ import io.minio.MinioClient;
 import lombok.SneakyThrows;
 import lombok.Synchronized;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.kafka.clients.admin.Admin;
 import org.apache.kafka.clients.producer.RecordMetadata;
 import org.springframework.beans.factory.annotation.Value;
@@ -125,6 +127,8 @@ public class ProjectApplicationService {
     private SimulationMapMapper mapMapper;
     @Resource
     private MultiSimulationProjectMapper multiSimulationProjectMapper;
+    @Resource
+    private SimulationMageGroupMapper mageGroupMapper;
 
     @Resource
     private MultiSimulationProjectTaskRecordMapper taskRecordMapper;
@@ -584,6 +588,7 @@ public class ProjectApplicationService {
             parallel = multiTaskMessageEntityList.size();
         }
         Integer runState = multiProjectWaitQueue.getRunState();
+
         // 使用完塞入
         Map<String, Integer> multiNodeMapToUse = projectDomainService.getMultiNodeMapToUse(isChoiceGpu, parallel);
         List<MultiCreateYamlRet> yamlList = new ArrayList<>();
@@ -615,7 +620,9 @@ public class ProjectApplicationService {
                 throw new RuntimeException("未选取到可用的节点");
             }
             MultiSimulationSceneKafkaParam multiSimulationSceneKafkaParam = multiProjectWaitQueue.getKafkaParamList().get(i);
-            MultiCreateYamlRet multiTempYaml = projectDomainService.createMultiTempYaml(projectId, multiSimulationSceneKafkaParam, messageEntity, modelName, partition, offset, isChoiceGpu);
+            MultiCreateYamlRet multiTempYaml = projectDomainService.createMultiTempYaml(projectId, multiSimulationSceneKafkaParam, messageEntity
+                ,multiProjectWaitQueue.getConnectorPath(),multiProjectWaitQueue.getControllerPath()
+                , modelName, partition, offset, isChoiceGpu);
             multiTempYaml.setTaskId(messageEntity.getInfo().getTask_id());
             multiTempYaml.setNodeName(modelName);
             yamlList.add(multiTempYaml);
@@ -674,6 +681,9 @@ public class ProjectApplicationService {
         KafkaUtil.createTopic(kafkaAdminClient, projectId, finalParallelism, (short) 1);   // 创建主题
         TimeUnit.SECONDS.sleep(3);
         // 需要即时启动的任务(并行度的大小)
+        SimulationMageGroupPO groupPO = mageGroupMapper.selectSimulationMageGroupById(projectStartMessageEntity.getSimulationMageGroupId());
+        String connectorPath = groupPO.getConnectorPath();
+        String controllerPath = groupPO.getControllerPath();
         ArrayList<String> yamlToRunRedisKeyList = new ArrayList<>();
         for (String taskJsonPath : taskJsonList) {
             String taskId = FileUtil.getFilenameWithoutSuffix(taskJsonPath);
@@ -718,7 +728,7 @@ public class ProjectApplicationService {
             }
             // 只有准备启动(即 currentCount == 0)的时候才指定 cpu 编号
             log.info("创建任务 {} 的 yaml:是否使用 gpu (0是1否){},当前节点已创建 yaml 个数为:{},当前节点名称为:{},当前 cpu 编号为:{},镜像名:{}", taskId, isChoiceGpu, currentCount, currentNodeName, cpuOrder, algorithmDockerImage);
-            String yamlRedisKey = projectDomainService.createTempYaml(projectId, vehicleConfigId, modelType, algorithmDockerImage, currentNodeName, partition, offset, isChoiceGpu, cpuOrder);
+            String yamlRedisKey = projectDomainService.createTempYaml(projectId, vehicleConfigId, modelType, algorithmDockerImage, currentNodeName, partition, offset, isChoiceGpu, cpuOrder, connectorPath, controllerPath);
             if (currentCount == 0) {
                 yamlToRunRedisKeyList.add(yamlRedisKey);
             }
@@ -1038,6 +1048,7 @@ public class ProjectApplicationService {
     }
 
     @Async("pool1")
+    @SneakyThrows
     public void runMultiProject(MultiSimulationProjectKafkaParam projectStartMessageEntity) {
         MultiProjectWaitQueueEntity multiTaskAndFixData = createMultiTaskAndFixData(projectStartMessageEntity);
         checkIfCanRunMulti(multiTaskAndFixData);
@@ -1123,6 +1134,16 @@ public class ProjectApplicationService {
             KafkaUtil.deleteTopic(kafkaAdminClient, projectId);
 
             List<MultiSimulationSceneKafkaParam> kafkaParamList = projectStartMessageEntity.getKafkaParamList();
+
+            MultiSimulationProjectVO projectVO = multiSimulationProjectMapper.selectMultiSimulationProjectById(projectId);
+            if (Objects.isNull(projectVO)){
+                throw new RuntimeException("未找到有效的仿真任务");
+            }
+            String simulationMageGroupId = projectVO.getSimulationMageGroupId();
+            SimulationMageGroupPO groupPO = mageGroupMapper.selectSimulationMageGroupById(simulationMageGroupId);
+            if (Objects.isNull(groupPO) || StringUtils.isBlank(groupPO.getControllerPath()) || StringUtils.isBlank(groupPO.getConnectorPath())){
+                throw new RuntimeException("仿真镜像组无效");
+            }
             List<MultiTaskMessageEntity> entityList = new ArrayList<>();
             for (MultiSimulationSceneKafkaParam kafkaParam: kafkaParamList) {
                 String taskId = StringUtil.getRandomUUID();
@@ -1226,6 +1247,9 @@ public class ProjectApplicationService {
             MultiProjectWaitQueueEntity build = MultiProjectWaitQueueEntity.builder()
                 .multiTaskMessageEntityList(entityList)
                 .projectId(projectId)
+                .connectorPath(groupPO.getConnectorPath())
+                .controllerPath(groupPO.getControllerPath())
+                .softwarePath(groupPO.getSoftwarePath())
                 .waitingParallelism(entityList.size())
                 .kafkaParamList(kafkaParamList)
                 .runState(-1)
@@ -1344,6 +1368,9 @@ public class ProjectApplicationService {
             waitMulti(MultiProjectWaitQueueEntity.builder().waitingParallelism(parallelism - remainderParallelism)
                 .runState(runSt)
                 .projectId(projectWaitQueueEntity.getProjectId())
+                .softwarePath(projectWaitQueueEntity.getSoftwarePath())
+                .connectorPath(projectWaitQueueEntity.getConnectorPath())
+                .controllerPath(projectWaitQueueEntity.getControllerPath())
                 .multiTaskMessageEntityList(projectWaitQueueEntity.getMultiTaskMessageEntityList())
                 .kafkaParamList(projectWaitQueueEntity.getKafkaParamList())
                 .build());
@@ -1361,6 +1388,9 @@ public class ProjectApplicationService {
             waitMulti(MultiProjectWaitQueueEntity.builder().waitingParallelism(0)
                     .runState(projectWaitQueueEntity.getMultiTaskMessageEntityList().size() -1)
                     .projectId(projectWaitQueueEntity.getProjectId())
+                    .softwarePath(projectWaitQueueEntity.getSoftwarePath())
+                    .connectorPath(projectWaitQueueEntity.getConnectorPath())
+                    .controllerPath(projectWaitQueueEntity.getControllerPath())
                     .kafkaParamList(projectWaitQueueEntity.getKafkaParamList())
                     .multiTaskMessageEntityList(projectWaitQueueEntity.getMultiTaskMessageEntityList()).build()
             );

+ 18 - 2
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/domain/service/ProjectDomainService.java

@@ -114,7 +114,7 @@ public class ProjectDomainService {
      * 创建一个临时 yaml,node 在最后用 # 号隔开
      */
     @SneakyThrows
-    public String createTempYaml(String projectId, String vehicleConfigId, String modelType, String algorithmDockerImage, String nodeName, int kafkaPartition, long kafkaOffset, String isChoiceGpu, Integer cpuOrder) {
+    public String createTempYaml(String projectId, String vehicleConfigId, String modelType, String algorithmDockerImage, String nodeName, int kafkaPartition, long kafkaOffset, String isChoiceGpu, Integer cpuOrder, String connectorPath, String controllerPath) {
         String podName = getRandomPodName(projectId);   // 生成 podName
         String podYaml = getPodYamlName(nodeName, podName);     // 模板文件名称
         String yamlPath = podYamlDirectory + podYaml;
@@ -142,6 +142,11 @@ public class ProjectDomainService {
             String replace13 = replace12.replace("namespace-name", kubernetesConfiguration.getNamespace()); // pod 名称包括 projectId 和 随机字符串
             String replace14 = replace13.replace("node-name", nodeName);     // 指定 pod 运行节点
 
+            replace14 = replace14.replace("controller-container", "controller-" + projectId);
+            replace14 = replace14.replace("controller-image", controllerPath);
+            replace14 = replace14.replace("connector-container", "connector-" + projectId);
+            replace14 = replace14.replace("connector-image", connectorPath);
+
             String replace15;
             if (cpuOrder != null) {
                 replace15 = replace14.replace("cpu-order", "\"" + cpuOrder + "\"");     // 指定 cpu 编号
@@ -186,6 +191,11 @@ public class ProjectDomainService {
             String replace17 = replace16.replace("namespace-name", kubernetesConfiguration.getNamespace()); // pod 名称包括 projectId 和 随机字符串
             String replace18 = replace17.replace("node-name", nodeName);     // 指定 pod 运行节点
 
+            replace18 = replace18.replace("controller-container", "controller-" + projectId);
+            replace18 = replace18.replace("controller-image", controllerPath);
+            replace18 = replace18.replace("connector-container", "connector-" + projectId);
+            replace18 = replace18.replace("connector-image", connectorPath);
+
             String replace19;
             if (cpuOrder != null) {
                 replace19 = replace18.replace("cpu-order", "\"" + cpuOrder + "\"");     // 指定 cpu 编号
@@ -218,7 +228,9 @@ public class ProjectDomainService {
     }
 
     @SneakyThrows
-    public MultiCreateYamlRet createMultiTempYaml(String projectId, MultiSimulationSceneKafkaParam multiSimulationSceneKafkaParam, MultiTaskMessageEntity messageEntity, String nodeName, int kafkaPartition, long kafkaOffset, String isChoiceGpu) {
+    public MultiCreateYamlRet createMultiTempYaml(String projectId, MultiSimulationSceneKafkaParam multiSimulationSceneKafkaParam, MultiTaskMessageEntity messageEntity,
+                                                  String connectorPath, String controllerPath,
+                                                  String nodeName, int kafkaPartition, long kafkaOffset, String isChoiceGpu) {
         String podName = getMultiRandomPodName(projectId);   // 生成 podName
         String podYaml = getMultiPodYamlName(nodeName, podName);     // 模板文件名称
         String yamlPath = multiPodYamlDirectory + podYaml;
@@ -242,6 +254,10 @@ public class ProjectDomainService {
         podString = podString.replace("cpu-order", "\""+1+"\"");
         podString = podString.replace("vtd-command", kubernetesConfiguration.getMultiCommandVtdGpu());
         podString = podString.replace("kafka-topic", projectId);
+        podString = podString.replace("controller-container", "controller-multi-" + messageEntity.getInfo().getScene_id());
+        podString = podString.replace("controller-image", controllerPath);
+        podString = podString.replace("connector-container", "connector-multi-" + messageEntity.getInfo().getScene_id());
+        podString = podString.replace("connector-image", connectorPath);
 
         List<MultiSimulationSceneCarVO> simulationSceneCarVOList = multiSimulationSceneKafkaParam.getSimulationSceneCarVOList();
 

+ 1 - 1
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/infra/db/mysql/mapper/MultiSimulationProjectMapper.java

@@ -27,7 +27,7 @@ public interface MultiSimulationProjectMapper {
         "where id = #{projectId}")
     int updateMultiSimulationProjectStatus(MultiSimulationProjectParam param);
 
-    @Select("select id,project_key as projectKey,project_name as projectName,project_status as projectStatus,create_time as createTime,project_description as projectDescription, " +
+    @Select("select id,project_key as projectKey,project_name as projectName,project_status as projectStatus,simulation_mage_group_id as simulationMageGroupId,create_time as createTime,project_description as projectDescription, " +
         "project_user_id as projectUserId from multi_simulation_project where deleted = 0 " +
         "and id = #{id} limit 1")
     MultiSimulationProjectVO selectMultiSimulationProjectById(@Param("id") String projectId);

+ 12 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/infra/db/mysql/mapper/SimulationMageGroupMapper.java

@@ -0,0 +1,12 @@
+package com.css.simulation.resource.scheduler.infra.db.mysql.mapper;
+
+import api.common.pojo.po.group.SimulationMageGroupPO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+@Mapper
+public interface SimulationMageGroupMapper {
+    @Select("select id,group_name as groupName,software_path as softwarePath,controller_path as controllerPath,connector_path as connectorPath,group_description as groupDescription from simulation_mage_group where id = #{id} and deleted = 0")
+    SimulationMageGroupPO selectSimulationMageGroupById(@Param("id") String id);
+}

+ 55 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/adapter/controller/job_manage/SimulationMageGroupController.java

@@ -0,0 +1,55 @@
+package com.css.simulation.resource.server.adapter.controller.job_manage;
+
+import api.common.pojo.common.ResponseBodyVO;
+import api.common.pojo.param.group.SimulationMageGroupParam;
+import api.common.pojo.po.group.SimulationMageGroupPO;
+import com.css.simulation.resource.server.app.service.job_manage.SimulationMageGroupService;
+import com.github.pagehelper.PageInfo;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 工作台模块--项目运行
+ */
+@RestController
+@RequestMapping("/simulationMageGroup")
+public class SimulationMageGroupController {
+
+    @Resource
+    private SimulationMageGroupService groupService;
+
+
+    @RequestMapping("/selectAllSimulationMageGroupList")
+    public ResponseBodyVO<List<SimulationMageGroupPO>> selectAllSimulationMageGroupList(@RequestBody SimulationMageGroupParam param) {
+        return groupService.selectAllSimulationMageGroupList(param);
+    }
+
+    @RequestMapping("/selectSimulationMapList")
+    public ResponseBodyVO<PageInfo<SimulationMageGroupPO>> selectSimulationMapList(@RequestBody SimulationMageGroupParam param) {
+        return groupService.selectSimulationMageGroupList(param);
+    }
+
+    @RequestMapping("/getSimulationMageGroup")
+    public ResponseBodyVO<SimulationMageGroupPO> getSimulationMageGroup(@RequestBody SimulationMageGroupParam param) {
+        return groupService.getSimulationMageGroup(param);
+    }
+
+    @RequestMapping("/updateSimulationMageGroup")
+    public ResponseBodyVO updateSimulationMageGroup(@RequestBody SimulationMageGroupParam param) {
+        return groupService.updateSimulationMageGroup(param);
+    }
+
+    @RequestMapping("/deleteSimulationMageGroup")
+    public ResponseBodyVO deleteSimulationMageGroup(@RequestBody List<SimulationMageGroupParam> paramList) {
+        return groupService.deleteSimulationMageGroup(paramList);
+    }
+
+    @RequestMapping("/addSimulationMageGroup")
+    public ResponseBodyVO addSimulationMageGroup(@RequestBody SimulationMageGroupParam param) {
+        return groupService.addSimulationMageGroup(param);
+    }
+}

+ 37 - 3
simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/impl/MultiSimulationProjectServiceImpl.java

@@ -11,6 +11,7 @@ import api.common.pojo.param.KafkaParameter;
 import api.common.pojo.param.MinioParameter;
 import api.common.pojo.param.project.*;
 import api.common.pojo.po.algorithm.AlgorithmPO;
+import api.common.pojo.po.group.SimulationMageGroupPO;
 import api.common.pojo.po.model.ConfigPO;
 import api.common.pojo.po.project.MultiSimulationProjectPO;
 import api.common.pojo.po.project.MultiSimulationProjectTaskRecordPO;
@@ -65,6 +66,8 @@ public class MultiSimulationProjectServiceImpl implements MultiSimulationProject
     private MultiSimulationProjectTaskRecordMapper taskRecordMapper;
     @Resource
     private MultiSimulationSceneMapper simulationSceneMapper;
+    @Resource
+    private SimulationMageGroupMapper mageGroupMapper;
 
     @Resource
     private MultiSimulationSceneCarMapper sceneCarMapper;
@@ -132,10 +135,16 @@ public class MultiSimulationProjectServiceImpl implements MultiSimulationProject
             return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "添加失败,存在同名的多模式仿真任务");
         }
         String currentUserId = AuthUtil.getCurrentUserId();
-
+        if (StringUtils.isBlank(currentUserId)){
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "当前角色为空");
+        }
+        if (StringUtils.isBlank(param.getSimulationMageGroupId())){
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "仿真镜像组id为空");
+        }
         MultiSimulationProjectPO build = MultiSimulationProjectPO.builder()
             .id(StringUtil.getRandomUUID())
             .projectName(param.getProjectName() == null ? "" : param.getProjectName())
+            .simulationMageGroupId(param.getSimulationMageGroupId())
             .projectMaxSeconds(param.getProjectMaxSeconds() == null ? 0 : param.getProjectMaxSeconds())
             .projectKey(param.getProjectKey() == null ? "" : param.getProjectKey())
             .projectDescription(param.getProjectDescription() == null ? "" : param.getProjectDescription())
@@ -167,6 +176,11 @@ public class MultiSimulationProjectServiceImpl implements MultiSimulationProject
         if (Objects.isNull(projectVO)){
             return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "未查询到可用的任务");
         }
+        String simulationMageGroupId = projectVO.getSimulationMageGroupId();
+        if (StringUtils.isBlank(simulationMageGroupId)){
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "仿真镜像组为空");
+        }
+
         Integer projectStatus = projectVO.getProjectStatus();
         Integer status = param.getProjectStatus();
         int res = 0;
@@ -198,7 +212,7 @@ public class MultiSimulationProjectServiceImpl implements MultiSimulationProject
                     return sceneCars;
                 }
             }
-            MultiSimulationProjectKafkaParam multiSimulationProjectKafkaParam = buildSendKafkaParam(projectId, projectVO.getProjectMaxSeconds());
+            MultiSimulationProjectKafkaParam multiSimulationProjectKafkaParam = buildSendKafkaParam(projectId, projectVO.getProjectMaxSeconds(), simulationMageGroupId);
             projectRunToKafka(multiSimulationProjectKafkaParam);
             res = multiSimulationProjectMapper.updateMultiSimulationProjectStatus(param);
         } else if (projectStatus == MultiSimulationStatusEnum.COMPLETED_STATUS.getProjectStatus()) {
@@ -216,9 +230,10 @@ public class MultiSimulationProjectServiceImpl implements MultiSimulationProject
         return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
     }
 
-    public MultiSimulationProjectKafkaParam buildSendKafkaParam(String projectId, Integer defaultTime){
+    public MultiSimulationProjectKafkaParam buildSendKafkaParam(String projectId, Integer defaultTime, String simulationMageGroupId){
         MultiSimulationProjectKafkaParam multiSimulationProjectKafkaParam = new MultiSimulationProjectKafkaParam();
         multiSimulationProjectKafkaParam.setProjectId(projectId);
+        multiSimulationProjectKafkaParam.setSimulationMageGroupId(simulationMageGroupId);
         MultiSimulationSceneParam sceneParam = new MultiSimulationSceneParam();
         sceneParam.setProjectId(projectId);
         List<MultiSimulationSceneVO> multiSimulationSceneVOS = simulationSceneMapper.selectSceneList(sceneParam);
@@ -278,6 +293,9 @@ public class MultiSimulationProjectServiceImpl implements MultiSimulationProject
         String currentUserId = AuthUtil.getCurrentUserId();
         param.setProjectUserId(currentUserId);
         param.setProjectStatus(MultiSimulationStatusEnum.RUN_STATUS.getProjectStatus());
+        if (StringUtils.isBlank(param.getSimulationMageGroupId())){
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "仿真镜像组为空");
+        }
         // 先更新
         multiSimulationProjectMapper.updateMultiSimulationProject(param);
         MultiSimulationProjectVO projectVO = multiSimulationProjectMapper.selectMultiSimulationProjectById(param.getProjectId());
@@ -300,11 +318,17 @@ public class MultiSimulationProjectServiceImpl implements MultiSimulationProject
         if (StringUtils.isBlank(param.getProjectId())) {
             return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "项目id不能为空");
         }
+        String simulationMageGroupId = param.getSimulationMageGroupId();
+        if (StringUtils.isBlank(simulationMageGroupId)){
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "仿真镜像组id不能为空");
+        }
         String currentUserId = AuthUtil.getCurrentUserId();
+        
 
         param.setProjectName(StringUtils.isBlank(param.getProjectName()) ? "" : param.getProjectName());
         param.setProjectDescription(StringUtils.isBlank(param.getProjectDescription()) ? "" : param.getProjectDescription());
         param.setProjectMaxSeconds(Objects.isNull(param.getProjectMaxSeconds()) ? 0 : param.getProjectMaxSeconds());
+        param.setSimulationMageGroupId(StringUtils.isBlank(param.getSimulationMageGroupId()) ? "" : param.getSimulationMageGroupId());
         param.setProjectUserId(currentUserId);
         int i = multiSimulationProjectMapper.updateMultiSimulationProject(param);
         return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, null);
@@ -320,6 +344,11 @@ public class MultiSimulationProjectServiceImpl implements MultiSimulationProject
         if (Objects.isNull(multiSimulationProjectVO)) {
             return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "未查询出有效的项目");
         }
+        String simulationMageGroupId = multiSimulationProjectVO.getSimulationMageGroupId();
+        SimulationMageGroupPO groupPO = mageGroupMapper.selectSimulationMageGroupById(simulationMageGroupId);
+        if (!Objects.isNull(groupPO)){
+            multiSimulationProjectVO.setSimulationMageGroupName(groupPO.getGroupName());
+        }
         multiSimulationProjectVO.setProjectStatusValue(MultiSimulationStatusEnum.matchStatusEnumByStatus(multiSimulationProjectVO.getProjectStatus()).getProjectStatusValue());
         return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, multiSimulationProjectVO);
     }
@@ -639,6 +668,9 @@ public class MultiSimulationProjectServiceImpl implements MultiSimulationProject
         if (Objects.isNull(projectVO)) {
             return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "请先保存当前的多模式仿真任务");
         }
+        if (StringUtils.isBlank(projectVO.getSimulationMageGroupId())){
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "仿真镜像组id为空");
+        }
         MultiSimulationProjectParam multiSimulationProjectParam = buildProjectParam(projectVO);
         multiSimulationProjectParam.setProjectName(param.getProjectNewName());
 
@@ -991,6 +1023,8 @@ public class MultiSimulationProjectServiceImpl implements MultiSimulationProject
     public static MultiSimulationProjectParam buildProjectParam(MultiSimulationProjectVO projectVO) {
         MultiSimulationProjectParam multiSimulationProjectParam = new MultiSimulationProjectParam();
         multiSimulationProjectParam.setProjectId(StringUtil.getRandomUUID()).setProjectKey(projectVO.getProjectKey())
+            .setProjectUserId(projectVO.getProjectUserId())
+            .setSimulationMageGroupId(projectVO.getSimulationMageGroupId())
             .setProjectDescription(projectVO.getProjectDescription()).setProjectMaxSeconds(projectVO.getProjectMaxSeconds())
             .setProjectStatus(MultiSimulationStatusEnum.INIT_STATUS.getProjectStatus());
         return multiSimulationProjectParam;

+ 149 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/impl/SimulationMageGroupServiceImpl.java

@@ -0,0 +1,149 @@
+package com.css.simulation.resource.server.app.impl;
+
+import api.common.pojo.common.PageVO;
+import api.common.pojo.common.ResponseBodyVO;
+import api.common.pojo.constants.DictConstants;
+import api.common.pojo.param.group.SimulationMageGroupParam;
+import api.common.pojo.po.group.SimulationMageGroupPO;
+import api.common.util.StringUtil;
+import com.alibaba.cloud.commons.lang.StringUtils;
+import com.css.simulation.resource.server.app.service.job_manage.SimulationMageGroupService;
+import com.css.simulation.resource.server.infra.db.mysql.mapper.SimulationMageGroupMapper;
+import com.css.simulation.resource.server.infra.util.AuthUtil;
+import com.css.simulation.resource.server.infra.util.PageUtil;
+import com.github.pagehelper.PageInfo;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Objects;
+
+@Service
+@Slf4j
+public class SimulationMageGroupServiceImpl implements SimulationMageGroupService {
+
+    @Resource
+    private SimulationMageGroupMapper mageGroupMapper;
+
+    @Override
+    @SneakyThrows
+    public ResponseBodyVO<PageInfo<SimulationMageGroupPO>> selectSimulationMageGroupList(SimulationMageGroupParam param) {
+        if (Objects.isNull(param.getPageNum())) {
+            param.setPageNum(1);
+        }
+        if (Objects.isNull(param.getPageSize())) {
+            param.setPageSize(10);
+        }
+        if (StringUtils.isBlank(param.getGroupName())) {
+            param.setGroupName(null);
+        }
+        if (StringUtils.isBlank(param.getGroupDescription())) {
+            param.setGroupDescription(null);
+        }
+
+        setPage(param.getPageNum(), param.getPageSize());
+        List<SimulationMageGroupPO> simulationMapVOS = mageGroupMapper.selectSimulationMageGroupList(param.getGroupName(), param.getGroupDescription());
+        PageInfo<SimulationMageGroupPO> pageInfo = new PageInfo<>(simulationMapVOS);
+        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, pageInfo);
+    }
+
+    @Override
+    @SneakyThrows
+    public ResponseBodyVO<List<SimulationMageGroupPO>> selectAllSimulationMageGroupList(SimulationMageGroupParam param) {
+        List<SimulationMageGroupPO> simulationMapVOS = mageGroupMapper.selectSimulationMageGroupList(null, null);
+        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, simulationMapVOS);
+    }
+
+    @Override
+    @SneakyThrows
+    public ResponseBodyVO<SimulationMageGroupPO> getSimulationMageGroup(SimulationMageGroupParam param) {
+        if (StringUtils.isBlank(param.getId())) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "镜像组id为空");
+        }
+        SimulationMageGroupPO groupPO = mageGroupMapper.selectSimulationMageGroupById(param.getId());
+        if (Objects.isNull(groupPO)) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "未找到有效的id");
+        }
+        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS, groupPO);
+    }
+
+
+    public ResponseBodyVO updateSimulationMageGroup(SimulationMageGroupParam param) {
+        String currentUserRoleCode = AuthUtil.getCurrentUserRoleCode();
+        if (!StringUtils.equals(DictConstants.ROLE_CODE_ADMIN, currentUserRoleCode) && !StringUtils.equals(DictConstants.ROLE_CODE_SYSADMIN, currentUserRoleCode)) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "当前用户无该权限");
+        }
+        if (StringUtils.isBlank(param.getId())) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "镜像组id为空");
+        }
+        if (StringUtils.isBlank(param.getSoftwarePath()) || StringUtils.isBlank(param.getControllerPath()) || StringUtils.isBlank(param.getConnectorPath())) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "存上为空数据");
+        }
+        if (StringUtils.isBlank(param.getGroupDescription())) {
+            param.setGroupDescription("");
+        }
+        int i = mageGroupMapper.updateSimulationMageGroupById(param);
+        if (i > 0) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
+        }
+        return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE);
+
+    }
+
+    @Override
+    @Transactional
+    public ResponseBodyVO deleteSimulationMageGroup(List<SimulationMageGroupParam> paramList) {
+        String currentUserRoleCode = AuthUtil.getCurrentUserRoleCode();
+        if (!StringUtils.equals(DictConstants.ROLE_CODE_ADMIN, currentUserRoleCode) && !StringUtils.equals(DictConstants.ROLE_CODE_SYSADMIN, currentUserRoleCode)) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "当前用户无该权限");
+        }
+        if (CollectionUtils.isEmpty(paramList)) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "id为空");
+        }
+        for (SimulationMageGroupParam param : paramList) {
+            if (StringUtils.isBlank(param.getId())) {
+                return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "id为空");
+            }
+        }
+        for (SimulationMageGroupParam param : paramList) {
+            int i = mageGroupMapper.deleteSimulationMageGroupById(param.getId());
+            if (i <= 0) {
+                throw new RuntimeException("删除失败" + param.getId());
+            }
+        }
+        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
+    }
+
+    @SneakyThrows
+    @Transactional
+    public ResponseBodyVO addSimulationMageGroup(SimulationMageGroupParam param) {
+        String currentUserRoleCode = AuthUtil.getCurrentUserRoleCode();
+        if (!StringUtils.equals(DictConstants.ROLE_CODE_ADMIN, currentUserRoleCode) && !StringUtils.equals(DictConstants.ROLE_CODE_SYSADMIN, currentUserRoleCode)) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "当前用户无该权限");
+        }
+        if (StringUtils.isBlank(param.getSoftwarePath()) || StringUtils.isBlank(param.getControllerPath()) || StringUtils.isBlank(param.getConnectorPath())) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "存上为空数据");
+        }
+        if (StringUtils.isBlank(param.getGroupDescription())) {
+            param.setGroupDescription("");
+        }
+        param.setId(StringUtil.getRandomUUID());
+
+        int i = mageGroupMapper.addSimulationMageGroup(param);
+        if (i <= 0) {
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "添加失败");
+        }
+        return new ResponseBodyVO<>(ResponseBodyVO.Response.SUCCESS);
+    }
+
+    private void setPage(Integer pageNum, Integer pageSize) {
+        PageVO pageVO = new PageVO();
+        pageVO.setCurrentPage(pageNum);
+        pageVO.setPageSize(pageSize);
+        PageUtil.setPageInfo(pageVO);
+    }
+}

+ 33 - 1
simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/impl/SimulationProjectServiceImpl.java

@@ -14,6 +14,7 @@ import api.common.pojo.param.scene.ScenePackageParam;
 import api.common.pojo.param.scene.SceneReferenceLibSelectParam;
 import api.common.pojo.param.system.DictParam;
 import api.common.pojo.po.algorithm.AlgorithmPO;
+import api.common.pojo.po.group.SimulationMageGroupPO;
 import api.common.pojo.po.model.ConfigPO;
 import api.common.pojo.po.model.ConfigSensorPO;
 import api.common.pojo.po.model.VehiclePO;
@@ -96,6 +97,9 @@ public class SimulationProjectServiceImpl implements SimulationProjectService {
     private SimulationMptFirstTargetScoreMapper simulationMptFirstTargetScoreMapper;
     @Resource
     private SimulationMptLastTargetScoreMapper simulationMptLastTargetScoreMapper;
+
+    @Resource
+    private SimulationMageGroupMapper mageGroupMapper;
     @Resource
     private AlgorithmMapper algorithmMapper;
     @Resource
@@ -145,6 +149,9 @@ public class SimulationProjectServiceImpl implements SimulationProjectService {
         if (isEmpty(param.getProjectName())) {
             return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "工作名称不能为空。");
         }
+        if (isEmpty(param.getSimulationMageGroupId())){
+            return new ResponseBodyVO<>(ResponseBodyVO.Response.CLIENT_FAILURE, "仿真镜像组不能为空");
+        }
         SimulationManualProjectPO po = convertParamToPo(param);
 
         if (isEmpty(param.getId())) {
@@ -318,6 +325,10 @@ public class SimulationProjectServiceImpl implements SimulationProjectService {
             projectDetailsVO.setNowRunState(DictConstants.PROJECT_RUNNING);
             projectDetailsVO.setNowRunStateName(DictConstants.PROJECT_RUNNING_NAME);
             //1 校验项目的信息是否可用
+            SimulationMageGroupPO groupPO = mageGroupMapper.selectSimulationMageGroupById(oldProjectPO.getSimulationMageGroupId());
+            if (Objects.isNull(groupPO)){
+                throw new RuntimeException("仿真镜像组无效");
+            }
             projectUtil.checkProject(oldProjectPO.getAlgorithm(), oldProjectPO.getVehicle(), oldProjectPO.getScene(), parallelism);
             if (DictConstants.PROJECT_COMPLETED.equals(oldState)) {  // 根据已完成的项目创建新项目
                 SimulationManualProjectPO newProjectPO = new SimulationManualProjectPO();
@@ -382,6 +393,7 @@ public class SimulationProjectServiceImpl implements SimulationProjectService {
         kafkaParam.setAlgorithmId(po.getAlgorithm());
         kafkaParam.setVehicleConfigId(po.getVehicle());
         kafkaParam.setScenePackageId(po.getScene());
+        kafkaParam.setSimulationMageGroupId(po.getSimulationMageGroupId());
         kafkaParam.setMaxSimulationTime(po.getMaxSimulationTime());
         kafkaParam.setParallelism(Integer.valueOf(po.getParallelism()));
         kafkaParam.setType(DictConstants.PROJECT_TYPE_MANUAL);
@@ -457,6 +469,8 @@ public class SimulationProjectServiceImpl implements SimulationProjectService {
         String algorithmId;
         String projectId;
         String createTime;
+        String simulationMageGroupId = null;// 仿真镜像组id
+        String simulationMageGroupName = null;
         if (DictConstants.PROJECT_TYPE_MANUAL.equals(projectType)) { // 手动运行任务
             SimulationManualProjectPO simulationManualProjectPO = simulationManualProjectMapper.selectProjectById(param);
             details = simulationManualProjectPO.getDetails();
@@ -464,6 +478,13 @@ public class SimulationProjectServiceImpl implements SimulationProjectService {
             algorithmId = simulationManualProjectPO.getAlgorithm();
             projectId = simulationManualProjectPO.getProjectId();
             createTime = String.valueOf(simulationManualProjectPO.getCreateTime());
+            simulationMageGroupId = simulationManualProjectPO.getSimulationMageGroupId();
+            if (com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(simulationMageGroupId)){
+                SimulationMageGroupPO groupPO = mageGroupMapper.selectSimulationMageGroupById(simulationMageGroupId);
+                if (!Objects.isNull(groupPO)){
+                    simulationMageGroupName = groupPO.getGroupName();
+                }
+            }
         } else if (DictConstants.PROJECT_TYPE_AUTO_SUB.equals(projectType)) {
             SimulationManualProjectVO simulationManualProjectVO = simulationAutomaticSubProjectMapper.selectProjectInfo(param);
             details = simulationManualProjectVO.getDetails();
@@ -475,7 +496,8 @@ public class SimulationProjectServiceImpl implements SimulationProjectService {
             throw new RuntimeException("未知项目类型:" + projectType);
         }
         projectDetailsVO = JsonUtil.jsonToBean(details, ProjectDetailsVO.class);
-
+        projectDetailsVO.setSimulationMageGroupId(simulationMageGroupId);
+        projectDetailsVO.setSimulationMageGroupName(simulationMageGroupName);
         // 修正项目ID、创建时间
         {
             projectDetailsVO.setProjectId(projectId);
@@ -589,6 +611,14 @@ public class SimulationProjectServiceImpl implements SimulationProjectService {
             projectDetailsVO.setNowRunStateName(getDictName(DictConstants.PROJECT_RUN_STATE, po.getNowRunState()));
             algorithmType = po.getAlgorithmType();
             algorithmId = po.getAlgorithm();
+            String simulationMageGroupId = po.getSimulationMageGroupId();
+            if (com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(simulationMageGroupId)){
+                SimulationMageGroupPO groupPO = mageGroupMapper.selectSimulationMageGroupById(simulationMageGroupId);
+                if (!Objects.isNull(groupPO)){
+                    projectDetailsVO.setSimulationMageGroupId(simulationMageGroupId);
+                    projectDetailsVO.setSimulationMageGroupName(groupPO.getGroupName());
+                }
+            }
         } else if (DictConstants.PROJECT_TYPE_AUTO_SUB.equals(param.getProjectType())) {
             SimulationManualProjectVO po = simulationAutomaticSubProjectMapper.selectProjectInfo(param);
             projectDetailsVO = JsonUtil.jsonToBean(po.getDetails(), ProjectDetailsVO.class);
@@ -1792,6 +1822,7 @@ public class SimulationProjectServiceImpl implements SimulationProjectService {
         po.setAlgorithm(param.getAlgorithm());
         po.setVehicle(param.getVehicle());
         po.setScene(param.getScene());
+        po.setSimulationMageGroupId(param.getSimulationMageGroupId());
         // po.setOperationCycle(param.getOperationCycle());
         po.setMaxSimulationTime(param.getMaxSimulationTime());
         po.setParallelism(param.getParallelism());
@@ -1857,6 +1888,7 @@ public class SimulationProjectServiceImpl implements SimulationProjectService {
         vo.setAlgorithmType(po.getAlgorithmType());
         vo.setVehicle(po.getVehicle());
         vo.setScene(po.getScene());
+        vo.setSimulationMageGroupId(po.getSimulationMageGroupId());
         vo.setMaxSimulationTime(po.getMaxSimulationTime());
         vo.setParallelism(po.getParallelism());
         vo.setIsChoiceGpu(po.getIsChoiceGpu());

+ 23 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/app/service/job_manage/SimulationMageGroupService.java

@@ -0,0 +1,23 @@
+package com.css.simulation.resource.server.app.service.job_manage;
+
+import api.common.pojo.common.ResponseBodyVO;
+import api.common.pojo.param.group.SimulationMageGroupParam;
+import api.common.pojo.po.group.SimulationMageGroupPO;
+import com.github.pagehelper.PageInfo;
+
+import java.util.List;
+
+public interface SimulationMageGroupService {
+    ResponseBodyVO<List<SimulationMageGroupPO>> selectAllSimulationMageGroupList(SimulationMageGroupParam param);
+
+    ResponseBodyVO<PageInfo<SimulationMageGroupPO>> selectSimulationMageGroupList(SimulationMageGroupParam param);
+
+    ResponseBodyVO<SimulationMageGroupPO> getSimulationMageGroup(SimulationMageGroupParam param);
+
+    ResponseBodyVO updateSimulationMageGroup(SimulationMageGroupParam param);
+
+    ResponseBodyVO deleteSimulationMageGroup(List<SimulationMageGroupParam> param);
+
+    ResponseBodyVO addSimulationMageGroup(SimulationMageGroupParam param);
+
+}

+ 4 - 4
simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/db/mysql/mapper/MultiSimulationProjectMapper.java

@@ -34,8 +34,8 @@ public interface MultiSimulationProjectMapper {
     List<MultiSimulationProjectVO> selectProjectList(MultiSimulationProjectParam param);
 
 
-    @Insert("insert into multi_simulation_project (id,project_key,project_name,project_description,project_max_seconds,project_status,project_user_id) values" +
-        "(#{id},#{projectKey},#{projectName},#{projectDescription},#{projectMaxSeconds},#{projectStatus},#{projectUserId})")
+    @Insert("insert into multi_simulation_project (id,project_key,project_name,project_description,project_max_seconds,project_status,project_user_id,simulation_mage_group_id) values" +
+        "(#{id},#{projectKey},#{projectName},#{projectDescription},#{projectMaxSeconds},#{projectStatus},#{projectUserId},#{simulationMageGroupId})")
     int  addMultiSimulationProject(MultiSimulationProjectPO projectPO);
 
     @Select("select id,project_key,project_name,project_status,create_time from multi_simulation_project where deleted = 0 " +
@@ -46,14 +46,14 @@ public interface MultiSimulationProjectMapper {
     int deleteMultiSimulationProject(@Param("id") String id);
 
     @Update("update multi_simulation_project set project_name = #{projectName}, project_description = #{projectDescription}," +
-        "project_max_seconds = #{projectMaxSeconds}, project_user_id = #{projectUserId} where id = #{projectId}")
+        "project_max_seconds = #{projectMaxSeconds}, project_user_id = #{projectUserId}, simulation_mage_group_id = #{simulationMageGroupId} where id = #{projectId}")
     int updateMultiSimulationProject(MultiSimulationProjectParam param);
 
     @Update("update multi_simulation_project set project_status = #{projectStatus} " +
         "where id = #{projectId}")
     int updateMultiSimulationProjectStatus(MultiSimulationProjectParam param);
 
-    @Select("select id,project_key,project_name,project_status,create_time,project_description,project_max_seconds from multi_simulation_project where deleted = 0 " +
+    @Select("select id,project_key,project_name,project_status,create_time,project_description,project_max_seconds,simulation_mage_group_id from multi_simulation_project where deleted = 0 " +
         "and id = #{id} limit 1")
     MultiSimulationProjectVO selectMultiSimulationProjectById(@Param("id") String projectId);
 }

+ 37 - 0
simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/db/mysql/mapper/SimulationMageGroupMapper.java

@@ -0,0 +1,37 @@
+package com.css.simulation.resource.server.infra.db.mysql.mapper;
+
+import api.common.pojo.param.group.SimulationMageGroupParam;
+import api.common.pojo.po.group.SimulationMageGroupPO;
+import org.apache.ibatis.annotations.*;
+
+import java.util.List;
+
+@Mapper
+public interface SimulationMageGroupMapper {
+    @Insert("insert into simulation_mage_group (id,group_name,software_path,controller_path,connector_path,group_description) values" +
+        "(#{id},#{groupName},#{softwarePath},#{controllerPath},#{connectorPath},#{groupDescription})")
+    int addSimulationMageGroup(SimulationMageGroupParam scene);
+
+    @Select("<script>" +
+        "select id,group_name,software_path,controller_path,connector_path,group_description,create_time,update_time from simulation_mage_group where deleted = 0 " +
+        "<if test='groupName != null'> " +
+        " AND group_name like CONCAT('%',#{groupName},'%') " +
+        "</if>" +
+        "<if test='groupDescription != null'> " +
+        " AND group_description like CONCAT('%',#{groupDescription},'%') " +
+        "</if>" +
+        "order by create_time desc" +
+        "</script>")
+    List<SimulationMageGroupPO> selectSimulationMageGroupList(@Param("groupName") String groupName, @Param("groupDescription") String groupDescription);
+
+    @Select("select id,group_name,software_path,controller_path,connector_path,group_description,create_time,update_time from simulation_mage_group where id = #{id} and deleted = 0")
+    SimulationMageGroupPO selectSimulationMageGroupById(@Param("id") String id);
+
+    @Update("update simulation_mage_group set deleted = 1 where id = #{id}")
+    int deleteSimulationMageGroupById(@Param("id") String id);
+
+    @Update("update simulation_mage_group set software_path = #{softwarePath},controller_path = #{controllerPath},connector_path = #{connectorPath},group_description = #{groupDescription}" +
+        " where id = #{id}")
+    int updateSimulationMageGroupById(SimulationMageGroupParam param);
+
+}

+ 2 - 8
simulation-resource-server/src/main/java/com/css/simulation/resource/server/infra/util/ProjectUtil.java

@@ -5,14 +5,7 @@ import api.common.pojo.param.project.SimulationManualProjectParam;
 import api.common.pojo.po.project.SimulationManualProjectPO;
 import api.common.pojo.po.scheduler.SchedulerProjectPO;
 import api.common.util.StringUtil;
-import com.css.simulation.resource.server.infra.db.mysql.mapper.AlgorithmMapper;
-import com.css.simulation.resource.server.infra.db.mysql.mapper.ModelConfigMapper;
-import com.css.simulation.resource.server.infra.db.mysql.mapper.ModelVehicleMapper;
-import com.css.simulation.resource.server.infra.db.mysql.mapper.AutoSubProjectMapper;
-import com.css.simulation.resource.server.infra.db.mysql.mapper.ManualProjectMapper;
-import com.css.simulation.resource.server.infra.db.mysql.mapper.SimulationManualProjectMapper;
-import com.css.simulation.resource.server.infra.db.mysql.mapper.ScenePackageMapper;
-import com.css.simulation.resource.server.infra.db.mysql.mapper.ScenePackageSublistMapper;
+import com.css.simulation.resource.server.infra.db.mysql.mapper.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
@@ -111,6 +104,7 @@ public class ProjectUtil {
         if (DictConstants.IS_UNAVAILABLE.equals(isUnavailable2)) {
             throw new RuntimeException("场景测试包已被禁用,编辑场景测试包后可重新运行。");
         }
+
         log.info("3 查询评分规则是否被删除。");
         sceneUtil.checkRules(scenePackageId);
         log.info("4 查询场景测试包是否有场景。");

+ 4 - 0
simulation-resource-server/src/main/resources/mysql/mapper/SimulationManualProjectMapper.xml

@@ -16,6 +16,7 @@
          algorithm_type,
          vehicle,
          scene,
+         simulation_mage_group_id,
          operation_cycle,
          parallelism,
          rule_view,
@@ -52,6 +53,7 @@
                 #{algorithmType},
                 #{vehicle},
                 #{scene},
+                #{simulationMageGroupId},
                 #{operationCycle},
                 #{parallelism},
                 #{ruleView},
@@ -92,6 +94,7 @@
             algorithm_type      = #{algorithmType},
             vehicle             = #{vehicle},
             scene               = #{scene},
+            simulation_mage_group_id = #{simulationMageGroupId},
             max_simulation_time = #{maxSimulationTime,jdbcType=BIGINT},
             complexity_evaluation_rule_id = #{complexityEvaluationRuleId},
             risk_evaluation_rule_id = #{riskEvaluationRuleId},
@@ -243,6 +246,7 @@
                algorithm_type,
                vehicle,
                scene,
+               simulation_mage_group_id,
                operation_cycle,
                parallelism,
                rule_view,