Browse Source

x新增预测任务 训练任务的新增任务接口

刘桐 2 weeks ago
parent
commit
579d921069

+ 14 - 0
xvji-admin/pom.xml

@@ -47,6 +47,20 @@
         <dependency>
             <groupId>com.xvji</groupId>
             <artifactId>xvji-framework</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.mybatis</groupId>
+                    <artifactId>mybatis</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.mybatis</groupId>
+                    <artifactId>mybatis-spring</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.github.pagehelper</groupId>
+                    <artifactId>pagehelper-spring-boot-starter</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
 
         <!-- 定时任务-->

+ 24 - 9
xvji-admin/src/main/java/com/xvji/XvJiApplication.java

@@ -1,9 +1,12 @@
 package com.xvji;
 
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.FilterType;
 import org.springframework.web.client.RestTemplate;
 
 /**
@@ -12,6 +15,14 @@ import org.springframework.web.client.RestTemplate;
  * @author ruoyi
  */
 @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+@ComponentScan(
+        basePackages = "com.xvji",
+        excludeFilters = @ComponentScan.Filter(
+                type = FilterType.ASSIGNABLE_TYPE,
+                classes = com.xvji.framework.config.MyBatisConfig.class // 原生 MyBatis 配置类的全路径
+        )
+)
+@MapperScan("com.xvji.mapper")
 public class XvJiApplication
 {
     public static void main(String[] args)
@@ -19,15 +30,19 @@ public class XvJiApplication
         // System.setProperty("spring.devtools.restart.enabled", "false");
         SpringApplication.run(XvJiApplication.class, args);
         System.out.println("(♥◠‿◠)ノ゙  许继功率预测系统启动成功   ლ(´ڡ`ლ)゙  \n" +
-                "  X       X           JJJJJJJJ          \n" +
-                "   X     X               J              \n" +
-                "    X   X                J              \n" +
-                "     X X                 J              \n" +
-                "      X                  J              \n" +
-                "     X X                 J              \n" +
-                "    X   X                J              \n" +
-                "   X     X            J  J              \n" +
-                "  X       X            JJJ            \n" +
+                "      XX         XX                     JJJJJJJJJJJJJJJ       \n" +
+                "       XX       XX                            JJ              \n" +
+                "        XX     XX                             JJ              \n" +
+                "         XX   XX                              JJ              \n" +
+                "          XX XX                               JJ              \n" +
+                "           XX                                 JJ              \n" +
+                "         XX   XX                              JJ              \n" +
+                "        XX     XX                             JJ              \n" +
+                "       XX       XX                            JJ              \n" +
+                "      XX         XX                    JJ     JJ              \n" +
+                "     XX           XX                     JJ   JJ              \n" +
+                "    XX             XX                      JJ JJJ             \n" +
+                "         START    SUCCESSFUL                                  \n" +
                 "-------------------------------------------------->>>\n");
 
     }

+ 5 - 0
xvji-admin/src/main/java/com/xvji/domain/Component.java

@@ -2,18 +2,23 @@ package com.xvji.domain;
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.TypeReference;
+import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import java.util.Map;
 
 /**
  * 组件表实体类(对应component表)
  */
