martin před 3 roky
rodič
revize
385fbdd692
14 změnil soubory, kde provedl 302 přidání a 115 odebrání
  1. 8 1
      api-common/src/main/java/api/common/pojo/constants/DictConstants.java
  2. 8 0
      api-common/src/main/java/api/common/util/CollectionUtil.java
  3. 0 84
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/configuration/redis/RedisTemplateConfiguration.java
  4. 16 3
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/consumer/ManualProjectConsumer.java
  5. 2 2
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/controller/TaskController.java
  6. 45 12
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/mapper/IndexMapper.java
  7. 29 6
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/mapper/ProjectMapper.java
  8. 50 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/mapper/TaskMapper.java
  9. 5 1
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/pojo/po/IndexPO.java
  10. 19 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/pojo/po/MonitorTaskPO.java
  11. 17 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/pojo/po/ProjectPO.java
  12. 1 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/pojo/po/TaskPO.java
  13. 88 6
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/service/TaskService.java
  14. 14 0
      simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/util/ScoreUtil.java

+ 8 - 1
api-common/src/main/java/api/common/pojo/constants/DictConstants.java

@@ -24,7 +24,14 @@ public class DictConstants {
     public static final String SENSOR_RADAR = "4"; // 毫米波雷达表
     public static final String SENSOR_GPS = "5"; // GPS 传感器表
 
-    public static final String TASK_WAITING = "1"; // 任务执行状态,待执行
+    public static final String TASK_PENDING = "Pending"; // 任务执行状态,待执行
+    public static final String TASK_RUNNING = "Running"; // 任务执行状态,待执行
+    public static final String TASK_ABORTED = "Aborted"; // 任务执行状态,待执行
+    public static final String TASK_ANALYSIS = "Analysis"; // 任务执行状态,待执行
+    public static final String TASK_ANALYSING = "Analysing"; // 任务执行状态,待执行
+    public static final String TASK_COMPLETED = "Completed"; // 任务执行状态,待执行
+    public static final String TASK_TERMINATING = "Terminating"; // 任务执行状态,待执行
+    public static final String TASK_TERMINATED = "Terminated"; // 任务执行状态,待执行
 
     public static final String REGULATION_TYPE = "regulationType"; // 法规类型
     public static final String SELF_DRIVING = "selfDriving"; // 自车驾驶行为

+ 8 - 0
api-common/src/main/java/api/common/util/CollectionUtil.java

@@ -19,6 +19,14 @@ public class CollectionUtil {
         return new HashSet<>(Arrays.asList(elements));
     }
 
+    public static <T> Set<T> listToSet(List<T> list) {
+        return new HashSet<>(list);
+    }
+
+    public static <T> List<T> setToList(Set<T> set) {
+        return new ArrayList<>(set);
+    }
+
     public static boolean isEmpty(Collection<?> collection) {
         return collection == null || collection.isEmpty();
     }

+ 0 - 84
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/configuration/redis/RedisTemplateConfiguration.java

@@ -1,84 +0,0 @@
-//package com.css.simulation.resource.scheduler.configuration.redis;
-//
-//import com.fasterxml.jackson.annotation.JsonAutoDetect;
-//import com.fasterxml.jackson.annotation.PropertyAccessor;
-//import com.fasterxml.jackson.databind.ObjectMapper;
-//import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
-//import org.springframework.cache.CacheManager;
-//import org.springframework.cache.annotation.EnableCaching;
-//import org.springframework.context.annotation.Bean;
-//import org.springframework.context.annotation.Configuration;
-//import org.springframework.data.redis.cache.RedisCacheConfiguration;
-//import org.springframework.data.redis.cache.RedisCacheManager;
-//import org.springframework.data.redis.connection.RedisConnectionFactory;
-//import org.springframework.data.redis.core.RedisTemplate;
-//import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
-//import org.springframework.data.redis.serializer.RedisSerializationContext;
-//import org.springframework.data.redis.serializer.RedisSerializer;
-//import org.springframework.data.redis.serializer.StringRedisSerializer;
-//
-//import java.time.Duration;
-//import java.util.HashMap;
-//import java.util.Map;
-//
-//@Configuration
-//@EnableCaching
-//public class RedisTemplateConfiguration {
-//
-//    @Bean
-//    public RedisSerializer<Object> jackson2JsonRedisSerializer() {
-//        // 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 redis 的 value 值。
-//        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
-//        ObjectMapper mapper = new ObjectMapper();
-//        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
-//        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
-//        // 指定序列化输入的类型,类必须是非 final 修饰的,final修饰的类,比如 String, Integer 等会跑出异常
-//        mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
-//        serializer.setObjectMapper(mapper);
-//        return serializer;
-//    }
-//
-//    @Bean
-//    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
-//        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
-//        configuration = configuration
-//                // 设置 key 为 string 序列化
-//                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
-//                // 设置 value 为 json 序列化
-//                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer()))
-//                // 不缓存空值
-//                .disableCachingNullValues()
-//                // 设置缓存默认过期时间(30 分钟)
-//                .entryTtl(Duration.ofMinutes(30L))
-//        ;
-//        // 特殊缓存空间应用不同的配置
-//        Map<String, RedisCacheConfiguration> map = new HashMap<>();
-//        map.put("miFirst", configuration.entryTtl(Duration.ofMinutes(30L)));
-//        map.put("miSecond", configuration.entryTtl(Duration.ofHours(1L)));
-//
-//        return RedisCacheManager.builder(connectionFactory)
-//                .cacheDefaults(configuration)           // 默认配置
-//                .withInitialCacheConfigurations(map)    // 特殊缓存
-//                .transactionAware()                     // 事务
-//                .build();
-//    }
-//
-//    @Bean
-//    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
-//        RedisTemplate<String, Object> template = new RedisTemplate<>();
-//        template.setConnectionFactory(connectionFactory);
-//        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
-//        // key 采用 String 的序列化方式
-//        template.setKeySerializer(stringRedisSerializer);
-//        // hash 的 key 采用 String 的序列化方式
-//        template.setHashKeySerializer(stringRedisSerializer);
-//        // value 采用 jackson 的序列化方式
-//        template.setValueSerializer(jackson2JsonRedisSerializer());
-//        // hash 的 value 采用 jackson 的序列化方式
-//        template.setHashValueSerializer(jackson2JsonRedisSerializer());
-//        template.afterPropertiesSet();
-//        return template;
-//    }
-//
-//
-//}

+ 16 - 3
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/consumer/ManualProjectConsumer.java

@@ -25,7 +25,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.kafka.annotation.KafkaListener;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ResourceUtils;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -97,7 +96,7 @@ public class ManualProjectConsumer {
         sceneList.addAll(sceneMapper.selectNaturalByIdList(naturalIdList));
         sceneList.addAll(sceneMapper.selectStandardByIdList(standardIdList));
         sceneList.addAll(sceneMapper.selectAccidentByIdList(accidentIdList));
-
+        projectMapper.updateTaskNumber(projectId,sceneList.size()); // 有多少场景就有多少任务
         // -------------------------------- 2 模型 --------------------------------
         // 根据 vehicleId, 获取 模型信息和传感器信息
         String vehicleId = projectMessageDTO.getVehicleId();    // 模型 id
@@ -108,6 +107,7 @@ public class ManualProjectConsumer {
         // -------------------------------- 3 任务消息 --------------------------------
         // 根据场景创建任务,组装 task 消息
         int maxSimulationTime = projectMessageDTO.getMaxSimulationTime();
+
         for (ScenePO scenePO : sceneList) {
             String taskId = StringUtil.getRandomUUID();
             String resultPath = "/project/manual-project/" + projectId + "/" + taskId;
@@ -117,9 +117,18 @@ public class ManualProjectConsumer {
                     .sceneId(scenePO.getId())
                     .sceneName(scenePO.getName())
                     .sceneType(scenePO.getType())
-                    .runState(DictConstants.TASK_WAITING)
+                    .runState(DictConstants.TASK_PENDING)
                     .runResult(resultPath)
                     .build();
+//            MonitorTaskPO taskPO = TaskPO.builder()
+//                    .id(taskId)
+//                    .pId(projectId)
+//                    .sceneId(scenePO.getId())
+//                    .sceneName(scenePO.getName())
+//                    .sceneType(scenePO.getType())
+//                    .runState(DictConstants.TASK_PENDING)
+//                    .runResult(resultPath)
+//                    .build();
             //4-1 组装 task 消息
             TaskDTO taskDTO = TaskDTO.builder()
                     .info(InfoDTO.builder()
@@ -222,4 +231,8 @@ public class ManualProjectConsumer {
         batchV1Api.createNamespacedJob("test-namespace1", yaml, null, null, null);
 
     }
+
+
+
+
 }

+ 2 - 2
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/controller/TaskController.java

@@ -28,8 +28,8 @@ public class TaskController {
      * 修改任务状态
      */
     @GetMapping("/state")
-    public void taskState(@RequestParam("taskId") String taskId, @RequestParam("taskState") String taskState) {
-        taskService.taskState(taskId, taskState);
+    public void taskState(@RequestParam("taskId") String taskId, @RequestParam("state") String state) {
+        taskService.taskState(taskId, state);
     }
 
     /**

+ 45 - 12
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/mapper/IndexMapper.java

@@ -16,21 +16,54 @@ public interface IndexMapper {
 
 
     @Results(id = "index", value = {
-            @Result(column = "scene_natural_ids",property = "sceneNaturalIds",  jdbcType = JdbcType.VARCHAR),
-            @Result(column = "scene_traffic_ids",property = "sceneTrafficIds",  jdbcType = JdbcType.VARCHAR),
-            @Result(column = "scene_statue_ids",property = "sceneStatueIds",  jdbcType = JdbcType.VARCHAR)
+            @Result(column = "sublist_id", property = "indexId", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "scene_natural_ids", property = "sceneNaturalIds", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "scene_traffic_ids", property = "sceneTrafficIds", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "scene_statue_ids", property = "sceneStatueIds", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "weight", property = "weight", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "parent_id", property = "parentId", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "rule_details", property = "ruleDetails", jdbcType = JdbcType.VARCHAR)
     })
-
-
     @Select("select scene_natural_ids,\n" +
             "       scene_traffic_ids,\n" +
             "       scene_statue_ids\n" +
-            "from scene_package_sublist sps\n" +
-            "         left join scene_package sp on parent_id = sp.package_id\n" +
-            "where sps.is_deleted = '0' and sp.is_deleted = '0'\n" +
-            "  and parent_id = '#{packageId}'\n" +
-            "  and ((scene_natural_ids is not null and scene_natural_ids != '')\n" +
-            "    or (scene_traffic_ids is not null and scene_traffic_ids != '')\n" +
-            "    or (scene_statue_ids is not null and scene_statue_ids != ''))")
+            "from scene_package_sublist\n" +
+            "where is_deleted = '0'\n" +
+            "  and root_id = #{packageId}\n" +
+            "  and package_and_rules is not null and package_and_rules != ''")
     List<IndexPO> selectLeafIndexByPackageId(@Param("packageId") String packageId);
+
+    @ResultMap("index")
+    @Select("select sps.scene_natural_ids,\n" +
+            "       sps.scene_traffic_ids,\n" +
+            "       sps.scene_statue_ids,\n" +
+            "       sps.weight,\n" +
+            "       sps.parent_id,\n" +
+            "       sr.rule_details\n" +
+            "from scene_package_sublist sps\n" +
+            "         left join scoring_rules sr on sps.package_and_rules = sr.rules_id\n" +
+            "where root_id = '#{packageId}'\n" +
+            "  and package_and_rules is not null\n" +
+            "  and package_and_rules != ''")
+    List<IndexPO> selectLeafIndexWithRuleDetailsByPackageId(@Param("packageId") String packageId);
+
+
+    @ResultMap("index")
+    @Select("select sublist_id,\n" +
+            "       scene_natural_ids,\n" +
+            "       scene_traffic_ids,\n" +
+            "       scene_statue_ids,\n" +
+            "       weight,\n" +
+            "       parent_id\n" +
+            "from scene_package_sublist\n" +
+            "where 1=1\n" +
+            "<if test='idList != null and idList.size() > 0'>\n" +
+            "   and sublist_id in\n" +
+            "       <foreach collection='idList' index='index' item='item' open='(' close=')' separator=','>\n" +
+            "           #{item}" +
+            "       </foreach>\n" +
+            "</if>\n" +
+            "")
+    List<IndexPO> selectByIdList(@Param("idList") List<String> idList);
+
 }

+ 29 - 6
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/mapper/ProjectMapper.java

@@ -1,6 +1,7 @@
 package com.css.simulation.resource.scheduler.mapper;
 
 
+import com.css.simulation.resource.scheduler.pojo.po.ProjectPO;
 import org.apache.ibatis.annotations.*;
 import org.apache.ibatis.type.JdbcType;
 
@@ -8,14 +9,36 @@ import org.apache.ibatis.type.JdbcType;
 public interface ProjectMapper {
 
 
-    @Results(id = "job", value = {
-            @Result(property = "id", column = "id", jdbcType = JdbcType.VARCHAR)
+    @Results(id = "project", value = {
+            @Result(column = "id", property = "id", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "scene", property = "scenePackageId", jdbcType = JdbcType.VARCHAR)
     })
 
+    @Select("select id, scene\n" +
+            "from simulation_manual_project \n" +
+            "where id = (select project_id from simulation_manual_project_task where id = #{taskId})")
+    ProjectPO selectById(@Param("taskId")String taskId);
 
-    @Update("update simulation_project\n" +
+    @Update("update simulation_manual_project\n" +
             "set state = #{state}\n" +
-            "where is_deleted = '0'\n" +
-            "   and id = #{id}")
-    void updateProjectState(@Param("id") String id,@Param("state") String state);
+            "where id = #{id}")
+    void updateProjectState(@Param("id") String id, @Param("state") String state);
+
+
+    @Update("update simulation_manual_project\n" +
+            "set task_number = {taskNumber}\n" +
+            "where id = #{id}")
+    void updateTaskNumber(@Param("id") String id, @Param("taskNumber") int taskNumber);
+
+
+    @Select("select task_number\n" +
+            "from simulation_manual_project\n" +
+            "where project_id = #{id}")
+    int selectTaskNumById(@Param("id") String id);
+
+    @Select("select count(1)\n" +
+            "from simulation_manual_project_task\n" +
+            "where run_state = #{state}\n" +
+            "  and p_id = #{projectId}")
+    int selectTaskNumByProjectIdAndState(@Param("projectId") String projectId,@Param("state") String state);
 }

+ 50 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/mapper/TaskMapper.java

@@ -0,0 +1,50 @@
+package com.css.simulation.resource.scheduler.mapper;
+
+
+import com.css.simulation.resource.scheduler.pojo.po.TaskPO;
+import org.apache.ibatis.annotations.*;
+import org.apache.ibatis.type.JdbcType;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+/**
+ * simulation_manual_project_task
+ */
+@Mapper
+public interface TaskMapper {
+
+    @Results(id = "task", value = {
+            @Result(column = "id", property = "id", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "p_id", property = "pId", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "scene_id", property = "sceneId", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "scene_name", property = "sceneName", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "scene_type", property = "sceneType", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "run_state", property = "runState", jdbcType = JdbcType.VARCHAR),
+            @Result(column = "run_result", property = "runResult", jdbcType = JdbcType.VARCHAR)
+    })
+    @Select("select id,\n" +
+            "       p_id,\n" +
+            "       scene_id,\n" +
+            "       scene_name,\n" +
+            "       scene_type,\n" +
+            "       run_state,\n" +
+            "       run_result\n" +
+            "from simulation_manual_project_task\n" +
+            "where p_id = #{projectId}")
+    List<TaskPO> selectTaskListByProjectId(@Param("projectId") String projectId);
+
+    @Update("update monitor_task\n" +
+            "set tick_time = #{tickTime}\n" +
+            "where task_id = #{id}")
+    void updateTickTime(@Param("id") String id, @Param("tickTime")Timestamp tickTime);
+
+    @Update("update simulation_manual_project_task smpt,monitor_task mt\n" +
+            "set smpt.run_state = #{tickTime},\n" +
+            "    mt.run_state= #{tickTime}\n" +
+            "where smpt.id = #{id}\n" +
+            "  and mt.task_id = #{id}")
+    void updateState(@Param("id") String id, @Param("runState")String runState);
+
+
+}

+ 5 - 1
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/pojo/po/IndexPO.java

@@ -11,8 +11,12 @@ import lombok.NoArgsConstructor;
 @AllArgsConstructor
 public class IndexPO {
 
+    private String indexId;
     private String sceneNaturalIds;
     private String sceneTrafficIds;
     private String sceneStatueIds;
-
+    private String weight;  // 权重
+    private String parentId;  // 权重
+    private String ruleDetails; // 打分规则代码
+    private Double score; // 打分规则代码
 }

+ 19 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/pojo/po/MonitorTaskPO.java

@@ -0,0 +1,19 @@
+package com.css.simulation.resource.scheduler.pojo.po;
+
+import api.common.pojo.common.CommonPO;
+import lombok.*;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MonitorTaskPO extends CommonPO {
+    private String taskId;
+    private String pId;
+    private String sceneId;
+    private String sceneName;
+    private String sceneType;
+    private String runState;
+    private String runResult;
+}

+ 17 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/pojo/po/ProjectPO.java

@@ -0,0 +1,17 @@
+package com.css.simulation.resource.scheduler.pojo.po;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ProjectPO {
+
+    private String id;
+    private String scenePackageId;
+
+}

+ 1 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/pojo/po/TaskPO.java

@@ -16,4 +16,5 @@ public class TaskPO extends CommonPO {
     private String sceneType;
     private String runState;
     private String runResult;
+    private Double score;
 }

+ 88 - 6
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/service/TaskService.java

@@ -1,34 +1,116 @@
 package com.css.simulation.resource.scheduler.service;
 
+import api.common.pojo.constants.DictConstants;
+import api.common.util.CollectionUtil;
+import api.common.util.StringUtil;
+import api.common.util.TimeUtil;
 import com.css.simulation.resource.scheduler.feign.CommonService;
+import com.css.simulation.resource.scheduler.mapper.IndexMapper;
+import com.css.simulation.resource.scheduler.mapper.ProjectMapper;
+import com.css.simulation.resource.scheduler.mapper.TaskMapper;
+import com.css.simulation.resource.scheduler.pojo.po.IndexPO;
+import com.css.simulation.resource.scheduler.pojo.po.ProjectPO;
+import com.css.simulation.resource.scheduler.pojo.po.TaskPO;
+import com.css.simulation.resource.scheduler.util.ScoreUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 @Service
 public class TaskService {
 
+
     @Autowired
     private CommonService commonService;
+    @Autowired
+    private ProjectMapper projectMapper;
+    @Autowired
+    private TaskMapper taskMapper;
+    @Autowired
+    private IndexMapper indexMapper;
 
 
     public void taskTick(String taskId) {
-        // 将 taskId 存储到 redis,并刷新过期时间
-//        commonService.set(new RedisParameter(taskId));
+        // 刷新 mysql 心跳时间
+        taskMapper.updateTickTime(taskId, TimeUtil.getNowForMysql());
     }
 
 
-    public void taskState(String taskId, String taskState) {
+    public void taskState(String taskId, String state) {
         //1 根据 taskId 修改任务状态 taskState。
-        //2 如果 taskState 为完成状态,项目的已完成任务数+1。
-        //3 如果已完成任务数等于所有任务数量,调用打分程序,对项目中每个指标进行打分,
-        //4 根据每个指标的得分和权重算出 project 的总得分。
+        taskMapper.updateState(taskId, state);
+        //2 如果 taskState 为完成状态,校验一下项目的已完成数量。
+        ProjectPO projectPO = projectMapper.selectById(taskId);
+        String projectId = projectPO.getId();
+        String scenePackageId = projectPO.getScenePackageId();
+        int taskNum = projectMapper.selectTaskNumById(projectId);
+        int completedTaskNum = projectMapper.selectTaskNumByProjectIdAndState(projectId, DictConstants.TASK_COMPLETED);
+        if (taskNum != completedTaskNum) {
+            return;
+        }  //3 如果已完成任务数等于所有任务数量,调用打分程序,对项目中每个指标进行打分,
+        List<TaskPO> taskList = taskMapper.selectTaskListByProjectId(projectId);  // 所有任务信息
+        List<IndexPO> leafIndexList = indexMapper.selectLeafIndexWithRuleDetailsByPackageId(scenePackageId);
 
+        // 计算所有叶子节点指标的得分
+        for (IndexPO indexPO : leafIndexList) {
+            String ruleDetails = indexPO.getRuleDetails();
+            Set<String> sceneIdSet = new HashSet<>();
+            String naturalIds = indexPO.getSceneNaturalIds();
+            String standardIds = indexPO.getSceneStatueIds();
+            String accidentIds = indexPO.getSceneTrafficIds();
+            if (StringUtil.isNotEmpty(naturalIds)) {
+                String[] naturalIdArray = naturalIds.split(",");
+                sceneIdSet.addAll(Arrays.asList(naturalIdArray));
+            }
+            if (StringUtil.isNotEmpty(standardIds)) {
+                String[] standardArray = standardIds.split(",");
+                sceneIdSet.addAll(Arrays.asList(standardArray));
+            }
+            if (StringUtil.isNotEmpty(accidentIds)) {
+                String[] accidentIdArray = accidentIds.split(",");
+                sceneIdSet.addAll(Arrays.asList(accidentIdArray));
+            }
+            int resultNumberOfCurrentIndex = sceneIdSet.size();
+            double sum = taskList.stream()
+                    .filter(task1 -> sceneIdSet.contains(task1.getSceneId()))
+                    .mapToDouble(task2 -> {
+                        // 计算每个任务的得分
+                        double score = ScoreUtil.score(task2.getRunResult(), ruleDetails);
+                        task2.setScore(score);
+                        return score;
+                    }).sum();
+            double indexScore = sum / resultNumberOfCurrentIndex;
+            indexPO.setScore(indexScore);
+        }
+        // 计算不合格的任务总数(不到100分就是不合格)
+        int unqualified = (int) taskList.stream().filter(taskPO -> taskPO.getScore() < 100).count();
+        //4 根据每个指标的得分和权重算出 project 的总得分。
+        double totalScore = compute(leafIndexList);
+        //5 保存指标的分数和总分数
     }
 
 
+
     public Boolean taskConfirm(String taskId) {
         // 将 taskId 存储到 redis,并刷新过期时间
 //        commonService.set(new RedisParameter(taskId,));
         return null;
     }
+
+    public double compute(List<IndexPO> leaf) {
+        double result = 0.0;
+        Map<String, List<IndexPO>> groups = leaf.stream().collect(Collectors.groupingBy(IndexPO::getParentId));
+        Set<String> idSet = groups.keySet();
+        List<IndexPO> indexPOList = indexMapper.selectByIdList(CollectionUtil.setToList(idSet));
+        indexPOList.forEach(index1 -> {
+            double sum = groups.get(index1.getIndexId()).stream().mapToDouble(index2 -> index2.getScore() * Double.parseDouble(index2.getWeight())).sum();
+            index1.setScore(sum);
+        });
+        if (indexPOList.size() > 1) {
+            result = result + compute(indexPOList);
+        }
+        return result;
+    }
 }

+ 14 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/util/ScoreUtil.java

@@ -0,0 +1,14 @@
+package com.css.simulation.resource.scheduler.util;
+
+/**
+ * 任务结果打分
+ */
+public class ScoreUtil {
+
+    public static double score(Object taskResult, String scoreRule) {
+        return Math.random();
+    }
+
+
+
+}