From 21b6ff4389162ddc03594ad411728ee0a6f4ef94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=87=A4=E5=90=89?= Date: Sat, 10 May 2025 09:46:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=AE=9E=E9=AA=8C=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iflytop/gd/app/controller/TasksController.java | 76 +++++++++++++ .../com/iflytop/gd/app/mapper/TaskStepsMapper.java | 15 +++ .../com/iflytop/gd/app/mapper/TasksMapper.java | 23 ++++ .../com/iflytop/gd/app/model/dto/StopTaskDTO.java | 10 ++ .../java/com/iflytop/gd/app/model/dto/TaskDTO.java | 10 ++ .../com/iflytop/gd/app/model/entity/TaskSteps.java | 30 ++++++ .../com/iflytop/gd/app/model/entity/Tasks.java | 35 ++++++ .../com/iflytop/gd/app/model/vo/TaskListVO.java | 35 ++++++ .../iflytop/gd/app/service/TaskStepsService.java | 26 +++++ .../com/iflytop/gd/app/service/TasksService.java | 119 +++++++++++++++++++++ src/main/resources/sql/init.sql | 23 ++++ 11 files changed, 402 insertions(+) create mode 100644 src/main/java/com/iflytop/gd/app/controller/TasksController.java create mode 100644 src/main/java/com/iflytop/gd/app/mapper/TaskStepsMapper.java create mode 100644 src/main/java/com/iflytop/gd/app/mapper/TasksMapper.java create mode 100644 src/main/java/com/iflytop/gd/app/model/dto/StopTaskDTO.java create mode 100644 src/main/java/com/iflytop/gd/app/model/dto/TaskDTO.java create mode 100644 src/main/java/com/iflytop/gd/app/model/entity/TaskSteps.java create mode 100644 src/main/java/com/iflytop/gd/app/model/entity/Tasks.java create mode 100644 src/main/java/com/iflytop/gd/app/model/vo/TaskListVO.java create mode 100644 src/main/java/com/iflytop/gd/app/service/TaskStepsService.java create mode 100644 src/main/java/com/iflytop/gd/app/service/TasksService.java diff --git a/src/main/java/com/iflytop/gd/app/controller/TasksController.java b/src/main/java/com/iflytop/gd/app/controller/TasksController.java new file mode 100644 index 0000000..d7eb169 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/controller/TasksController.java @@ -0,0 +1,76 @@ +package com.iflytop.gd.app.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.iflytop.gd.app.model.dto.StopTaskDTO; +import com.iflytop.gd.app.model.dto.TaskDTO; +import com.iflytop.gd.app.model.entity.Tasks; +import com.iflytop.gd.app.model.vo.TaskListVO; +import com.iflytop.gd.app.service.TasksService; +import com.iflytop.gd.common.base.BasePageQuery; +import com.iflytop.gd.common.result.PageResult; +import com.iflytop.gd.common.result.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +@Tag(name = "实验") +@RestController +@RequestMapping("/api/tasks") +@RequiredArgsConstructor +@Slf4j +public class TasksController { + private final TasksService tasksService; + + @Operation(summary = "实验列表") + @GetMapping("/list") + public PageResult getAllTasks(BasePageQuery pageQuery) { + IPage result = tasksService.getPage(pageQuery); + return PageResult.success(result); + } + + @Operation(summary = "实验详情") + @GetMapping("/{id}") + public Result detail(@PathVariable Long id) { + return Result.success(tasksService.selectById(id)); + } + + @Operation(summary = "获取正在进行的实验") + @GetMapping("/getIngTask") + public Result getIngTask() { + return Result.success(tasksService.getIngTask()); + } + + @Operation(summary = "添加新实验") + @PostMapping("/") + public Result addTask(@RequestBody TaskDTO dto) { + if (tasksService.getIngTask() != null) { + return Result.failed("存在正在运行的实验,请先停止"); + } + return Result.success(tasksService.addTask(dto.getName())); + } + + @Operation(summary = "更新实验") + @PutMapping("/") + public Result updateTask(@RequestBody Tasks task) { + + return Result.success(tasksService.updateById(task)); + } + + @Operation(summary = "删除实验") + @DeleteMapping("/{ids}") + public Result deleteTask(@Parameter(description = "实验ID,多个以英文逗号(,)分割") @PathVariable String ids) { + return Result.success(tasksService.removeByIds(ids)); + } + + @Operation(summary = "停止实验") + @PostMapping("/stop") + public Result stopTask(@RequestBody StopTaskDTO dto) { + if(dto.getTaskId() != null) { + return Result.success(tasksService.stopTask(dto.getTaskId())); + } + return Result.failed("停止实验失败"); + } +} diff --git a/src/main/java/com/iflytop/gd/app/mapper/TaskStepsMapper.java b/src/main/java/com/iflytop/gd/app/mapper/TaskStepsMapper.java new file mode 100644 index 0000000..6cded2a --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/mapper/TaskStepsMapper.java @@ -0,0 +1,15 @@ +package com.iflytop.gd.app.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.iflytop.gd.app.model.entity.TaskSteps; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 实验持久层接口 + */ +@Mapper +public interface TaskStepsMapper extends BaseMapper { + List getTaskStepsByTaskId(Long taskId); +} diff --git a/src/main/java/com/iflytop/gd/app/mapper/TasksMapper.java b/src/main/java/com/iflytop/gd/app/mapper/TasksMapper.java new file mode 100644 index 0000000..fc0ff97 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/mapper/TasksMapper.java @@ -0,0 +1,23 @@ +package com.iflytop.gd.app.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.iflytop.gd.app.model.entity.Tasks; +import com.iflytop.gd.app.model.vo.TaskListVO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 实验持久层接口 + */ +@Mapper +public interface TasksMapper extends BaseMapper { + Page selectPage(Page page); + + TaskListVO selectById(Long id); + + Integer removeByIds(List ids); + + int stopTask(Long taskId); +} diff --git a/src/main/java/com/iflytop/gd/app/model/dto/StopTaskDTO.java b/src/main/java/com/iflytop/gd/app/model/dto/StopTaskDTO.java new file mode 100644 index 0000000..18c1cee --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/model/dto/StopTaskDTO.java @@ -0,0 +1,10 @@ +package com.iflytop.gd.app.model.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class StopTaskDTO { + @Schema(description = "实验id") + private Long taskId; +} diff --git a/src/main/java/com/iflytop/gd/app/model/dto/TaskDTO.java b/src/main/java/com/iflytop/gd/app/model/dto/TaskDTO.java new file mode 100644 index 0000000..c153ed0 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/model/dto/TaskDTO.java @@ -0,0 +1,10 @@ +package com.iflytop.gd.app.model.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class TaskDTO { + @Schema(description = "实验名称") + private String name; +} diff --git a/src/main/java/com/iflytop/gd/app/model/entity/TaskSteps.java b/src/main/java/com/iflytop/gd/app/model/entity/TaskSteps.java new file mode 100644 index 0000000..2255ae2 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/model/entity/TaskSteps.java @@ -0,0 +1,30 @@ +package com.iflytop.gd.app.model.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = false) +@Schema(description = "实验步骤") +@TableName("task_steps") +@Data +public class TaskSteps { + + @NotBlank + @Schema(description = "id") + private Long id; + + @NotBlank + @Schema(description = "实验id") + private Long taskId; + + @NotBlank + @Schema(description = "步骤描述") + private String stepDescription; + + @NotBlank + @Schema(description = "创建时间") + private String createTime; +} diff --git a/src/main/java/com/iflytop/gd/app/model/entity/Tasks.java b/src/main/java/com/iflytop/gd/app/model/entity/Tasks.java new file mode 100644 index 0000000..8599609 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/model/entity/Tasks.java @@ -0,0 +1,35 @@ +package com.iflytop.gd.app.model.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.iflytop.gd.common.base.BaseEntity; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Schema(description = "实验") +@TableName("tasks") +@Data +public class Tasks extends BaseEntity { + + @NotBlank + @Schema(description = "实验名称") + private String name; + + @NotBlank + @Schema(description = "开始时间") + private String startTime; + + @Schema(description = "创建人") + private Long createUser; + + @Schema(description = "结束时间") + private String endTime; + + @Schema(description = "状态 1 执行中 2 执行完毕") + private Integer status; + + @Schema(description = "是否删除 0 未删除 1 已删除") + private Integer isDeleted; +} diff --git a/src/main/java/com/iflytop/gd/app/model/vo/TaskListVO.java b/src/main/java/com/iflytop/gd/app/model/vo/TaskListVO.java new file mode 100644 index 0000000..c23ad4f --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/model/vo/TaskListVO.java @@ -0,0 +1,35 @@ +package com.iflytop.gd.app.model.vo; + +import com.iflytop.gd.app.model.entity.TaskSteps; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +@EqualsAndHashCode(callSuper = false) +@Data +public class TaskListVO { + @Schema(description = "实验id") + private Long id; + + @Schema(description = "实验名称") + private String name; + + @NotBlank + @Schema(description = "开始时间") + private String startTime; + + @Schema(description = "创建人") + private Long createUser; + + @Schema(description = "结束时间") + private String endTime; + + @Schema(description = "状态 1 执行中 2 执行完毕") + private Integer status; + + @Schema(description = "实验步骤") + private List steps; +} diff --git a/src/main/java/com/iflytop/gd/app/service/TaskStepsService.java b/src/main/java/com/iflytop/gd/app/service/TaskStepsService.java new file mode 100644 index 0000000..fa2b3df --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/service/TaskStepsService.java @@ -0,0 +1,26 @@ +package com.iflytop.gd.app.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.iflytop.gd.app.mapper.TaskStepsMapper; +import com.iflytop.gd.app.model.entity.TaskSteps; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 实验业务实现类 + */ +@Service +@RequiredArgsConstructor +public class TaskStepsService extends ServiceImpl{ + private final TaskStepsMapper taskStepsMapper; + + public List getTaskStepsByTaskId(Long taskId) { + return taskStepsMapper.getTaskStepsByTaskId(taskId); + } + + public int addTaskSteps(TaskSteps taskSteps) { + return this.baseMapper.insert(taskSteps); + } +} diff --git a/src/main/java/com/iflytop/gd/app/service/TasksService.java b/src/main/java/com/iflytop/gd/app/service/TasksService.java new file mode 100644 index 0000000..507939c --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/service/TasksService.java @@ -0,0 +1,119 @@ +package com.iflytop.gd.app.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.iflytop.gd.app.mapper.TaskStepsMapper; +import com.iflytop.gd.app.mapper.TasksMapper; +import com.iflytop.gd.app.model.entity.TaskSteps; +import com.iflytop.gd.app.model.entity.Tasks; +import com.iflytop.gd.app.model.entity.User; +import com.iflytop.gd.app.model.vo.TaskListVO; +import com.iflytop.gd.common.base.BasePageQuery; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 实验业务实现类 + */ +@Service +@RequiredArgsConstructor +public class TasksService extends ServiceImpl{ + + private final TasksMapper tasksMapper; + private final UserService userService; + private final TaskStepsMapper taskStepsMapper; + private final TaskStepsService taskStepsService; + + public IPage getPage(BasePageQuery pageQuery) { + // 构建分页对象 + Page page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()); + + + IPage tasksIPage = tasksMapper.selectPage(page); + + + List taskIds = tasksIPage.getRecords().stream() + .map(TaskListVO::getId) + .toList(); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("task_id", taskIds); + List list = taskStepsMapper.selectList(queryWrapper); + + + Map> map = list.stream() + .collect(Collectors.groupingBy(TaskSteps::getTaskId)); + + + List taskList = tasksIPage.getRecords().stream().map(task -> { + TaskListVO taskListVO = new TaskListVO(); + taskListVO.setId(task.getId()); + taskListVO.setName(task.getName()); + taskListVO.setStatus(task.getStatus()); + taskListVO.setStartTime(task.getStartTime()); + taskListVO.setEndTime(task.getEndTime()); + taskListVO.setCreateUser(task.getCreateUser()); + + List steps = map.get(task.getId()); + taskListVO.setSteps(steps); + + return taskListVO; + }).collect(Collectors.toList()); + + + Page resultPage = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()); + resultPage.setTotal(tasksIPage.getTotal()); + resultPage.setRecords(taskList); + + return resultPage; + } + + public TaskListVO selectById(Long id) { + TaskListVO taskListVO = tasksMapper.selectById(id); + List taskSteps = taskStepsMapper.selectList(new QueryWrapper().eq("task_id", id)); + taskListVO.setSteps(taskSteps); + return taskListVO; + } + + public Tasks addTask(String taskName) { + Tasks tasks = new Tasks(); + tasks.setName(taskName); + User user = userService.getCurrentUser(); + tasks.setCreateUser(user.getId()); + tasks.setStatus(1); + tasks.setIsDeleted(0); + tasksMapper.insert(tasks); + TaskSteps taskSteps = new TaskSteps(); + taskSteps.setTaskId(tasks.getId()); + taskSteps.setStepDescription("开始实验"); + taskStepsService.addTaskSteps(taskSteps); + return tasks; + } + + public Tasks getIngTask() { + return tasksMapper.selectOne(new QueryWrapper().eq("status", 1)); + } + + public int removeByIds(String ids) { + List idsArr = Arrays.stream(ids.split(",")) + .map(Long::parseLong) + .collect(Collectors.toList()); + return tasksMapper.removeByIds(idsArr); + } + + public int stopTask(Long taskId) { + TaskSteps taskSteps = new TaskSteps(); + taskSteps.setTaskId(taskId); + taskSteps.setStepDescription("结束实验"); + taskStepsService.addTaskSteps(taskSteps); + return tasksMapper.stopTask(taskId); + } + +} diff --git a/src/main/resources/sql/init.sql b/src/main/resources/sql/init.sql index 4997ab0..795dcf8 100644 --- a/src/main/resources/sql/init.sql +++ b/src/main/resources/sql/init.sql @@ -117,3 +117,26 @@ CREATE TABLE IF NOT EXISTS system_log ( create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); + +-- 实验 表 +CREATE TABLE IF NOT EXISTS tasks +( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR NOT NULL, + start_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + end_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + status INTEGER, + create_user INTEGER, + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + is_deleted INTEGER +); + +-- 实验步骤记录 表 +CREATE TABLE IF NOT EXISTS task_steps +( + id INTEGER PRIMARY KEY AUTOINCREMENT, + task_id INTEGER, + step_description TEXT, + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); \ No newline at end of file