+@TableName("component")
 @Data
 public class Component {
     /**
      * 组件ID
      */
+    @TableId(type = IdType.AUTO)
     private Long componentId;
 
     /**

+ 10 - 0
xvji-admin/src/main/java/com/xvji/domain/PredictTask.java

@@ -1,19 +1,29 @@
 package com.xvji.domain;
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import java.util.Date;
 
 /**
  * 预测任务表实体类(对应predict_task表)
  */
+@TableName("predict_task")
 @Data
 public class PredictTask {
     /**
      * 预测任务ID(主键)
      */
+    @TableId(type = IdType.AUTO)
     private Long pTaskId;
 
     /**
+     * 任务名称
+     */
+    private String pTaskName;
+
+    /**
      * 关联组件ID:多个组件ID用逗号分隔(如"1,2,3")
      */
     private String pComponentIds;

+ 10 - 0
xvji-admin/src/main/java/com/xvji/domain/TrainTask.java

@@ -1,19 +1,29 @@
 package com.xvji.domain;
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import java.util.Date;
 
 /**
  * 训练任务表实体类(对应train_task表)
  */
+@TableName("train_task")
 @Data
 public class TrainTask {
     /**
      * 训练任务ID(主键)
      */
+    @TableId(type = IdType.AUTO)
     private Long tTaskId;
 
     /**
+     * 任务名称
+     */
+    private String tTaskName;
+
+    /**
      * 关联组件ID:多个组件ID用逗号分隔(如"1,2,3")
      */
     private String tComponentIds;

+ 13 - 0
xvji-admin/src/main/java/com/xvji/mapper/ComponentMapper.java

@@ -0,0 +1,13 @@
+package com.xvji.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xvji.domain.Component;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 组件实体
+ */
+@Mapper
+public interface ComponentMapper extends BaseMapper<Component> {
+
+}

+ 13 - 0
xvji-admin/src/main/java/com/xvji/mapper/PredictTaskMapper.java

@@ -0,0 +1,13 @@
+package com.xvji.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xvji.domain.PredictTask;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 预测任务实体
+ */
+@Mapper
+public interface PredictTaskMapper extends BaseMapper<PredictTask> {
+
+}

+ 12 - 0
xvji-admin/src/main/java/com/xvji/mapper/TrainTaskMapper.java

@@ -0,0 +1,12 @@
+package com.xvji.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xvji.domain.TrainTask;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 训练任务实体
+ */
+@Mapper
+public interface TrainTaskMapper extends BaseMapper<TrainTask> {
+}

+ 17 - 0
xvji-admin/src/main/java/com/xvji/service/ComponentService.java

@@ -0,0 +1,17 @@
+package com.xvji.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.xvji.domain.Component;
+import java.util.List;
+
+public interface ComponentService extends IService<Component> {
+    /**
+     * 新增组件
+     */
+    boolean addComponent(Component component);
+
+    /**
+     * 根据任务ID查询组件
+     */
+    List<Component> getComponentsByTaskId(Long taskId);
+}

+ 24 - 0
xvji-admin/src/main/java/com/xvji/service/PredictTaskService.java

@@ -0,0 +1,24 @@
+package com.xvji.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.xvji.domain.Component;
+import com.xvji.domain.PredictTask;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface PredictTaskService extends IService<PredictTask> {
+    /**
+     * 新增预测任务并关联组件
+     * @param predictTask 预测任务信息
+     * @param component 关联的组件信息
+     * @return 操作结果
+     */
+    boolean addPredictTaskWithComponent(PredictTask predictTask, Component component);
+
+    /**
+     * 查询所有预测任务
+     */
+    List<PredictTask> getAllPredictTasks();
+
+}

+ 27 - 0
xvji-admin/src/main/java/com/xvji/service/TrainTaskService.java

@@ -0,0 +1,27 @@
+package com.xvji.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.xvji.domain.Component;
+import com.xvji.domain.TrainTask;
+
+import java.util.List;
+
+/**
+ * 训练任务服务接口(继承MyBatis-Plus的IService,获取基础CRUD能力)
+ */
+public interface TrainTaskService extends IService<TrainTask> {
+
+    /**
+     * 新增训练任务并关联单个组件(可选方法,用于单独新增场景)
+     * @param trainTask 训练任务信息
+     * @param component 关联组件信息
+     * @return 操作结果(true成功,false失败)
+     */
+    boolean addTrainTaskWithComponent(TrainTask trainTask, Component component);
+
+    /**
+     * 查询所有训练任务(自定义查询方法)
+     * @return 训练任务列表
+     */
+    List<TrainTask> getAllTrainTasks();
+}

+ 25 - 0
xvji-admin/src/main/java/com/xvji/service/impl/ComponentServiceImpl.java

@@ -0,0 +1,25 @@
+package com.xvji.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xvji.domain.Component;
+import com.xvji.mapper.ComponentMapper;
+import com.xvji.service.ComponentService;
+import org.springframework.stereotype.Service;
+import java.util.List;
+
+@Service
+public class ComponentServiceImpl extends ServiceImpl<ComponentMapper, Component> implements ComponentService {
+
+    @Override
+    public boolean addComponent(Component component) {
+        if (component.getIsEnable() == null) {
+            component.setIsEnable(true);
+        }
+        return save(component);
+    }
+
+    @Override
+    public List<Component> getComponentsByTaskId(Long taskId) {
+        return lambdaQuery().eq(Component::getTaskId, taskId).list();
+    }
+}

+ 64 - 0
xvji-admin/src/main/java/com/xvji/service/impl/PredictTaskServiceImpl.java

@@ -0,0 +1,64 @@
+package com.xvji.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xvji.domain.Component;
+import com.xvji.domain.PredictTask;
+import com.xvji.mapper.PredictTaskMapper;
+import com.xvji.service.ComponentService;
+import com.xvji.service.PredictTaskService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class PredictTaskServiceImpl extends ServiceImpl<PredictTaskMapper, PredictTask> implements PredictTaskService {
+
+    @Autowired
+    private ComponentService componentService;
+
+    /**
+     * 新增预测任务并关联组件(事务保证:任务和组件要么同时成功,要么同时失败)
+     */
+    @Transactional
+    @Override
+    public boolean addPredictTaskWithComponent(PredictTask predictTask, Component component) {
+        // 设置预测任务默认值
+        if (predictTask.getPCreateTime() == null) {
+            predictTask.setPCreateTime(new Date());
+        }
+        if (predictTask.getPTaskStatus() == null) {
+            predictTask.setPTaskStatus(0); // 0-初始状态
+        }
+
+        // 插入预测任务
+        boolean taskSaved = this.save(predictTask);
+        if (!taskSaved) {
+            throw new RuntimeException("预测任务插入失败");
+        }
+
+        // 设置关联的任务ID和类型(1-预测任务)
+        component.setTaskId(predictTask.getPTaskId());
+        component.setTaskType(1);
+        if (component.getIsEnable() == null) {
+            component.setIsEnable(true);
+        }
+
+        // 4. 插入组件
+        boolean componentSaved = componentService.save(component);
+        if (!componentSaved) {
+            throw new RuntimeException("组件插入失败");
+        }
+
+        return true;
+    }
+
+    @Override
+    public List<PredictTask> getAllPredictTasks() {
+        return list();
+    }
+
+
+}

+ 61 - 0
xvji-admin/src/main/java/com/xvji/service/impl/TrainTaskServiceImpl.java

@@ -0,0 +1,61 @@
+package com.xvji.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xvji.domain.Component;
+import com.xvji.domain.TrainTask;
+import com.xvji.mapper.TrainTaskMapper;
+import com.xvji.service.ComponentService;
+import com.xvji.service.TrainTaskService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 训练任务服务实现类(基于MyBatis-Plus的ServiceImpl封装)
+ */
+@Service
+public class TrainTaskServiceImpl extends ServiceImpl<TrainTaskMapper, TrainTask> implements TrainTaskService {
+
+    @Autowired
+    private ComponentService componentService;
+
+    /**
+     * 新增训练任务并关联单个组件(事务保证)
+     * 额外处理:默认填充任务创建时间、任务状态
+     */
+    @Transactional
+    @Override
+    public boolean addTrainTaskWithComponent(TrainTask trainTask, Component component) {
+        if (trainTask.getTCreateTime() == null) {
+            trainTask.setTCreateTime(new Date()); // 默认当前时间
+        }
+        if (trainTask.getTTaskStatus() == null) {
+            trainTask.setTTaskStatus(0); // 默认初始状态(1-成功,0-失败)
+        }
+
+        // 保存训练任务
+        boolean taskSaved = this.save(trainTask);
+        if (!taskSaved) {
+            throw new RuntimeException("训练任务保存失败");
+        }
+
+        component.setTaskId(trainTask.getTTaskId());
+        component.setTaskType(0);
+        if (component.getIsEnable() == null) {
+            component.setIsEnable(true); // 组件默认启用
+        }
+        return componentService.save(component);
+    }
+
+    /**
+     * 查询所有训练任务(直接调用Mapper的查询方法,可根据需求扩展条件)
+     */
+    @Override
+    public List<TrainTask> getAllTrainTasks() {
+        // 若需分页/条件查询,可扩展为 selectPage 或 selectList(QueryWrapper)
+        return baseMapper.selectList(null);
+    }
+}

+ 183 - 0
xvji-admin/src/main/java/com/xvji/web/controller/PredictTaskController.java

@@ -0,0 +1,183 @@
+package com.xvji.web.controller;
+
+import com.xvji.common.core.domain.AjaxResult;
+import com.xvji.domain.Component;
+import com.xvji.domain.PredictTask;
+import com.xvji.mapper.PredictTaskMapper;
+import com.xvji.service.ComponentService;
+import com.xvji.service.PredictTaskService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/task/predict")
+public class PredictTaskController {
+
+    @Autowired
+    private PredictTaskService predictTaskService;
+
+    @Autowired
+    private ComponentService componentService;
+
+    @Autowired
+    private PredictTaskMapper predictTaskMapper;
+
+    /**
+     * 新增预测任务及关联组件
+     */
+    @PostMapping("/addTask")
+    @Transactional
+    public AjaxResult addPredictTask(@RequestBody Map<String, Object> taskInfo) {
+        try {
+            PredictTask task = new PredictTask();
+            task.setPTaskName((String) taskInfo.get("pTaskName"));
+            task.setPCronExpression((String) taskInfo.get("pCronExpression"));
+            task.setPQuartzTask((String) taskInfo.get("pQuartzTask"));
+            task.setPRunInfo((String) taskInfo.get("pRunInfo"));
+
+            Object pTaskIdObj = taskInfo.get("pTaskId");
+            Long manualTaskId = null;
+            if (pTaskIdObj != null) {
+                // 校验ID格式
+                try {
+                    manualTaskId = Long.parseLong(pTaskIdObj.toString());
+                } catch (NumberFormatException e) {
+                    return AjaxResult.error("传入的任务 ID 格式不正确,请传数字类型");
+                }
+                // 校验ID是否已存在
+                PredictTask existTask = predictTaskMapper.selectById(manualTaskId);
+                if (existTask != null) { // 不为null说明ID已存在
+                    return AjaxResult.error("任务 ID 已存在:" + manualTaskId + ",请更换其他 ID");
+                }
+                task.setPTaskId(manualTaskId);
+            }
+
+            boolean taskAdded = predictTaskService.save(task);
+            if (!taskAdded) {
+                return AjaxResult.error("预测任务新增失败");
+            }
+
+            Long taskId = task.getPTaskId();
+            List<Long> componentIds = new ArrayList<>();
+
+            // 数据获取组件
+            Map<String, Object> dataAcquisition = (Map<String, Object>) taskInfo.get("dataAcquisition");
+            if (dataAcquisition != null && (Boolean) dataAcquisition.get("enable")) {
+                Component component = createComponent(taskId, "数据获取", dataAcquisition);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("数据获取组件保存失败");
+                }
+            }
+
+            // 数据处理组件
+            Map<String, Object> dataCleaning = (Map<String, Object>) taskInfo.get("dataCleaning");
+            if (dataCleaning != null && (Boolean) dataCleaning.get("enable")) {
+                Component component = createComponent(taskId, "数据处理", dataCleaning);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("数据处理组件保存失败");
+                }
+            }
+
+            // 限电清洗-光伏组件
+            Map<String, Object> powerRationing = (Map<String, Object>) taskInfo.get("powerRationing");
+            if (powerRationing != null && (Boolean) powerRationing.get("enable")) {
+                Component component = createComponent(taskId, "限电清洗-光伏", powerRationing);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("限电清洗-光伏组件保存失败");
+                }
+            }
+
+            //光伏物理模型组件
+            Map<String, Object> model = (Map<String, Object>) taskInfo.get("model");
+            if (model != null && (Boolean) model.get("enable")) {
+                Component component = createComponent(taskId, "光伏物理模型", model);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("光伏物理模型组件保存失败");
+                }
+            }
+
+            // 后处理
+            Map<String, Object> postProcessing = (Map<String, Object>) taskInfo.get("postProcessing");
+            if (postProcessing != null && (Boolean) postProcessing.get("enable")) {
+                Component component = createComponent(taskId, "后处理", postProcessing);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("后处理组件保存失败");
+                }
+            }
+
+            // 分析报告组件
+            Map<String, Object> analysisReport = (Map<String, Object>) taskInfo.get("analysisReport");
+            if (analysisReport != null && (Boolean) analysisReport.get("enable")) {
+                Component component = createComponent(taskId, "分析报告", analysisReport);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("分析报告组件保存失败");
+                }
+            }
+
+
+            // 3. 更新任务表中的组件 ID 关联(逗号分隔)
+            if (!componentIds.isEmpty()) {
+                String componentIdsStr = String.join(",", componentIds.stream()
+                        .map(String::valueOf)
+                        .collect(java.util.stream.Collectors.toList()));
+                task.setPComponentIds(componentIdsStr);
+                predictTaskService.updateById(task);
+            }
+
+            return AjaxResult.success("预测任务新增成功");
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxResult.error("新增失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 辅助方法:创建组件对象
+     * @param taskId 任务 ID
+     * @param componentType 组件类型
+     * @param config 组件配置
+     */
+    private Component createComponent(Long taskId, String componentType, Map<String, Object> config) {
+        Component component = new Component();
+        component.setTaskId(taskId);         // 关联当前预测任务 ID
+        component.setTaskType(1);            // 1-预测任务(固定标识)
+        component.setComponentType(componentType);
+        component.setParamsMap((Map<String, Object>) config.get("value"));
+        component.setIsEnable((Boolean) config.get("enable"));
+        String interfaceUrl = (String) config.get("interfaceUrl");
+        component.setInterfaceUrl(interfaceUrl);
+
+        return component;
+    }
+
+    /**
+     * 查询所有预测任务
+     */
+    @GetMapping
+    public AjaxResult getAllPredictTasks() {
+        List<PredictTask> tasks = predictTaskService.getAllPredictTasks();
+        return AjaxResult.success(tasks);
+    }
+}

