| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539 |
- package com.ruoyi.web.controller.robot;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.stream.Collectors;
- import javax.servlet.http.HttpServletResponse;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.http.ResponseEntity;
- import org.springframework.scheduling.support.CronTrigger;
- import org.springframework.scheduling.support.SimpleTriggerContext;
- import org.springframework.web.bind.annotation.*;
- import org.springframework.web.multipart.MultipartFile;
- import com.alibaba.fastjson2.JSON;
- import com.alibaba.fastjson2.JSONArray;
- import com.alibaba.fastjson2.JSONObject;
- import com.ruoyi.common.annotation.Log;
- import com.ruoyi.common.core.controller.BaseController;
- import com.ruoyi.common.core.domain.AjaxResult;
- import com.ruoyi.common.core.page.TableDataInfo;
- import com.ruoyi.common.enums.BusinessType;
- import com.ruoyi.common.utils.poi.ExcelUtil;
- import com.ruoyi.robot.domain.LdTask;
- import com.ruoyi.robot.domain.LdTaskExecutionLog;
- import com.ruoyi.robot.service.ILdTaskExecutionLogService;
- import com.ruoyi.robot.service.ILdTaskService;
- import io.swagger.annotations.Api;
- import io.swagger.annotations.ApiOperation;
- import io.swagger.annotations.ApiParam;
- /**
- * LD导航系统任务管理接口
- * 提供任务的增删改查及定时任务执行功能
- *
- * 接口前缀: /v1
- */
- @Api(tags = "LD导航系统任务管理接口")
- @RestController
- @RequestMapping("/v1")
- public class LdTaskController extends BaseController {
- @Autowired
- private ILdTaskService ldTaskService;
- @Autowired
- private ILdTaskExecutionLogService ldTaskExecutionLogService;
- /**
- * 1.1 获取任务列表
- * GET /v1/path/list?map=地图名
- */
- @ApiOperation("获取任务列表")
- @GetMapping("/path/list")
- public ResponseEntity<Map<String, Object>> getTaskList(
- @ApiParam("地图名称") @RequestParam(value = "map", required = false) String mapName) {
- try {
- Map<String, Object> response = new HashMap<>();
-
- List<LdTask> taskList;
- if (mapName != null && !mapName.isEmpty()) {
- taskList = ldTaskService.selectLdTaskListByMapName(mapName);
- } else {
- taskList = ldTaskService.selectLdTaskList(new LdTask());
- }
-
- List<Map<String, Object>> paths = taskList.stream().map(task -> {
- Map<String, Object> path = new HashMap<>();
- path.put("taskId", task.getId());
- path.put("taskName", task.getTaskName());
- path.put("status", task.getStatus());
- path.put("cron", task.getCronExpression());
- path.put("executeTime", task.getExecuteTime());
- path.put("executeWeekdays", task.getExecuteWeekdays());
- path.put("repeatCount", task.getRepeatCount());
-
- // 解析目标点坐标
- if (task.getWaypointCoords() != null && !task.getWaypointCoords().isEmpty()) {
- try {
- path.put("coord", JSON.parse(task.getWaypointCoords()));
- } catch (Exception e) {
- path.put("coord", new java.util.ArrayList<>());
- }
- } else {
- path.put("coord", new java.util.ArrayList<>());
- }
-
- // 解析目标点类型
- if (task.getWaypointTypes() != null && !task.getWaypointTypes().isEmpty()) {
- try {
- path.put("plan", JSON.parse(task.getWaypointTypes()));
- } catch (Exception e) {
- path.put("plan", new java.util.ArrayList<>());
- }
- } else {
- path.put("plan", new java.util.ArrayList<>());
- }
-
- // 解析目标点动作
- if (task.getWaypointActions() != null && !task.getWaypointActions().isEmpty()) {
- try {
- path.put("action", JSON.parse(task.getWaypointActions()));
- } catch (Exception e) {
- path.put("action", new java.util.ArrayList<>());
- }
- } else {
- path.put("action", new java.util.ArrayList<>());
- }
-
- path.put("map", task.getMapName());
- path.put("lastExecuteTime", task.getLastExecuteTime());
- path.put("totalExecuteCount", task.getTotalExecuteCount());
- return path;
- }).collect(Collectors.toList());
-
- response.put("status", true);
- response.put("paths", paths);
- response.put("total", paths.size());
-
- return ResponseEntity.ok(response);
- } catch (Exception e) {
- logger.error("获取任务列表异常", e);
- return buildErrorResponse(4, "内部错误: " + e.getMessage());
- }
- }
- /**
- * 1.2 获取任务详情
- * GET /v1/path?map=地图名&path=任务名
- */
- @ApiOperation("获取任务详情")
- @GetMapping("/path")
- public ResponseEntity<Map<String, Object>> getTask(
- @ApiParam("地图名称") @RequestParam("map") String mapName,
- @ApiParam("任务名称") @RequestParam("path") String taskName) {
- try {
- LdTask task = ldTaskService.selectLdTaskByMapAndName(mapName, taskName);
-
- if (task == null) {
- return buildErrorResponse(2, "任务不存在");
- }
-
- Map<String, Object> response = new HashMap<>();
- response.put("status", true);
- response.put("taskId", task.getId());
- response.put("taskName", task.getTaskName());
- response.put("taskDesc", task.getTaskDesc());
- response.put("status", task.getStatus());
- response.put("cron", task.getCronExpression());
- response.put("executeTime", task.getExecuteTime());
- response.put("executeWeekdays", task.getExecuteWeekdays());
- response.put("repeatCount", task.getRepeatCount());
- response.put("coord_type", task.getCoordType());
- response.put("map", task.getMapName());
-
- // 解析目标点坐标
- if (task.getWaypointCoords() != null && !task.getWaypointCoords().isEmpty()) {
- response.put("coord", JSON.parse(task.getWaypointCoords()));
- } else {
- response.put("coord", new java.util.ArrayList<>());
- }
-
- // 解析目标点类型
- if (task.getWaypointTypes() != null && !task.getWaypointTypes().isEmpty()) {
- response.put("plan", JSON.parse(task.getWaypointTypes()));
- } else {
- response.put("plan", new java.util.ArrayList<>());
- }
-
- // 解析目标点动作
- if (task.getWaypointActions() != null && !task.getWaypointActions().isEmpty()) {
- response.put("action", JSON.parse(task.getWaypointActions()));
- } else {
- response.put("action", new java.util.ArrayList<>());
- }
-
- // 解析目标点ID
- if (task.getWaypointIds() != null && !task.getWaypointIds().isEmpty()) {
- response.put("waypointIds", JSON.parse(task.getWaypointIds()));
- } else {
- response.put("waypointIds", new java.util.ArrayList<>());
- }
-
- response.put("lastExecuteTime", task.getLastExecuteTime());
- response.put("lastExecuteStatus", task.getLastExecuteStatus());
- response.put("nextExecuteTime", task.getNextExecuteTime());
- response.put("totalExecuteCount", task.getTotalExecuteCount());
-
- return ResponseEntity.ok(response);
- } catch (Exception e) {
- logger.error("获取任务详情异常", e);
- return buildErrorResponse(4, "内部错误: " + e.getMessage());
- }
- }
- /**
- * 1.3 创建任务
- * POST /v1/path
- */
- @ApiOperation("创建任务")
- @PostMapping("/path")
- public ResponseEntity<Map<String, Object>> createTask(@RequestBody JSONObject taskData) {
- try {
- String mapName = taskData.getString("map");
- String pathName = taskData.getString("path");
-
- if (mapName == null || mapName.isEmpty() || pathName == null || pathName.isEmpty()) {
- return buildErrorResponse(1, "请求参数不合法:缺少map或path参数");
- }
-
- // 检查任务是否已存在
- LdTask existingTask = ldTaskService.selectLdTaskByMapAndName(mapName, pathName);
- if (existingTask != null) {
- return buildErrorResponse(2, "任务已存在");
- }
-
- // 构建任务对象
- LdTask task = new LdTask();
- task.setMapName(mapName);
- task.setTaskName(pathName);
- task.setTaskDesc(taskData.getString("desc"));
- task.setCronExpression(taskData.getString("cron"));
- task.setExecuteTime(taskData.getString("executeTime"));
- task.setExecuteWeekdays(taskData.getString("executeWeekdays"));
- task.setRepeatCount(taskData.getInteger("repeate") != null ? taskData.getInteger("repeate") : 1);
- task.setCoordType(taskData.getString("coord_type") != null ? taskData.getString("coord_type") : "local");
- task.setStatus("idle");
- task.setTotalExecuteCount(0);
-
- // 保存目标点坐标
- Object coordObj = taskData.get("coord");
- if (coordObj != null) {
- task.setWaypointCoords(JSON.toJSONString(coordObj));
- }
-
- // 保存目标点类型
- Object planObj = taskData.get("plan");
- if (planObj != null) {
- task.setWaypointTypes(JSON.toJSONString(planObj));
- }
-
- // 保存目标点动作
- Object actionObj = taskData.get("action");
- if (actionObj != null) {
- task.setWaypointActions(JSON.toJSONString(actionObj));
- }
-
- // 保存目标点ID
- Object waypointIdsObj = taskData.get("waypointIds");
- if (waypointIdsObj != null) {
- task.setWaypointIds(JSON.toJSONString(waypointIdsObj));
- }
-
- // 计算下次执行时间
- if (task.getCronExpression() != null && !task.getCronExpression().isEmpty()) {
- task.setNextExecuteTime(calculateNextExecuteTime(task.getCronExpression()));
- }
-
- int result = ldTaskService.insertLdTask(task);
-
- Map<String, Object> response = new HashMap<>();
- if (result > 0) {
- response.put("status", true);
- response.put("taskId", task.getId());
- response.put("msg", "任务创建成功");
- } else {
- response.put("status", false);
- response.put("msg", "任务创建失败");
- }
-
- return ResponseEntity.ok(response);
- } catch (Exception e) {
- logger.error("创建任务异常", e);
- return buildErrorResponse(4, "内部错误: " + e.getMessage());
- }
- }
- /**
- * 1.4 更新任务
- * PUT /v1/path
- */
- @ApiOperation("更新任务")
- @PutMapping("/path")
- public ResponseEntity<Map<String, Object>> updateTask(@RequestBody JSONObject taskData) {
- try {
- Long taskId = taskData.getLong("taskId");
- String mapName = taskData.getString("map");
- String pathName = taskData.getString("path");
-
- if (taskId == null && (mapName == null || mapName.isEmpty() || pathName == null || pathName.isEmpty())) {
- return buildErrorResponse(1, "请求参数不合法:缺少taskId或map/path参数");
- }
-
- LdTask task;
- if (taskId != null) {
- task = ldTaskService.selectLdTaskById(taskId);
- } else {
- task = ldTaskService.selectLdTaskByMapAndName(mapName, pathName);
- }
-
- if (task == null) {
- return buildErrorResponse(2, "任务不存在");
- }
-
- // 更新字段
- if (taskData.containsKey("taskName")) {
- String newTaskName = taskData.getString("taskName");
- if (!newTaskName.equals(task.getTaskName())) {
- // 检查新名称是否已存在
- LdTask existingTask = ldTaskService.selectLdTaskByMapAndName(task.getMapName(), newTaskName);
- if (existingTask != null) {
- return buildErrorResponse(2, "任务名称已存在");
- }
- task.setTaskName(newTaskName);
- }
- }
-
- task.setTaskDesc(taskData.getString("desc"));
- task.setCronExpression(taskData.getString("cron"));
- task.setExecuteTime(taskData.getString("executeTime"));
- task.setExecuteWeekdays(taskData.getString("executeWeekdays"));
-
- if (taskData.containsKey("repeate")) {
- task.setRepeatCount(taskData.getInteger("repeate"));
- }
-
- // 更新目标点数据
- Object coordObj = taskData.get("coord");
- if (coordObj != null) {
- task.setWaypointCoords(JSON.toJSONString(coordObj));
- }
-
- Object planObj = taskData.get("plan");
- if (planObj != null) {
- task.setWaypointTypes(JSON.toJSONString(planObj));
- }
-
- Object actionObj = taskData.get("action");
- if (actionObj != null) {
- task.setWaypointActions(JSON.toJSONString(actionObj));
- }
-
- Object waypointIdsObj = taskData.get("waypointIds");
- if (waypointIdsObj != null) {
- task.setWaypointIds(JSON.toJSONString(waypointIdsObj));
- }
-
- // 重新计算下次执行时间
- if (task.getCronExpression() != null && !task.getCronExpression().isEmpty()) {
- task.setNextExecuteTime(calculateNextExecuteTime(task.getCronExpression()));
- }
-
- int result = ldTaskService.updateLdTask(task);
-
- Map<String, Object> response = new HashMap<>();
- response.put("status", result > 0);
- response.put("msg", result > 0 ? "任务更新成功" : "任务更新失败");
-
- return ResponseEntity.ok(response);
- } catch (Exception e) {
- logger.error("更新任务异常", e);
- return buildErrorResponse(4, "内部错误: " + e.getMessage());
- }
- }
- /**
- * 1.5 删除任务
- * DELETE /v1/path
- */
- @ApiOperation("删除任务")
- @DeleteMapping("/path")
- public ResponseEntity<Map<String, Object>> deleteTask(@RequestBody JSONObject params) {
- try {
- String mapName = params.getString("map");
- String taskName = params.getString("path");
- Long taskId = params.getLong("taskId");
-
- if (taskId == null && (mapName == null || taskName == null)) {
- return buildErrorResponse(1, "请求参数不合法:缺少taskId或map/path参数");
- }
-
- LdTask task;
- if (taskId != null) {
- task = ldTaskService.selectLdTaskById(taskId);
- } else {
- task = ldTaskService.selectLdTaskByMapAndName(mapName, taskName);
- }
-
- if (task == null) {
- return buildErrorResponse(2, "任务不存在");
- }
-
- int result = ldTaskService.deleteLdTaskById(task.getId());
-
- Map<String, Object> response = new HashMap<>();
- response.put("status", result > 0);
- response.put("msg", result > 0 ? "任务删除成功" : "任务删除失败");
-
- return ResponseEntity.ok(response);
- } catch (Exception e) {
- logger.error("删除任务异常", e);
- return buildErrorResponse(4, "内部错误: " + e.getMessage());
- }
- }
- /**
- * 1.6 更新任务状态
- * PUT /v1/path/status
- */
- @ApiOperation("更新任务状态")
- @PutMapping("/path/status")
- public ResponseEntity<Map<String, Object>> updateTaskStatus(
- @ApiParam("任务ID") @RequestParam("taskId") Long taskId,
- @ApiParam("新状态") @RequestParam("status") String status) {
- try {
- LdTask task = ldTaskService.selectLdTaskById(taskId);
- if (task == null) {
- return buildErrorResponse(2, "任务不存在");
- }
-
- int result = ldTaskService.updateTaskStatus(taskId, status);
-
- Map<String, Object> response = new HashMap<>();
- response.put("status", result > 0);
- response.put("msg", result > 0 ? "状态更新成功" : "状态更新失败");
-
- return ResponseEntity.ok(response);
- } catch (Exception e) {
- logger.error("更新任务状态异常", e);
- return buildErrorResponse(4, "内部错误: " + e.getMessage());
- }
- }
- /**
- * 1.7 获取任务执行记录
- * GET /v1/path/logs
- */
- @ApiOperation("获取任务执行记录")
- @GetMapping("/path/logs")
- public ResponseEntity<Map<String, Object>> getTaskLogs(
- @ApiParam("任务ID") @RequestParam(value = "taskId", required = false) Long taskId,
- @ApiParam("设备ID") @RequestParam(value = "deviceId", required = false) String deviceId,
- @ApiParam("地图名称") @RequestParam(value = "map", required = false) String mapName) {
- try {
- LdTaskExecutionLog logQuery = new LdTaskExecutionLog();
- if (taskId != null) {
- logQuery.setTaskId(taskId);
- }
- if (deviceId != null) {
- logQuery.setDeviceId(deviceId);
- }
- if (mapName != null) {
- logQuery.setMapName(mapName);
- }
-
- List<LdTaskExecutionLog> logs = ldTaskExecutionLogService.selectLdTaskExecutionLogList(logQuery);
-
- List<Map<String, Object>> logList = logs.stream().map(log -> {
- Map<String, Object> logMap = new HashMap<>();
- logMap.put("id", log.getId());
- logMap.put("taskId", log.getTaskId());
- logMap.put("taskName", log.getTaskName());
- logMap.put("mapName", log.getMapName());
- logMap.put("executeTime", log.getExecuteTime());
- logMap.put("endTime", log.getEndTime());
- logMap.put("status", log.getStatus());
- logMap.put("startWaypoint", log.getStartWaypoint());
- logMap.put("endWaypoint", log.getEndWaypoint());
- logMap.put("completedWaypoints", log.getCompletedWaypoints());
- logMap.put("totalWaypoints", log.getTotalWaypoints());
- logMap.put("errorCode", log.getErrorCode());
- logMap.put("errorMessage", log.getErrorMessage());
- logMap.put("deviceId", log.getDeviceId());
- return logMap;
- }).collect(Collectors.toList());
-
- Map<String, Object> response = new HashMap<>();
- response.put("status", true);
- response.put("logs", logList);
- response.put("total", logList.size());
-
- return ResponseEntity.ok(response);
- } catch (Exception e) {
- logger.error("获取任务执行记录异常", e);
- return buildErrorResponse(4, "内部错误: " + e.getMessage());
- }
- }
- /**
- * 1.8 获取设备今日执行记录
- * GET /v1/path/logs/today
- */
- @ApiOperation("获取设备今日执行记录")
- @GetMapping("/path/logs/today")
- public ResponseEntity<Map<String, Object>> getTodayExecutionLogs(
- @ApiParam("设备ID") @RequestParam("deviceId") String deviceId) {
- try {
- List<LdTaskExecutionLog> logs = ldTaskExecutionLogService.selectTodayExecutionLogsByDeviceId(deviceId);
-
- Map<String, Object> response = new HashMap<>();
- response.put("status", true);
- response.put("logs", logs);
- response.put("total", logs.size());
-
- return ResponseEntity.ok(response);
- } catch (Exception e) {
- logger.error("获取今日执行记录异常", e);
- return buildErrorResponse(4, "内部错误: " + e.getMessage());
- }
- }
- /**
- * 辅助方法:根据Cron表达式计算下次执行时间
- */
- private java.util.Date calculateNextExecuteTime(String cronExpression) {
- try {
- CronTrigger cronTrigger = new CronTrigger(cronExpression);
- SimpleTriggerContext triggerContext = new SimpleTriggerContext();
- return cronTrigger.nextExecutionTime(triggerContext);
- } catch (Exception e) {
- logger.warn("解析Cron表达式失败: {}", cronExpression, e);
- return null;
- }
- }
- /**
- * 构建错误响应
- */
- private ResponseEntity<Map<String, Object>> buildErrorResponse(int code, String msg) {
- Map<String, Object> response = new HashMap<>();
- response.put("status", false);
- response.put("code", code);
- response.put("msg", msg);
- return ResponseEntity.ok(response);
- }
- }
|