+ 186 - 0
xvji-admin/src/main/java/com/xvji/web/controller/TrainTaskController.java

@@ -0,0 +1,186 @@
+package com.xvji.web.controller;
+
+import com.xvji.common.core.domain.AjaxResult;
+import com.xvji.domain.Component;
+import com.xvji.domain.TrainTask;
+import com.xvji.mapper.TrainTaskMapper;
+import com.xvji.service.ComponentService;
+import com.xvji.service.TrainTaskService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 训练任务控制器(对应train_task表及关联组件)
+ */
+@RestController
+@RequestMapping("/task/train")
+public class TrainTaskController {
+
+    @Autowired
+    private TrainTaskService trainTaskService;
+
+    @Autowired
+    private ComponentService componentService;
+
+    @Autowired
+    private TrainTaskMapper trainTaskMapper;
+
+    /**
+     * 新增训练任务及关联组件
+     * 逻辑说明:与预测任务一致,额外处理训练分析报告字段(传则存,不传则空)
+     */
+    @PostMapping("/addTask")
+    @Transactional
+    public AjaxResult addTrainTask(@RequestBody Map<String, Object> taskInfo) {
+        try {
+            TrainTask task = new TrainTask();
+            task.setTTaskName((String) taskInfo.get("tTaskName"));
+            task.setTCronExpression((String) taskInfo.get("tCronExpression"));
+            task.setTQuartzTask((String) taskInfo.get("tQuartzTask"));
+            task.setTRunInfo((String) taskInfo.get("tRunInfo"));
+            task.setTAnalysisReport((String) taskInfo.get("tAnalysisReport"));
+
+            Object tTaskIdObj = taskInfo.get("tTaskId");
+            Long manualTaskId = null;
+            if (tTaskIdObj != null) {
+                //校验ID格式
+                try {
+                    manualTaskId = Long.parseLong(tTaskIdObj.toString());
+                } catch (NumberFormatException e) {
+                    return AjaxResult.error("传入的任务ID格式不正确,请传数字类型");
+                }
+                //校验ID是否已存在
+                TrainTask existTask = trainTaskMapper.selectById(manualTaskId);
+                if (existTask != null) {
+                    return AjaxResult.error("任务ID已存在:" + manualTaskId + ",请更换其他ID");
+                }
+                task.setTTaskId(manualTaskId);
+            }
+
+            boolean taskAdded = trainTaskService.save(task);
+            if (!taskAdded) {
+                return AjaxResult.error("训练任务新增失败");
+            }
+
+            Long taskId = task.getTTaskId();
+            List<Long> componentIds = new ArrayList<>();
+
+            //数据获取组件
+            Map<String, Object> dataAcquisition = (Map<String, Object>) taskInfo.get("dataAcquisition");
+            if (dataAcquisition != null && (Boolean) dataAcquisition.get("enable")) {
+                Component component = createComponent(taskId, "数据获取", dataAcquisition);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("数据获取组件保存失败");
+                }
+            }
+
+            // 数据处理组件
+            Map<String, Object> dataPreprocess = (Map<String, Object>) taskInfo.get("dataCleaning");
+            if (dataPreprocess != null && (Boolean) dataPreprocess.get("enable")) {
+                Component component = createComponent(taskId, "数据处理", dataPreprocess);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("数据处理组件保存失败");
+                }
+            }
+
+            //限电清洗-光伏 组件
+            Map<String, Object> powerRationing = (Map<String, Object>) taskInfo.get("powerRationing");
+            if (powerRationing != null && (Boolean) powerRationing.get("enable")) {
+                Component component = createComponent(taskId, "限电清洗-光伏", powerRationing);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("限电清洗-光伏组件保存失败");
+                }
+            }
+
+            //光伏物理模型组件
+            Map<String, Object> model = (Map<String, Object>) taskInfo.get("model");
+            if (model != null && (Boolean) model.get("enable")) {
+                Component component = createComponent(taskId, "光伏物理模型", model);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("光伏物理模型组件保存失败");
+                }
+            }
+
+            // 后处理
+            Map<String, Object> postProcessing = (Map<String, Object>) taskInfo.get("postProcessing");
+            if (postProcessing != null && (Boolean) postProcessing.get("enable")) {
+                Component component = createComponent(taskId, "后处理", postProcessing);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("后处理组件保存失败");
+                }
+            }
+
+            // 分析报告组件
+            Map<String, Object> analysisReport = (Map<String, Object>) taskInfo.get("analysisReport");
+            if (analysisReport != null && (Boolean) analysisReport.get("enable")) {
+                Component component = createComponent(taskId, "分析报告", analysisReport);
+                boolean saved = componentService.save(component);
+                if (saved) {
+                    componentIds.add(component.getComponentId());
+                } else {
+                    throw new RuntimeException("分析报告组件保存失败");
+                }
+            }
+
+            //更新任务表中的关联组件ID
+            if (!componentIds.isEmpty()) {
+                String componentIdsStr = String.join(",", componentIds.stream()
+                        .map(String::valueOf)
+                        .collect(java.util.stream.Collectors.toList()));
+                task.setTComponentIds(componentIdsStr);
+                trainTaskService.updateById(task);
+            }
+
+            return AjaxResult.success("训练任务新增成功");
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxResult.error("新增失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 辅助方法:创建组件对象(训练任务专用,taskType固定为0)
+     * @param taskId 训练任务ID
+     * @param componentType 组件类型(如数据预处理、模型训练)
+     * @param config 组件配置(包含enable、value、interfaceUrl)
+     */
+    private Component createComponent(Long taskId, String componentType, Map<String, Object> config) {
+        Component component = new Component();
+        component.setTaskId(taskId);
+        component.setTaskType(0); // 训练任务固定标识:0-训练任务
+        component.setComponentType(componentType);
+        component.setParamsMap((Map<String, Object>) config.get("value")); // 组件参数(JSON字符串存储)
+        component.setIsEnable((Boolean) config.get("enable")); // 组件启用状态
+        component.setInterfaceUrl((String) config.get("interfaceUrl")); // 接口地址:传则存,不传则空
+        return component;
+    }
+
+    /**
+     * 查询所有训练任务(与预测任务查询逻辑一致)
+     */
+    @GetMapping
+    public AjaxResult getAllTrainTasks() {
+        List<TrainTask> tasks = trainTaskService.getAllTrainTasks();
+        return AjaxResult.success(tasks);
+    }
+}

+ 25 - 15
xvji-admin/src/main/resources/application.yml

@@ -102,21 +102,31 @@ token:
     # 令牌有效期(六个小时过期重新登陆)
     expireTime: 360
   
-# MyBatis配置
-mybatis:
-    # 搜索指定包别名
-    typeAliasesPackage: com.xvji.**.domain
-    # 配置mapper的扫描,找到所有的mapper.xml映射文件
-    mapperLocations: classpath*:mapper/**/*Mapper.xml
-    # 加载全局的配置文件
-    configLocation: classpath:mybatis/mybatis-config.xml
-
-# PageHelper分页插件
-pagehelper: 
-  helperDialect: mysql
-  supportMethodsArguments: true
-  params: count=countSql 
-
+# MyBatis-Plus配置(替换原MyBatis配置)
+mybatis-plus:
+  # 搜索指定包别名(与原配置保持一致,无需修改)
+  type-aliases-package: com.xvji.**.domain
+  # 配置mapper的扫描(若有自定义XML映射文件可保留,无则可省略)
+  mapper-locations: classpath*:mapper/**/*Mapper.xml
+  # 全局配置
+  global-config:
+    db-config:
+      # 全局默认主键类型(自增)
+      id-type: auto
+      # 逻辑删除字段名(若需逻辑删除可配置,否则默认null)
+      logic-delete-field: deleted
+      # 逻辑删除值(默认为1)
+      logic-delete-value: 1
+      # 未逻辑删除值(默认为0)
+      logic-not-delete-value: 0
+  # 核心配置
+  configuration:
+    # 开启驼峰命名转换(如数据库字段 p_task_id → 实体类 pTaskId)
+    map-underscore-to-camel-case: true
+    # 打印SQL日志(开发阶段开启,生产关闭)
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+    # 允许返回嵌套结果(复杂对象映射)
+    aggressive-lazy-loading: true
 # Swagger配置
 swagger:
   # 是否开启swagger