add:主页看板,任务完成情况统计、agv实时监控
This commit is contained in:
@@ -18,7 +18,7 @@ public enum TaskStatusEnum {
|
|||||||
BUSY("1", "BUSY", "执行中"),
|
BUSY("1", "BUSY", "执行中"),
|
||||||
FINISHED("2", "FINISHED", "完成"),
|
FINISHED("2", "FINISHED", "完成"),
|
||||||
CANCEL("3", "CANCEL", "取消"),
|
CANCEL("3", "CANCEL", "取消"),
|
||||||
FORCED_COMPLETION("4", "", "强制完成"),
|
FORCED_COMPLETION("4", "FORCED_COMPLETION", "强制完成"),
|
||||||
ERROR("99", "ERROR", "异常");
|
ERROR("99", "ERROR", "异常");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,11 +64,30 @@ public enum TaskStatusEnum {
|
|||||||
|
|
||||||
public static String getName(String code) {
|
public static String getName(String code) {
|
||||||
for (TaskStatusEnum c : TaskStatusEnum.values()) {
|
for (TaskStatusEnum c : TaskStatusEnum.values()) {
|
||||||
if (c.code == code) {
|
if (code.equals(c.code)) {
|
||||||
return c.name;
|
return c.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getNameByIndex(String index) {
|
||||||
|
for (TaskStatusEnum c : TaskStatusEnum.values()) {
|
||||||
|
if (index.equals(c.index)) {
|
||||||
|
return c.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCodeByIndex(String index) {
|
||||||
|
for (TaskStatusEnum c : TaskStatusEnum.values()) {
|
||||||
|
if (index.equals(c.index)) {
|
||||||
|
return c.code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import org.springframework.data.domain.Pageable;
|
|||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -591,4 +593,8 @@ public interface TaskService extends CommonService<Task> {
|
|||||||
TaskDto findByTaskCode(String task_code);
|
TaskDto findByTaskCode(String task_code);
|
||||||
|
|
||||||
List<TaskDto> queryAllHJReadyTask();
|
List<TaskDto> queryAllHJReadyTask();
|
||||||
|
|
||||||
|
List<Map<String, Object>> countByStatusAndCreateTimeBetween(
|
||||||
|
Date start,
|
||||||
|
Date end);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ import org.springframework.data.domain.Pageable;
|
|||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
@@ -1760,6 +1761,13 @@ public class TaskServiceImpl extends CommonServiceImpl<TaskMapper, Task> impleme
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> countByStatusAndCreateTimeBetween(Date start, Date end) {
|
||||||
|
|
||||||
|
return taskMapper.countByStatusAndCreateTimeBetween(DateUtil.format(start,"yyyy-MM-dd HH:mm:ss.SSS"),
|
||||||
|
DateUtil.format(end,"yyyy-MM-dd HH:mm:ss.SSS"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 把多个字符串拼接的inst_nextDevice_code解析成集合
|
* 把多个字符串拼接的inst_nextDevice_code解析成集合
|
||||||
|
|||||||
@@ -1,14 +1,30 @@
|
|||||||
package org.nl.acs.task.service.mapper;
|
package org.nl.acs.task.service.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
import org.nl.acs.common.base.CommonMapper;
|
import org.nl.acs.common.base.CommonMapper;
|
||||||
import org.nl.acs.task.domain.Task;
|
import org.nl.acs.task.domain.Task;
|
||||||
|
import org.nl.common.annotation.Query;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jiaolm
|
* @author jiaolm
|
||||||
* @date 2023-05-09
|
* @date 2023-05-09
|
||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public interface TaskMapper extends CommonMapper<Task> {
|
public interface TaskMapper extends CommonMapper<Task> {
|
||||||
|
/**
|
||||||
|
* 按状态和时间范围统计任务数量
|
||||||
|
*/
|
||||||
|
@Select("SELECT t.task_status AS status, COUNT(1) AS count FROM acs_task t " +
|
||||||
|
"WHERE t.create_time BETWEEN #{start} AND #{end} " +
|
||||||
|
"GROUP BY t.task_status")
|
||||||
|
List<Map<String, Object>> countByStatusAndCreateTimeBetween(
|
||||||
|
@Param("start") String start,
|
||||||
|
@Param("end") String end);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.nl.system.controller.dashboard;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.nl.system.service.dashboard.DashboardService;
|
||||||
|
import org.nl.system.service.dashboard.dto.ApiResponse;
|
||||||
|
import org.nl.system.service.monitor.MonitorService;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhengxuming
|
||||||
|
* @date 2025年8月15日14:12:53
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
|
||||||
|
@RequestMapping("/api/dashboard")
|
||||||
|
public class DashboardController {
|
||||||
|
|
||||||
|
private final DashboardService serverService;
|
||||||
|
|
||||||
|
@GetMapping("/today")
|
||||||
|
public ApiResponse<Object> getTodayTaskStats() {
|
||||||
|
return ApiResponse.success(serverService.getTodayTaskStats());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/seven-days")
|
||||||
|
public ApiResponse<Object> getSevenDaysTaskStats() {
|
||||||
|
return ApiResponse.success(serverService.getSevenDaysTaskStats());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package org.nl.system.controller.trajectory;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nl.common.base.TableDataInfo;
|
||||||
|
import org.nl.common.domain.query.PageQuery;
|
||||||
|
import org.nl.common.logging.annotation.Log;
|
||||||
|
import org.nl.system.service.trajectory.TrajectoryBackgroundService;
|
||||||
|
import org.nl.system.service.trajectory.dto.TrajectoryBackground;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/6/19
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/trajectoryBackground")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
@SaIgnore
|
||||||
|
public class TrajectoryBackgroundController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TrajectoryBackgroundService trajectoryBackgroundService;
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@Log("查询轨迹背景图")
|
||||||
|
public ResponseEntity<Object> query(@RequestParam Map whereJson, PageQuery page) {
|
||||||
|
return new ResponseEntity<>(TableDataInfo.build(trajectoryBackgroundService.queryAll(whereJson, page)), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@Log("新增轨迹背景图")
|
||||||
|
public ResponseEntity<Object> create(@Validated @RequestBody TrajectoryBackground trajectoryBackground) {
|
||||||
|
trajectoryBackgroundService.create(trajectoryBackground);
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
@Log("修改轨迹背景图")
|
||||||
|
public ResponseEntity<Object> update(@Validated @RequestBody TrajectoryBackground entity) {
|
||||||
|
trajectoryBackgroundService.update(entity);
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping
|
||||||
|
@Log("删除轨迹背景图")
|
||||||
|
public ResponseEntity<Object> delete(@RequestBody Set<String> ids) {
|
||||||
|
trajectoryBackgroundService.deleteAll(ids);
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/queryAllEnable")
|
||||||
|
@SaIgnore
|
||||||
|
public ResponseEntity<Object> queryAllEnable() {
|
||||||
|
return new ResponseEntity<>(TableDataInfo.build(trajectoryBackgroundService.queryAllEnable()), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package org.nl.system.controller.trajectory;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nl.common.base.TableDataInfo;
|
||||||
|
import org.nl.common.domain.query.PageQuery;
|
||||||
|
import org.nl.common.logging.annotation.Log;
|
||||||
|
import org.nl.system.service.trajectory.TrajectoryConfigurationService;
|
||||||
|
import org.nl.system.service.trajectory.dto.TrajectoryConfiguration;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/6/19
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/trajectoryConfiguration")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
@SaIgnore
|
||||||
|
public class TrajectoryConfigurationController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TrajectoryConfigurationService trajectoryConfigurationService;
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@Log("查询轨迹设备配置")
|
||||||
|
public ResponseEntity<Object> query(@RequestParam Map whereJson, PageQuery page) {
|
||||||
|
return new ResponseEntity<>(TableDataInfo.build(trajectoryConfigurationService.queryAll(whereJson, page)), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@Log("新增轨迹设备配置")
|
||||||
|
public ResponseEntity<Object> create(@Validated @RequestBody TrajectoryConfiguration trajectoryConfiguration) {
|
||||||
|
trajectoryConfigurationService.create(trajectoryConfiguration);
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
@Log("修改轨迹设备配置")
|
||||||
|
public ResponseEntity<Object> update(@Validated @RequestBody TrajectoryConfiguration entity) {
|
||||||
|
trajectoryConfigurationService.update(entity);
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping
|
||||||
|
@Log("删除轨迹设备配置")
|
||||||
|
public ResponseEntity<Object> delete(@RequestBody Set<String> ids) {
|
||||||
|
trajectoryConfigurationService.deleteAll(ids);
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/queryAllEnable")
|
||||||
|
@SaIgnore
|
||||||
|
public ResponseEntity<Object> queryAllEnable() {
|
||||||
|
return new ResponseEntity<>(TableDataInfo.build(trajectoryConfigurationService.queryAllEnable()), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package org.nl.system.controller.trajectory;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nl.common.logging.annotation.Log;
|
||||||
|
import org.nl.system.service.trajectory.TrajectoryService;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/6/19
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/trajectory")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
@SaIgnore
|
||||||
|
public class TrajectoryController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TrajectoryService trajectoryService;
|
||||||
|
|
||||||
|
@PostMapping("/queryDevice")
|
||||||
|
@Log(value = "查询设备状态")
|
||||||
|
@SaIgnore
|
||||||
|
public ResponseEntity<Object> queryDevice(@RequestBody String whereJson) throws Exception {
|
||||||
|
return new ResponseEntity<>(trajectoryService.queryDevice(whereJson), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.nl.system.service.dashboard;
|
||||||
|
|
||||||
|
import org.nl.system.service.dashboard.dto.DailyTaskStats;
|
||||||
|
import org.nl.system.service.dashboard.dto.TaskSummary;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhengxuming
|
||||||
|
* @date 2025-8-15 14:03:37
|
||||||
|
*/
|
||||||
|
public interface DashboardService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当天任务统计数据
|
||||||
|
*/
|
||||||
|
List<TaskSummary> getTodayTaskStats();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取近7天任务统计数据
|
||||||
|
*/
|
||||||
|
List<DailyTaskStats> getSevenDaysTaskStats();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package org.nl.system.service.dashboard.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ApiResponse<T> {
|
||||||
|
private int code; // 状态码:200成功,其他失败
|
||||||
|
private String message; // 消息
|
||||||
|
private T data; // 数据
|
||||||
|
|
||||||
|
public static <T> ApiResponse<T> success(T data) {
|
||||||
|
ApiResponse<T> response = new ApiResponse<>();
|
||||||
|
response.setCode(200);
|
||||||
|
response.setMessage("success");
|
||||||
|
response.setData(data);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ApiResponse<T> error(String message) {
|
||||||
|
ApiResponse<T> response = new ApiResponse<>();
|
||||||
|
response.setCode(500);
|
||||||
|
response.setMessage(message);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.nl.system.service.dashboard.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DailyTaskStats {
|
||||||
|
private String date;
|
||||||
|
private long readyCount;
|
||||||
|
private long busyCount;
|
||||||
|
private long finishedCount;
|
||||||
|
private long cancelCount;
|
||||||
|
private long forcedCompletionCount;
|
||||||
|
private long errorCount;
|
||||||
|
private long totalCount;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.nl.system.service.dashboard.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TaskSummary {
|
||||||
|
private String status; // 任务状态
|
||||||
|
private long count; // 数量
|
||||||
|
private double percentage; // 百分比(用于饼图)
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.nl.system.service.dashboard.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.BetweenFormatter;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import org.nl.acs.task.enums.TaskStatusEnum;
|
||||||
|
import org.nl.acs.task.service.TaskService;
|
||||||
|
import org.nl.common.utils.ElAdminConstant;
|
||||||
|
import org.nl.common.utils.FileUtil;
|
||||||
|
import org.nl.common.utils.StringUtils;
|
||||||
|
import org.nl.config.language.LangProcess;
|
||||||
|
import org.nl.system.service.dashboard.DashboardService;
|
||||||
|
import org.nl.system.service.dashboard.dto.DailyTaskStats;
|
||||||
|
import org.nl.system.service.dashboard.dto.TaskSummary;
|
||||||
|
import org.nl.system.service.monitor.MonitorService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import oshi.SystemInfo;
|
||||||
|
import oshi.hardware.CentralProcessor;
|
||||||
|
import oshi.hardware.GlobalMemory;
|
||||||
|
import oshi.hardware.HardwareAbstractionLayer;
|
||||||
|
import oshi.hardware.VirtualMemory;
|
||||||
|
import oshi.software.os.FileSystem;
|
||||||
|
import oshi.software.os.OSFileStore;
|
||||||
|
import oshi.software.os.OperatingSystem;
|
||||||
|
import oshi.util.FormatUtil;
|
||||||
|
import oshi.util.Util;
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @date 2020-05-02
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class DashboardServiceImpl implements DashboardService {
|
||||||
|
|
||||||
|
private final DecimalFormat df = new DecimalFormat("0.00");
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TaskService taskService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TaskSummary> getTodayTaskStats() {
|
||||||
|
// 获取今天的起始和结束时间
|
||||||
|
Date todayStart = DateUtil.beginOfDay(new Date());
|
||||||
|
Date todayEnd = DateUtil.endOfDay(new Date());
|
||||||
|
|
||||||
|
// 按状态分组统计
|
||||||
|
List<Map<String, Object>> statusCounts = taskService.countByStatusAndCreateTimeBetween(todayStart, todayEnd);
|
||||||
|
|
||||||
|
// 计算总任务数
|
||||||
|
long total = statusCounts.stream()
|
||||||
|
.mapToLong(item -> Long.parseLong(item.get("count").toString()))
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
// 转换为TaskSummary列表
|
||||||
|
return statusCounts.stream()
|
||||||
|
.map(item -> {
|
||||||
|
TaskSummary summary = new TaskSummary();
|
||||||
|
summary.setStatus(TaskStatusEnum.getNameByIndex(item.get("status").toString()));
|
||||||
|
summary.setCount(Long.parseLong(item.get("count").toString()));
|
||||||
|
summary.setPercentage(total > 0 ? (summary.getCount() * 100.0) / total : 0);
|
||||||
|
return summary;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DailyTaskStats> getSevenDaysTaskStats() {
|
||||||
|
List<DailyTaskStats> statsList = new ArrayList<>();
|
||||||
|
|
||||||
|
// 统计过去7天的数据
|
||||||
|
for (int i = 6; i >= 0; i--) {
|
||||||
|
Date date = DateUtil.offsetDay(new Date(),-i);
|
||||||
|
Date start = DateUtil.beginOfDay(date);
|
||||||
|
Date end = DateUtil.endOfDay(date);
|
||||||
|
|
||||||
|
DailyTaskStats dailyStats = new DailyTaskStats();
|
||||||
|
dailyStats.setDate(DateUtil.formatDate(date));
|
||||||
|
|
||||||
|
// 按状态统计
|
||||||
|
List<Map<String, Object>> statusCounts = taskService.countByStatusAndCreateTimeBetween(start, end);
|
||||||
|
|
||||||
|
// 计算各状态数量
|
||||||
|
long ready = 0, busy = 0, finished = 0, cancel = 0, forced_completion = 0, error = 0;
|
||||||
|
|
||||||
|
for (Map<String, Object> item : statusCounts) {
|
||||||
|
String status = item.get("status").toString();
|
||||||
|
long count = Long.parseLong(item.get("count").toString());
|
||||||
|
if(TaskStatusEnum.READY.getIndex().equals(status)){
|
||||||
|
ready = count;
|
||||||
|
}
|
||||||
|
if(TaskStatusEnum.BUSY.getIndex().equals(status)){
|
||||||
|
busy = count;
|
||||||
|
}
|
||||||
|
if(TaskStatusEnum.FINISHED.getIndex().equals(status)){
|
||||||
|
finished = count;
|
||||||
|
}
|
||||||
|
if(TaskStatusEnum.CANCEL.getIndex().equals(status)){
|
||||||
|
cancel = count;
|
||||||
|
}
|
||||||
|
if(TaskStatusEnum.FORCED_COMPLETION.getIndex().equals(status)){
|
||||||
|
forced_completion = count;
|
||||||
|
}
|
||||||
|
if(TaskStatusEnum.ERROR.getIndex().equals(status)){
|
||||||
|
error = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dailyStats.setReadyCount(ready);
|
||||||
|
dailyStats.setBusyCount(busy);
|
||||||
|
dailyStats.setFinishedCount(finished);
|
||||||
|
dailyStats.setCancelCount(cancel);
|
||||||
|
dailyStats.setForcedCompletionCount(forced_completion);
|
||||||
|
dailyStats.setErrorCount(error);
|
||||||
|
dailyStats.setTotalCount(ready + busy + finished + cancel + forced_completion +error);
|
||||||
|
|
||||||
|
statsList.add(dailyStats);
|
||||||
|
}
|
||||||
|
|
||||||
|
return statsList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package org.nl.system.service.trajectory;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import org.nl.acs.common.base.CommonService;
|
||||||
|
import org.nl.common.domain.query.PageQuery;
|
||||||
|
import org.nl.system.service.trajectory.dto.TrajectoryBackground;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/6/19
|
||||||
|
*/
|
||||||
|
public interface TrajectoryBackgroundService extends CommonService<TrajectoryBackground> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页
|
||||||
|
* @param whereJson
|
||||||
|
* @param page
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
IPage<TrajectoryBackground> queryAll(Map whereJson, PageQuery page);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建
|
||||||
|
* @param entity
|
||||||
|
*/
|
||||||
|
void create(TrajectoryBackground entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新
|
||||||
|
* @param entity
|
||||||
|
*/
|
||||||
|
void update(TrajectoryBackground entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
* @param ids
|
||||||
|
*/
|
||||||
|
void deleteAll(Set<String> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有已启用的配置设备
|
||||||
|
* @return List<TrajectoryConfiguration>
|
||||||
|
*/
|
||||||
|
List<TrajectoryBackground> queryAllEnable();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package org.nl.system.service.trajectory;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import org.nl.acs.common.base.CommonService;
|
||||||
|
import org.nl.common.domain.query.PageQuery;
|
||||||
|
import org.nl.system.service.trajectory.dto.TrajectoryConfiguration;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/6/19
|
||||||
|
*/
|
||||||
|
public interface TrajectoryConfigurationService extends CommonService<TrajectoryConfiguration> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页
|
||||||
|
* @param whereJson
|
||||||
|
* @param page
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
IPage<TrajectoryConfiguration> queryAll(Map whereJson, PageQuery page);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建
|
||||||
|
* @param entity
|
||||||
|
*/
|
||||||
|
void create(TrajectoryConfiguration entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新
|
||||||
|
* @param entity
|
||||||
|
*/
|
||||||
|
void update(TrajectoryConfiguration entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
* @param ids
|
||||||
|
*/
|
||||||
|
void deleteAll(Set<String> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有已启用的配置设备
|
||||||
|
* @return List<TrajectoryConfiguration>
|
||||||
|
*/
|
||||||
|
List<TrajectoryConfiguration> queryAllEnable();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.nl.system.service.trajectory;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/6/19
|
||||||
|
*/
|
||||||
|
public interface TrajectoryService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询设备状态
|
||||||
|
*
|
||||||
|
* @param jsonObject 条件
|
||||||
|
* @return Map<String, Object>
|
||||||
|
*/
|
||||||
|
Map<String, Object> queryDevice(String jsonObject) throws Exception;
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package org.nl.system.service.trajectory.dto;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liejiu
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("trajectory_background")
|
||||||
|
public class TrajectoryBackground implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 背景图标识
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private String background_uuid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 背景图名称
|
||||||
|
*/
|
||||||
|
private String background_code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 背景图片编码
|
||||||
|
*/
|
||||||
|
private String image_code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 背景图片地址
|
||||||
|
*/
|
||||||
|
private String image_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缩放比例(0-1之间 百分比)
|
||||||
|
*/
|
||||||
|
private String zoom_ratio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 坐标原点(1左上 2左下 3右上 4右下)
|
||||||
|
*/
|
||||||
|
private String coordinate_origin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* X坐标最大值
|
||||||
|
*/
|
||||||
|
private String max_x;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Y坐标最大值
|
||||||
|
*/
|
||||||
|
private String max_y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新时间(秒)
|
||||||
|
*/
|
||||||
|
private Integer refresh_time;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
private String is_active;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否删除
|
||||||
|
*/
|
||||||
|
private String is_delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建者
|
||||||
|
*/
|
||||||
|
private String create_id;
|
||||||
|
private String create_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private String create_time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改者
|
||||||
|
*/
|
||||||
|
private String update_id;
|
||||||
|
private String update_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改时间
|
||||||
|
*/
|
||||||
|
private String update_time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package org.nl.system.service.trajectory.dto;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liejiu
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("trajectory_configuration")
|
||||||
|
public class TrajectoryConfiguration implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置标识
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private String configuration_uuid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置名称
|
||||||
|
*/
|
||||||
|
private String configuration_code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标编码
|
||||||
|
*/
|
||||||
|
private String image_code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标名称
|
||||||
|
*/
|
||||||
|
private String image_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标高度
|
||||||
|
*/
|
||||||
|
private String image_height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标宽度
|
||||||
|
*/
|
||||||
|
private String image_width;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定设备编码
|
||||||
|
*/
|
||||||
|
private String device_code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
private String is_active;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否删除
|
||||||
|
*/
|
||||||
|
private String is_delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建者
|
||||||
|
*/
|
||||||
|
private String create_id;
|
||||||
|
private String create_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private String create_time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改者
|
||||||
|
*/
|
||||||
|
private String update_id;
|
||||||
|
private String update_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改时间
|
||||||
|
*/
|
||||||
|
private String update_time;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package org.nl.system.service.trajectory.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.nl.acs.common.base.impl.CommonServiceImpl;
|
||||||
|
import org.nl.common.domain.query.PageQuery;
|
||||||
|
import org.nl.common.exception.BadRequestException;
|
||||||
|
import org.nl.common.utils.SecurityUtils;
|
||||||
|
import org.nl.system.service.trajectory.TrajectoryBackgroundService;
|
||||||
|
import org.nl.system.service.trajectory.dto.TrajectoryBackground;
|
||||||
|
import org.nl.system.service.trajectory.mapper.TrajectoryBackgroundMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/6/19
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class TrajectoryBackgroundImpl extends CommonServiceImpl<TrajectoryBackgroundMapper, TrajectoryBackground> implements TrajectoryBackgroundService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TrajectoryBackgroundMapper trajectoryBackgroundMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage<TrajectoryBackground> queryAll(Map whereJson, PageQuery page) {
|
||||||
|
LambdaQueryWrapper<TrajectoryBackground> lam = new LambdaQueryWrapper<>();
|
||||||
|
IPage<TrajectoryBackground> pages = new Page<>(page.getPage() + 1, page.getSize());
|
||||||
|
trajectoryBackgroundMapper.selectPage(pages,lam);
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create(TrajectoryBackground entity) {
|
||||||
|
TrajectoryBackground stage = trajectoryBackgroundMapper.selectOne(new LambdaQueryWrapper<TrajectoryBackground>().eq(TrajectoryBackground::getBackground_code, entity.getBackground_code()));
|
||||||
|
if (ObjectUtil.isNotEmpty(stage)) {
|
||||||
|
throw new BadRequestException("背景图名称[" + entity.getBackground_code() + "]已存在");
|
||||||
|
}
|
||||||
|
String currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
String nickName = SecurityUtils.getCurrentNickName();
|
||||||
|
String now = DateUtil.now();
|
||||||
|
|
||||||
|
entity.setIs_active("1");
|
||||||
|
entity.setIs_delete("0");
|
||||||
|
entity.setBackground_uuid(IdUtil.simpleUUID());
|
||||||
|
entity.setCreate_id(currentUserId);
|
||||||
|
entity.setCreate_name(nickName);
|
||||||
|
entity.setCreate_time(now);
|
||||||
|
entity.setUpdate_id(currentUserId);
|
||||||
|
entity.setUpdate_name(nickName);
|
||||||
|
entity.setUpdate_time(now);
|
||||||
|
trajectoryBackgroundMapper.insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(TrajectoryBackground entity) {
|
||||||
|
TrajectoryBackground trajectoryBackground = trajectoryBackgroundMapper.selectOne(new LambdaQueryWrapper<TrajectoryBackground>().eq(TrajectoryBackground::getBackground_uuid, entity.getBackground_uuid()));
|
||||||
|
if (trajectoryBackground == null) {
|
||||||
|
throw new BadRequestException("未找到这条数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
String currentUsername = SecurityUtils.getCurrentNickName();
|
||||||
|
String currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
String now = DateUtil.now();
|
||||||
|
entity.setUpdate_time(now);
|
||||||
|
entity.setUpdate_id(currentUserId);
|
||||||
|
entity.setUpdate_name(currentUsername);
|
||||||
|
trajectoryBackgroundMapper.updateById(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAll(Set<String> ids) {
|
||||||
|
trajectoryBackgroundMapper.deleteBatchIds(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TrajectoryBackground> queryAllEnable() {
|
||||||
|
return new LambdaQueryChainWrapper<>(trajectoryBackgroundMapper)
|
||||||
|
.apply("is_delete= '0' AND is_active= '1'")
|
||||||
|
.orderByAsc(TrajectoryBackground::getBackground_uuid)
|
||||||
|
.list();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package org.nl.system.service.trajectory.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.nl.acs.common.base.impl.CommonServiceImpl;
|
||||||
|
import org.nl.common.domain.query.PageQuery;
|
||||||
|
import org.nl.common.exception.BadRequestException;
|
||||||
|
import org.nl.common.utils.SecurityUtils;
|
||||||
|
import org.nl.system.service.trajectory.TrajectoryConfigurationService;
|
||||||
|
import org.nl.system.service.trajectory.dto.TrajectoryConfiguration;
|
||||||
|
import org.nl.system.service.trajectory.mapper.TrajectoryConfigurationMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/6/19
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class TrajectoryConfigurationImpl extends CommonServiceImpl<TrajectoryConfigurationMapper, TrajectoryConfiguration> implements TrajectoryConfigurationService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TrajectoryConfigurationMapper trajectoryConfigurationMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage<TrajectoryConfiguration> queryAll(Map whereJson, PageQuery page) {
|
||||||
|
LambdaQueryWrapper<TrajectoryConfiguration> lam = new LambdaQueryWrapper<>();
|
||||||
|
IPage<TrajectoryConfiguration> pages = new Page<>(page.getPage() + 1, page.getSize());
|
||||||
|
trajectoryConfigurationMapper.selectPage(pages,lam);
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create(TrajectoryConfiguration entity) {
|
||||||
|
TrajectoryConfiguration stage = trajectoryConfigurationMapper.selectOne(new LambdaQueryWrapper<TrajectoryConfiguration>().eq(TrajectoryConfiguration::getConfiguration_code, entity.getConfiguration_code()));
|
||||||
|
if (ObjectUtil.isNotEmpty(stage)) {
|
||||||
|
throw new BadRequestException("轨迹图配置编码[" + entity.getConfiguration_code() + "]已存在");
|
||||||
|
}
|
||||||
|
String currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
String nickName = SecurityUtils.getCurrentNickName();
|
||||||
|
String now = DateUtil.now();
|
||||||
|
|
||||||
|
entity.setIs_delete("0");
|
||||||
|
entity.setConfiguration_uuid(IdUtil.simpleUUID());
|
||||||
|
entity.setCreate_id(currentUserId);
|
||||||
|
entity.setCreate_name(nickName);
|
||||||
|
entity.setCreate_time(now);
|
||||||
|
entity.setUpdate_id(currentUserId);
|
||||||
|
entity.setUpdate_name(nickName);
|
||||||
|
entity.setUpdate_time(now);
|
||||||
|
trajectoryConfigurationMapper.insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(TrajectoryConfiguration entity) {
|
||||||
|
TrajectoryConfiguration trajectoryBackground = trajectoryConfigurationMapper.selectOne(new LambdaQueryWrapper<TrajectoryConfiguration>().eq(TrajectoryConfiguration::getConfiguration_uuid, entity.getConfiguration_uuid()));
|
||||||
|
if (trajectoryBackground == null) {
|
||||||
|
throw new BadRequestException("未找到这条数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
String currentUsername = SecurityUtils.getCurrentNickName();
|
||||||
|
String currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
String now = DateUtil.now();
|
||||||
|
entity.setUpdate_time(now);
|
||||||
|
entity.setUpdate_id(currentUserId);
|
||||||
|
entity.setUpdate_name(currentUsername);
|
||||||
|
trajectoryConfigurationMapper.updateById(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAll(Set<String> ids) {
|
||||||
|
trajectoryConfigurationMapper.deleteBatchIds(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TrajectoryConfiguration> queryAllEnable() {
|
||||||
|
return new LambdaQueryChainWrapper<>(trajectoryConfigurationMapper)
|
||||||
|
.apply("is_delete= '0' AND is_active= '1'")
|
||||||
|
.orderByAsc(TrajectoryConfiguration::getConfiguration_uuid)
|
||||||
|
.list();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package org.nl.system.service.trajectory.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import org.nl.acs.device.domain.Device;
|
||||||
|
import org.nl.acs.device_driver.agv.ndcone.AgvNdcOneDeviceDriver;
|
||||||
|
import org.nl.acs.opc.DeviceAppService;
|
||||||
|
import org.nl.common.exception.BadRequestException;
|
||||||
|
import org.nl.system.service.trajectory.TrajectoryService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/6/19
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class TrajectoryImpl implements TrajectoryService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DeviceAppService deviceAppService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> queryDevice(String jsonObject) throws Exception {
|
||||||
|
JSONArray backja = new JSONArray();
|
||||||
|
JSONArray datas = JSONArray.parseArray(jsonObject);
|
||||||
|
//agv
|
||||||
|
AgvNdcOneDeviceDriver agvNdcOneDeviceDriver;
|
||||||
|
|
||||||
|
if (datas.size() == 0) {
|
||||||
|
throw new BadRequestException("缺少输入参数!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// for (int i = 0; i < datas.size(); i++) {
|
||||||
|
// JSONObject jo = new JSONObject();
|
||||||
|
// JSONObject ja = new JSONObject();
|
||||||
|
// JSONObject data = datas.getJSONObject(i);
|
||||||
|
// String device_code = data.getString("device_code");
|
||||||
|
// Device device = deviceAppService.findDeviceByCode(device_code);
|
||||||
|
// if (ObjectUtil.isEmpty(device)) {
|
||||||
|
// throw new Exception("未找到对应设备:" + device_code);
|
||||||
|
// }
|
||||||
|
// if (device.getDeviceDriver() instanceof AgvNdcOneDeviceDriver) {
|
||||||
|
// agvNdcOneDeviceDriver = (AgvNdcOneDeviceDriver) device.getDeviceDriver();
|
||||||
|
// jo.put("device_code", agvNdcOneDeviceDriver.getDevice().getDevice_code());
|
||||||
|
// jo.put("x", agvNdcOneDeviceDriver.getX());
|
||||||
|
// jo.put("y", agvNdcOneDeviceDriver.getY());
|
||||||
|
// jo.put("angle", agvNdcOneDeviceDriver.getAngle());
|
||||||
|
// ja.put(agvNdcOneDeviceDriver.getDevice().getDevice_code(),jo);
|
||||||
|
// }
|
||||||
|
// backja.add(ja);
|
||||||
|
// }
|
||||||
|
// JSONObject resultJson = new JSONObject();
|
||||||
|
// resultJson.put("status", HttpStatus.OK.value());
|
||||||
|
// resultJson.put("message", "操作成功");
|
||||||
|
// resultJson.put("data", backja);
|
||||||
|
// return resultJson;
|
||||||
|
JSONObject resultJson = new JSONObject();
|
||||||
|
Random rand = new Random();
|
||||||
|
for (int i = 0; i < datas.size(); i++) {
|
||||||
|
JSONObject jo = new JSONObject();
|
||||||
|
JSONObject data = datas.getJSONObject(i);
|
||||||
|
String device_code = data.getString("device_code");
|
||||||
|
jo.put("x", rand.nextInt(1001));
|
||||||
|
jo.put("y", rand.nextInt(501));
|
||||||
|
jo.put("angle", rand.nextInt(361));
|
||||||
|
jo.put("device_code", device_code);
|
||||||
|
backja.add(jo);
|
||||||
|
}
|
||||||
|
resultJson.put("status", HttpStatus.OK.value());
|
||||||
|
resultJson.put("message", "操作成功");
|
||||||
|
resultJson.put("data", backja);
|
||||||
|
return resultJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.nl.system.service.trajectory.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.nl.system.service.trajectory.dto.TrajectoryBackground;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liejiu
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface TrajectoryBackgroundMapper extends BaseMapper<TrajectoryBackground> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.nl.system.service.trajectory.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.nl.system.service.trajectory.dto.TrajectoryConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liejiu
|
||||||
|
*/
|
||||||
|
public interface TrajectoryConfigurationMapper extends BaseMapper<TrajectoryConfiguration> {
|
||||||
|
|
||||||
|
}
|
||||||
18
acs2/nladmin-ui/src/api/acs/dashboard/dashboard.js
Normal file
18
acs2/nladmin-ui/src/api/acs/dashboard/dashboard.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function getTodayTaskStats(param) {
|
||||||
|
return request({
|
||||||
|
url: '/api/dashboard/today',
|
||||||
|
method: 'get',
|
||||||
|
data: param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSevenDaysTaskStats() {
|
||||||
|
return request({
|
||||||
|
url: '/api/dashboard/seven-days',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { getTodayTaskStats, getSevenDaysTaskStats }
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function add(data) {
|
||||||
|
return request({
|
||||||
|
url: 'api/trajectoryConfiguration',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids) {
|
||||||
|
return request({
|
||||||
|
url: 'api/trajectoryConfiguration/',
|
||||||
|
method: 'delete',
|
||||||
|
data: ids
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function edit(data) {
|
||||||
|
return request({
|
||||||
|
url: 'api/trajectoryConfiguration',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { add, edit, del }
|
||||||
27
acs2/nladmin-ui/src/api/trajectory/trajectory_background.js
Normal file
27
acs2/nladmin-ui/src/api/trajectory/trajectory_background.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function add(data) {
|
||||||
|
return request({
|
||||||
|
url: 'api/trajectoryBackground',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids) {
|
||||||
|
return request({
|
||||||
|
url: 'api/trajectoryBackground/',
|
||||||
|
method: 'delete',
|
||||||
|
data: ids
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function edit(data) {
|
||||||
|
return request({
|
||||||
|
url: 'api/trajectoryBackground',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { add, edit, del }
|
||||||
BIN
acs2/nladmin-ui/src/assets/images/agvBackground.jpg
Normal file
BIN
acs2/nladmin-ui/src/assets/images/agvBackground.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 972 KiB |
BIN
acs2/nladmin-ui/src/assets/images/agvCar.png
Normal file
BIN
acs2/nladmin-ui/src/assets/images/agvCar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 822 KiB |
@@ -40,7 +40,7 @@ export const constantRouterMap = [
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'dashboard',
|
path: 'dashboard',
|
||||||
component: (resolve) => require(['@/views/monitor/server/index'], resolve),
|
component: (resolve) => require(['@/views/dashboard/index'], resolve),
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
meta: { title: i18n.t('auto.common.home'), icon: 'index', affix: true, noCache: true }
|
meta: { title: i18n.t('auto.common.home'), icon: 'index', affix: true, noCache: true }
|
||||||
}
|
}
|
||||||
|
|||||||
575
acs2/nladmin-ui/src/views/dashboard/index.vue
Normal file
575
acs2/nladmin-ui/src/views/dashboard/index.vue
Normal file
@@ -0,0 +1,575 @@
|
|||||||
|
<template>
|
||||||
|
<div class="task-stats-container">
|
||||||
|
<!-- 左侧:任务完成情况统计 -->
|
||||||
|
<el-card class="main-card left-card">
|
||||||
|
<div slot="header">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2>任务完成情况统计</h2>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-refresh"
|
||||||
|
:loading="refreshing"
|
||||||
|
@click="refreshData"
|
||||||
|
>
|
||||||
|
刷新数据
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 统计卡片区域 -->
|
||||||
|
<div class="stats-overview">
|
||||||
|
<el-card v-for="(item, index) in todayOverview" :key="index" class="stat-card">
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-label">{{ item.label }}</div>
|
||||||
|
<div class="stat-value">{{ item.value }}</div>
|
||||||
|
<div class="stat-desc">{{ item.desc }}</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 图表区域 - 垂直布局 -->
|
||||||
|
<div class="charts-container">
|
||||||
|
<!-- 当天任务完成情况饼图 -->
|
||||||
|
<el-card class="chart-card">
|
||||||
|
<div slot="header">当天任务完成情况</div>
|
||||||
|
<div class="chart-wrapper">
|
||||||
|
<v-chart :options="pieChartOptions" autoresize />
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 7天任务完成情况柱状图 -->
|
||||||
|
<el-card class="chart-card">
|
||||||
|
<div slot="header">近7天任务完成情况趋势</div>
|
||||||
|
<div class="chart-wrapper">
|
||||||
|
<v-chart :options="barChartOptions" autoresize />
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 右侧:show-track -->
|
||||||
|
<el-card class="main-card right-card">
|
||||||
|
<shou-track src="" />
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Card, Button, Tag } from 'element-ui'
|
||||||
|
import VChart from 'vue-echarts'
|
||||||
|
import 'echarts/lib/chart/pie'
|
||||||
|
import 'echarts/lib/chart/bar'
|
||||||
|
import 'echarts/lib/component/tooltip'
|
||||||
|
import 'echarts/lib/component/legend'
|
||||||
|
import 'echarts/lib/component/grid'
|
||||||
|
import 'echarts/lib/component/axis'
|
||||||
|
import taskStatsApi from '@/api/acs/dashboard/dashboard'
|
||||||
|
import ShouTrack from './showTrack/index.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'TaskStats',
|
||||||
|
components: {
|
||||||
|
'el-card': Card,
|
||||||
|
'el-button': Button,
|
||||||
|
'v-chart': VChart,
|
||||||
|
'shou-track': ShouTrack
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 数据状态
|
||||||
|
pieData: [],
|
||||||
|
barData: [],
|
||||||
|
todayOverview: [],
|
||||||
|
refreshing: false,
|
||||||
|
|
||||||
|
// 饼图配置
|
||||||
|
pieChartOptions: {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
orient: 'horizontal',
|
||||||
|
bottom: 2,
|
||||||
|
itemWidth: 6,
|
||||||
|
itemHeight: 3,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '任务状态',
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['30%', '60%'],
|
||||||
|
center: ['50%', '50%'],
|
||||||
|
avoidLabelOverlap: false,
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: 8,
|
||||||
|
borderColor: '#fff',
|
||||||
|
borderWidth: 2
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
position: 'center'
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
fontSize: '16',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 柱状图配置
|
||||||
|
barChartOptions: {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow'
|
||||||
|
},
|
||||||
|
formatter: function(params) {
|
||||||
|
let result = params[0].axisValue + '<br/>'
|
||||||
|
let total = 0
|
||||||
|
params.forEach(param => {
|
||||||
|
result += param.marker + param.seriesName + ': ' + param.value + '<br/>'
|
||||||
|
total += param.value
|
||||||
|
})
|
||||||
|
result += '<b>总计: ' + total + '</b>'
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['就绪', '执行中', '完成', '取消', '强制完成', '异常'],
|
||||||
|
top: 2,
|
||||||
|
left: 'center',
|
||||||
|
itemWidth: 6,
|
||||||
|
itemHeight: 3,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 8
|
||||||
|
},
|
||||||
|
pageButtonItemGap: 2,
|
||||||
|
pageButtonGap: 2,
|
||||||
|
pageButtonPosition: 'end',
|
||||||
|
pageIconSize: 8
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '5%',
|
||||||
|
right: '5%',
|
||||||
|
top: '12%',
|
||||||
|
bottom: '5%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: [],
|
||||||
|
axisLabel: {
|
||||||
|
rotate: 0,
|
||||||
|
fontSize: 9,
|
||||||
|
interval: 0
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
alignWithLabel: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
name: '任务数量',
|
||||||
|
nameTextStyle: {
|
||||||
|
fontSize: 9
|
||||||
|
},
|
||||||
|
minInterval: 1,
|
||||||
|
axisLabel: {
|
||||||
|
fontSize: 9
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '就绪',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
emphasis: { focus: 'series' },
|
||||||
|
data: [],
|
||||||
|
itemStyle: { color: this.getStatusColor('就绪') },
|
||||||
|
barWidth: '50%',
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '执行中',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
emphasis: { focus: 'series' },
|
||||||
|
data: [],
|
||||||
|
itemStyle: { color: this.getStatusColor('执行中') },
|
||||||
|
barWidth: '50%',
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '完成',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
emphasis: { focus: 'series' },
|
||||||
|
data: [],
|
||||||
|
itemStyle: { color: this.getStatusColor('完成') },
|
||||||
|
barWidth: '50%',
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '取消',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
emphasis: { focus: 'series' },
|
||||||
|
data: [],
|
||||||
|
itemStyle: { color: this.getStatusColor('取消') },
|
||||||
|
barWidth: '50%',
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '强制完成',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
emphasis: { focus: 'series' },
|
||||||
|
data: [],
|
||||||
|
itemStyle: { color: this.getStatusColor('强制完成') },
|
||||||
|
barWidth: '50%',
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '异常',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
emphasis: { focus: 'series' },
|
||||||
|
data: [],
|
||||||
|
itemStyle: { color: this.getStatusColor('异常') },
|
||||||
|
barWidth: '50%',
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.refreshData()
|
||||||
|
this.setTime()
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 确保组件挂载后图表能够正确渲染
|
||||||
|
this.$nextTick(() => {
|
||||||
|
console.log('组件已挂载,重新渲染图表')
|
||||||
|
this.updatePieChart()
|
||||||
|
this.updateBarChart()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setTime() {
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
this.fetchData()
|
||||||
|
}, 30000)
|
||||||
|
},
|
||||||
|
// 刷新数据
|
||||||
|
refreshData() {
|
||||||
|
this.refreshing = true
|
||||||
|
this.fetchData().finally(() => {
|
||||||
|
this.refreshing = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取所有统计数据
|
||||||
|
fetchData() {
|
||||||
|
return Promise.all([
|
||||||
|
this.fetchTodayStats(),
|
||||||
|
this.fetchSevenDaysStats()
|
||||||
|
])
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取当天任务统计
|
||||||
|
fetchTodayStats() {
|
||||||
|
return taskStatsApi.getTodayTaskStats()
|
||||||
|
.then(response => {
|
||||||
|
if (response.code === 200) {
|
||||||
|
this.pieData = response.data
|
||||||
|
this.updatePieChart()
|
||||||
|
this.updateTodayOverview()
|
||||||
|
} else {
|
||||||
|
this.$message.error('获取当天任务统计失败: ' + response.message)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.$message.error('获取当天任务统计失败: ' + error.message)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取近7天任务统计
|
||||||
|
fetchSevenDaysStats() {
|
||||||
|
return taskStatsApi.getSevenDaysTaskStats()
|
||||||
|
.then(response => {
|
||||||
|
if (response.code === 200) {
|
||||||
|
this.barData = response.data
|
||||||
|
console.log('7天数据:', this.barData) // 调试信息
|
||||||
|
this.updateBarChart()
|
||||||
|
} else {
|
||||||
|
this.$message.error('获取近7天任务统计失败: ' + response.message)
|
||||||
|
// 如果没有数据,显示默认数据
|
||||||
|
this.barData = []
|
||||||
|
this.updateBarChart()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('获取7天数据失败:', error)
|
||||||
|
this.$message.error('获取近7天任务统计失败: ' + error.message)
|
||||||
|
// 如果请求失败,显示默认数据
|
||||||
|
this.barData = []
|
||||||
|
this.updateBarChart()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新饼图数据
|
||||||
|
updatePieChart() {
|
||||||
|
console.log('更新饼图数据:', this.pieData)
|
||||||
|
this.pieChartOptions.series[0].data = this.pieData.map(item => ({
|
||||||
|
name: this.formatStatusName(item.status),
|
||||||
|
value: item.count,
|
||||||
|
itemStyle: { color: this.getStatusColor(item.status) }
|
||||||
|
}))
|
||||||
|
console.log('饼图配置:', this.pieChartOptions)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新柱状图数据
|
||||||
|
updateBarChart() {
|
||||||
|
console.log('更新柱状图数据:', this.barData)
|
||||||
|
if (!this.barData || this.barData.length === 0) {
|
||||||
|
// 如果没有数据,显示默认的7天日期
|
||||||
|
const defaultDates = []
|
||||||
|
for (let i = 6; i >= 0; i--) {
|
||||||
|
const date = new Date()
|
||||||
|
date.setDate(date.getDate() - i)
|
||||||
|
defaultDates.push(this.formatDate(date))
|
||||||
|
}
|
||||||
|
this.barChartOptions.xAxis.data = defaultDates
|
||||||
|
|
||||||
|
// 设置默认的空数据
|
||||||
|
this.barChartOptions.series.forEach(series => {
|
||||||
|
series.data = [0, 0, 0, 0, 0, 0, 0]
|
||||||
|
})
|
||||||
|
console.log('柱状图配置(默认数据):', this.barChartOptions)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化日期显示
|
||||||
|
this.barChartOptions.xAxis.data = this.barData.map(item => {
|
||||||
|
if (typeof item.date === 'string') {
|
||||||
|
// 如果是字符串格式,尝试格式化
|
||||||
|
const date = new Date(item.date)
|
||||||
|
if (!isNaN(date.getTime())) {
|
||||||
|
return this.formatDate(date)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return item.date
|
||||||
|
})
|
||||||
|
|
||||||
|
// 提取各类任务数据,确保数据为数字类型
|
||||||
|
this.barChartOptions.series[0].data = this.barData.map(item => parseInt(item.readyCount) || 0)
|
||||||
|
this.barChartOptions.series[1].data = this.barData.map(item => parseInt(item.busyCount) || 0)
|
||||||
|
this.barChartOptions.series[2].data = this.barData.map(item => parseInt(item.finishedCount) || 0)
|
||||||
|
this.barChartOptions.series[3].data = this.barData.map(item => parseInt(item.cancelCount) || 0)
|
||||||
|
this.barChartOptions.series[4].data = this.barData.map(item => parseInt(item.forcedCompletionCount) || 0)
|
||||||
|
this.barChartOptions.series[5].data = this.barData.map(item => parseInt(item.errorCount) || 0)
|
||||||
|
|
||||||
|
console.log('柱状图配置(实际数据):', this.barChartOptions)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新今日概览数据
|
||||||
|
updateTodayOverview() {
|
||||||
|
// 移除统计卡片,设置为空数组
|
||||||
|
this.todayOverview = []
|
||||||
|
|
||||||
|
// 如果没有数据,设置默认的饼图数据
|
||||||
|
if (!this.pieData || this.pieData.length === 0) {
|
||||||
|
this.pieChartOptions.series[0].data = [
|
||||||
|
{ name: '已完成', value: 0, itemStyle: { color: this.getStatusColor('完成') }},
|
||||||
|
{ name: '进行中', value: 0, itemStyle: { color: this.getStatusColor('执行中') }},
|
||||||
|
{ name: '待处理', value: 0, itemStyle: { color: this.getStatusColor('就绪') }}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 格式化状态名称(英文转中文)
|
||||||
|
formatStatusName(status) {
|
||||||
|
const statusMap = {
|
||||||
|
'COMPLETED': '已完成',
|
||||||
|
'IN_PROGRESS': '进行中',
|
||||||
|
'PENDING': '待处理',
|
||||||
|
'FAILED': '失败'
|
||||||
|
}
|
||||||
|
return statusMap[status] || status
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取状态对应的颜色
|
||||||
|
getStatusColor(status) {
|
||||||
|
const colorMap = {
|
||||||
|
'就绪': '#0d2fda',
|
||||||
|
'执行中': '#faad14',
|
||||||
|
'完成': '#41ff00',
|
||||||
|
'取消': '#971112',
|
||||||
|
'强制完成': '#339e0f',
|
||||||
|
'异常': '#ff0000'
|
||||||
|
}
|
||||||
|
return colorMap[status] || '#8c8c8c'
|
||||||
|
},
|
||||||
|
|
||||||
|
// 格式化日期显示
|
||||||
|
formatDate(date) {
|
||||||
|
const month = (date.getMonth() + 1).toString().padStart(2, '0')
|
||||||
|
const day = date.getDate().toString().padStart(2, '0')
|
||||||
|
return `${month}-${day}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.task-stats-container {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-card {
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: 35px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header h2 {
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-overview {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
padding: 15px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-desc {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.charts-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-card {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 200px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-wrapper .echarts {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
min-height: 200px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式设计 */
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.task-stats-container {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.stats-overview {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-wrapper {
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.stats-overview {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
226
acs2/nladmin-ui/src/views/dashboard/showTrack/index.vue
Normal file
226
acs2/nladmin-ui/src/views/dashboard/showTrack/index.vue
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="canvas-wrap" :style="getBgStyle(configInfo)">
|
||||||
|
<div v-for="e in carData" :key="e.device_code" class="car-wrap" :style="getCarWrapStyle(e)">
|
||||||
|
<div class="car_img" :style="getCarImgStyle(e)" />
|
||||||
|
<div class="car_name">{{ e.configuration_code }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 缩放指示器 -->
|
||||||
|
<div class="zoom-indicator">
|
||||||
|
<span>{{ Math.round(scale * 100) }}%</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import apiTrack from '@/views/dashboard/showTrack/track'
|
||||||
|
// const fullDomain = window.location.protocol + '//' + window.location.host
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
configInfo: { refresh_time: 1000 },
|
||||||
|
carData: [],
|
||||||
|
deviceData: [],
|
||||||
|
carCoor: [],
|
||||||
|
scale: 1, // 缩放比例
|
||||||
|
minScale: 0.5, // 最小缩放比例
|
||||||
|
maxScale: 3 // 最大缩放比例
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters([
|
||||||
|
'baseApi'
|
||||||
|
])
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
const res1 = await apiTrack.trackEdit()
|
||||||
|
this.configInfo = [...res1.content][0]
|
||||||
|
const res2 = await apiTrack.carEdit()
|
||||||
|
this.carData = [...res2.content]
|
||||||
|
this.deviceData = this.carData.map(e => { return { device_code: e.device_code } })
|
||||||
|
this._queryDevice(this.deviceData)
|
||||||
|
this.timerFun(this._queryDevice, this.configInfo.refresh_time * 1000)()
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 添加鼠标滚轮事件监听
|
||||||
|
this.$el.addEventListener('wheel', this.handleWheel, { passive: false })
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
// 移除事件监听
|
||||||
|
this.$el.removeEventListener('wheel', this.handleWheel)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
timerFun(f, time) {
|
||||||
|
const _this = this
|
||||||
|
return function backFun() {
|
||||||
|
clearTimeout(_this.intervalId)
|
||||||
|
_this.intervalId = setTimeout(function() {
|
||||||
|
f(_this.deviceData)
|
||||||
|
backFun()
|
||||||
|
}, time)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_queryDevice(arr) {
|
||||||
|
apiTrack.queryDevice(arr).then(res => {
|
||||||
|
this.carCoor = [...res.data]
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getBgStyle(obj) {
|
||||||
|
if (obj.image_code) {
|
||||||
|
const width = this.$el.offsetWidth * obj.zoom_ratio
|
||||||
|
const height = parseFloat(obj.max_y) * (this.$el.offsetWidth / this.$el.offsetWidth) * obj.zoom_ratio
|
||||||
|
// const fullImageUrl = require('@/assets/images/agvBackground.jpg')
|
||||||
|
const fullImageUrl = `${this.baseApi}/file/图片/${obj.image_code}`
|
||||||
|
return {
|
||||||
|
width: `${width}px`,
|
||||||
|
height: `${height}px`,
|
||||||
|
backgroundImage: `url(${fullImageUrl})`,
|
||||||
|
backgroundSize: '100% 100%',
|
||||||
|
backgroundRepeat: 'no-repeat',
|
||||||
|
backgroundPosition: 'center',
|
||||||
|
transform: `scale(${this.scale})`,
|
||||||
|
transformOrigin: 'center center'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getPositionById(code) {
|
||||||
|
const position = this.carCoor.find((p) => p.device_code === code)
|
||||||
|
return position || { x: 0, y: 0 }
|
||||||
|
},
|
||||||
|
getCarWrapStyle(el) {
|
||||||
|
const width = el.image_width
|
||||||
|
const height = el.image_height
|
||||||
|
const position = this.getPositionById(el.device_code)
|
||||||
|
|
||||||
|
// 计算缩放比例,保持小车位置相对正确
|
||||||
|
// 由于背景图片现在是100%宽度,需要调整小车位置的比例
|
||||||
|
const scaleRatio = 1 // 保持原始比例,小车位置基于原始坐标系统
|
||||||
|
|
||||||
|
const x = (position.x * parseFloat(this.configInfo.zoom_ratio) * scaleRatio * this.$el.offsetWidth / this.configInfo.max_x)
|
||||||
|
const y = position.y * parseFloat(this.configInfo.zoom_ratio) * scaleRatio
|
||||||
|
let sty = {}
|
||||||
|
switch (this.configInfo.coordinate_origin) {
|
||||||
|
case '1':
|
||||||
|
sty = {
|
||||||
|
width: `${width * this.scale}px`,
|
||||||
|
height: `${height * this.scale}px`,
|
||||||
|
left: `${x}px`,
|
||||||
|
top: `${y}px`
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case '2':
|
||||||
|
sty = {
|
||||||
|
width: `${width * this.scale}px`,
|
||||||
|
height: `${height * this.scale}px`,
|
||||||
|
left: `${x}px`,
|
||||||
|
bottom: `${y}px`
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case '3 ':
|
||||||
|
sty = {
|
||||||
|
width: `${width * this.scale}px`,
|
||||||
|
height: `${height * this.scale}px`,
|
||||||
|
right: `${x}px`,
|
||||||
|
top: `${y}px`
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case '4':
|
||||||
|
sty = {
|
||||||
|
width: `${width * this.scale}px`,
|
||||||
|
height: `${height * this.scale}px`,
|
||||||
|
right: `${x}px`,
|
||||||
|
bottom: `${y}px`
|
||||||
|
}
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
sty = {}
|
||||||
|
}
|
||||||
|
return sty
|
||||||
|
},
|
||||||
|
getCarImgStyle(el) {
|
||||||
|
// const fullImageUrl = require('@/assets/images/agvCar.png')
|
||||||
|
const fullImageUrl = `${this.baseApi}/file/图片/${el.image_code}`
|
||||||
|
const position = this.getPositionById(el.device_code)
|
||||||
|
const angle = parseFloat(position.angle)
|
||||||
|
return {
|
||||||
|
backgroundImage: `url(${fullImageUrl})`,
|
||||||
|
transform: `rotate(-${angle}deg)`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理鼠标滚轮事件
|
||||||
|
handleWheel(event) {
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
const delta = event.deltaY > 0 ? -0.1 : 0.1
|
||||||
|
const newScale = Math.max(this.minScale, Math.min(this.maxScale, this.scale + delta))
|
||||||
|
|
||||||
|
if (newScale !== this.scale) {
|
||||||
|
this.scale = newScale
|
||||||
|
// 强制更新视图
|
||||||
|
this.$forceUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
overflow: auto;
|
||||||
|
scrollbar-width: none;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.container::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.canvas-wrap {
|
||||||
|
position: relative;
|
||||||
|
background: #f3f3f3 top center / 100% auto no-repeat;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
transition: transform 0.1s ease-out;
|
||||||
|
}
|
||||||
|
.car-wrap {
|
||||||
|
position: absolute;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
.car_img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: top center / 100% auto no-repeat;
|
||||||
|
}
|
||||||
|
.car_name {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
bottom: -20px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zoom-indicator {
|
||||||
|
position: absolute;
|
||||||
|
top: 104px;
|
||||||
|
right: 21px;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
color: white;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
87
acs2/nladmin-ui/src/views/dashboard/showTrack/track.js
Normal file
87
acs2/nladmin-ui/src/views/dashboard/showTrack/track.js
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function trackEdit(data) {
|
||||||
|
return request({
|
||||||
|
url: 'api/trajectoryBackground/queryAllEnable',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function carEdit(data) {
|
||||||
|
return request({
|
||||||
|
url: 'api/trajectoryConfiguration/queryAllEnable',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function queryDevice(data) {
|
||||||
|
return request({
|
||||||
|
url: 'api/trajectory/queryDevice',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// export function trackEdit() {
|
||||||
|
// const res = {
|
||||||
|
// code: 200,
|
||||||
|
// msg: 'ok',
|
||||||
|
// content: [{
|
||||||
|
// background_code: '图片',
|
||||||
|
// image_code: 'aaa.jpg',
|
||||||
|
// zoom_ratio: '0.5',
|
||||||
|
// coordinate_origin: '4',
|
||||||
|
// max_x: '1000',
|
||||||
|
// max_y: '1000',
|
||||||
|
// refresh_time: 10000
|
||||||
|
// }]
|
||||||
|
// }
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// resolve(res)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function carEdit() {
|
||||||
|
// const res = {
|
||||||
|
// code: 200,
|
||||||
|
// msg: 'ok',
|
||||||
|
// content: [{
|
||||||
|
// configuration_code: '1号agv',
|
||||||
|
// image_code: 'aaa.jpg',
|
||||||
|
// image_width: '20',
|
||||||
|
// image_height: '20',
|
||||||
|
// device_code: '1',
|
||||||
|
// x: 100,
|
||||||
|
// y: 100,
|
||||||
|
// angle: 90
|
||||||
|
// }, {
|
||||||
|
// configuration_code: '2号agv',
|
||||||
|
// image_code: 'aaa.jpg',
|
||||||
|
// image_width: '20',
|
||||||
|
// image_height: '20',
|
||||||
|
// device_code: '2',
|
||||||
|
// x: 200,
|
||||||
|
// y: 200,
|
||||||
|
// angle: 0
|
||||||
|
// }]
|
||||||
|
// }
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// resolve(res)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function queryDevice() {
|
||||||
|
// const res = {
|
||||||
|
// data: [{ device_code: '1', x: Math.floor(Math.random() * 10) * 100, y: Math.floor(Math.random() * 10) * 100, angle: 90 }, { device_code: '2', x: Math.floor(Math.random() * 10) * 100, y: Math.floor(Math.random() * 10) * 100, angle: 0 }],
|
||||||
|
// data1: [{ device_code: '1', x: 100, y: 100, angle: 90 }, { device_code: '2', x: 200, y: 200, angle: 0 }],
|
||||||
|
// status: '200',
|
||||||
|
// message: '操作成功'
|
||||||
|
// }
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// resolve(res)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
export default { trackEdit, carEdit, queryDevice }
|
||||||
@@ -0,0 +1,270 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!--工具栏-->
|
||||||
|
<div class="head-container">
|
||||||
|
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||||
|
<!-- <div v-if="crud.props.searchToggle">-->
|
||||||
|
<!-- <!– 搜索 –>-->
|
||||||
|
<!-- <el-select-->
|
||||||
|
<!-- v-model="query.device_type"-->
|
||||||
|
<!-- class="filter-item"-->
|
||||||
|
<!-- clearable-->
|
||||||
|
<!-- placeholder="设备类型"-->
|
||||||
|
<!-- size="small"-->
|
||||||
|
<!-- style="width: 450px"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <el-option v-for="item in device_types" :key="item.id" :label="item.label" :value="item.value" />-->
|
||||||
|
<!-- </el-select>-->
|
||||||
|
<!-- <rrOperation />-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<crudOperation :permission="permission" />
|
||||||
|
<!--表单组件-->
|
||||||
|
<el-dialog
|
||||||
|
:before-close="crud.cancelCU"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:title="crud.status.title"
|
||||||
|
:visible.sync="crud.status.cu > 0"
|
||||||
|
width="500px"
|
||||||
|
>
|
||||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px" size="small">
|
||||||
|
<el-form-item label="图片上传" prop="image_code">
|
||||||
|
<el-upload
|
||||||
|
:action="imagesUploadApi"
|
||||||
|
:before-upload="beforeUpload_u"
|
||||||
|
:file-list="fileList"
|
||||||
|
:headers="headers"
|
||||||
|
:limit="1"
|
||||||
|
list-type="picture"
|
||||||
|
:on-success="handleSuccess"
|
||||||
|
class="upload-demo"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<el-button size="small" type="primary">点击上传</el-button>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="图标高度" prop="image_height">
|
||||||
|
<el-input v-model="form.image_height" style="width: 370px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="图标宽度" prop="image_width">
|
||||||
|
<el-input v-model="form.image_width" style="width: 370px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="配置名称" prop="configuration_code">
|
||||||
|
<el-input v-model="form.configuration_code" style="width: 370px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="绑定设备" prop="device_code">
|
||||||
|
<el-select v-model="form.device_code" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in options"
|
||||||
|
:key="item.device_code"
|
||||||
|
:label="item.device_name"
|
||||||
|
:value="item.device_code"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否启用">
|
||||||
|
<el-switch
|
||||||
|
v-model="form.is_active"
|
||||||
|
active-value="1"
|
||||||
|
inactive-value="0"
|
||||||
|
active-color="#13ce66"
|
||||||
|
inactive-color="#ff4949"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="text" @click="crud.cancelCU">取消</el-button>
|
||||||
|
<el-button :loading="crud.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
<!--表格渲染-->
|
||||||
|
<el-table
|
||||||
|
ref="table"
|
||||||
|
v-loading="crud.loading"
|
||||||
|
:data="crud.data"
|
||||||
|
size="small"
|
||||||
|
style="width: 100%;"
|
||||||
|
@selection-change="crud.selectionChangeHandler"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" />
|
||||||
|
<el-table-column label="图标" prop="image_name">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-image
|
||||||
|
:preview-src-list="[baseApi + '/file/图片/' + row.image_code]"
|
||||||
|
:src=" baseApi + '/file/图片/' + row.image_code"
|
||||||
|
class="el-avatar"
|
||||||
|
fit="contain"
|
||||||
|
lazy
|
||||||
|
>
|
||||||
|
<div slot="error">
|
||||||
|
<i class="el-icon-document" />
|
||||||
|
</div>
|
||||||
|
</el-image>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="配置名称" prop="configuration_code" />
|
||||||
|
<el-table-column label="图标编号" prop="image_code" />
|
||||||
|
<el-table-column label="图标高度" prop="image_height" />
|
||||||
|
<el-table-column label="图标宽度" prop="image_width" />
|
||||||
|
<el-table-column label="绑定设备编号" prop="device_code" />
|
||||||
|
<el-table-column label="是否启用" prop="is_active">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<span v-if="row.is_active === '1'"><el-tag type="success">启用</el-tag></span>
|
||||||
|
<span v-else><el-tag type="warning">未启用</el-tag></span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="create_name" label="创建人" />
|
||||||
|
<el-table-column prop="create_time" label="创建时间" min-width="135" />
|
||||||
|
<el-table-column
|
||||||
|
v-permission="['admin','stageImage:edit','stageImage:del']"
|
||||||
|
align="center"
|
||||||
|
label="操作"
|
||||||
|
width="150px"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<udOperation
|
||||||
|
:data="scope.row"
|
||||||
|
:permission="permission"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!--分页组件-->
|
||||||
|
<pagination />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CRUD, { crud, form, header, presenter } from '@crud/crud'
|
||||||
|
import crudOperation from '@crud/CRUD.operation'
|
||||||
|
import udOperation from '@crud/UD.operation'
|
||||||
|
import pagination from '@crud/Pagination'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
import { selectDeviceList } from '@/api/acs/device/device'
|
||||||
|
import crudTrajectoryConfiguration from '@/api/trajectory/configuration/trajectory_configuration'
|
||||||
|
|
||||||
|
const defaultForm = {
|
||||||
|
configuration_uuid: null,
|
||||||
|
configuration_code: null,
|
||||||
|
image_code: null,
|
||||||
|
image_name: null,
|
||||||
|
image_height: null,
|
||||||
|
image_width: null,
|
||||||
|
device_code: null,
|
||||||
|
is_active: '1',
|
||||||
|
is_delete: null,
|
||||||
|
create_by: null,
|
||||||
|
create_time: null,
|
||||||
|
update_by: null,
|
||||||
|
update_time: null
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: 'TrajectoryConfiguration',
|
||||||
|
components: { pagination, crudOperation, udOperation },
|
||||||
|
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||||
|
cruds() {
|
||||||
|
return CRUD({
|
||||||
|
title: '设备配置',
|
||||||
|
url: 'api/trajectoryConfiguration',
|
||||||
|
idField: 'configuration_uuid',
|
||||||
|
sort: 'configuration_uuid,desc',
|
||||||
|
crudMethod: { ...crudTrajectoryConfiguration },
|
||||||
|
optShow: {
|
||||||
|
add: true,
|
||||||
|
edit: true,
|
||||||
|
del: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
value: [],
|
||||||
|
permission: {
|
||||||
|
add: ['admin', 'TrajectoryConfiguration:add'],
|
||||||
|
edit: ['admin', 'TrajectoryConfiguration:edit'],
|
||||||
|
del: ['admin', 'TrajectoryConfiguration:del']
|
||||||
|
},
|
||||||
|
headers: { 'Authorization': getToken() },
|
||||||
|
rules: {
|
||||||
|
configuration_code: [
|
||||||
|
{ required: true, message: '配置名称不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
image_code: [
|
||||||
|
{ required: true, message: '图标编号不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
image_name: [
|
||||||
|
{ required: true, message: '图标名称不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
image_height: [
|
||||||
|
{ required: true, message: '图标高度不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
image_width: [
|
||||||
|
{ required: true, message: '图标宽度不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
device_code: [
|
||||||
|
{ required: true, message: '绑定设备不能为空', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
fileList: [],
|
||||||
|
options: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters([
|
||||||
|
'imagesUploadApi',
|
||||||
|
'baseApi'
|
||||||
|
])
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 获取所有设备
|
||||||
|
selectDeviceList().then(data => {
|
||||||
|
console.log(data)
|
||||||
|
this.options = data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 钩子:在获取表格数据之前执行,false 则代表不获取数据
|
||||||
|
[CRUD.HOOK.beforeRefresh]() {
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
[CRUD.HOOK.afterSubmit]() {
|
||||||
|
this.fileList = []
|
||||||
|
}, [CRUD.HOOK.beforeToAdd]() {
|
||||||
|
this.fileList = []
|
||||||
|
},
|
||||||
|
[CRUD.HOOK.afterToEdit]() {
|
||||||
|
let new_lst = []
|
||||||
|
const image_code = this.form.image_code
|
||||||
|
const image_name = this.baseApi + '/file/图片/' + image_code
|
||||||
|
new_lst = [{ name: image_code, url: image_name }]
|
||||||
|
this.fileList = new_lst
|
||||||
|
},
|
||||||
|
beforeUpload_u(file) {
|
||||||
|
const testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
|
||||||
|
const extension = (testmsg === 'png' || testmsg === 'jpg' || testmsg === 'svg')
|
||||||
|
|
||||||
|
let bool = false
|
||||||
|
if (extension) {
|
||||||
|
bool = true
|
||||||
|
} else {
|
||||||
|
bool = false
|
||||||
|
}
|
||||||
|
if (!extension) {
|
||||||
|
this.$confirm(`上传文件只能是png/jpg/svg格式!`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return bool
|
||||||
|
},
|
||||||
|
handleSuccess(response) {
|
||||||
|
console.log(response)
|
||||||
|
this.form.image_code = response.real_name
|
||||||
|
this.form.image_name = response.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
270
acs2/nladmin-ui/src/views/system/trajectory/index.vue
Normal file
270
acs2/nladmin-ui/src/views/system/trajectory/index.vue
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!--工具栏-->
|
||||||
|
<div class="head-container">
|
||||||
|
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||||
|
<crudOperation :permission="permission" />
|
||||||
|
<!--表单组件-->
|
||||||
|
<el-dialog
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:before-close="crud.cancelCU"
|
||||||
|
:visible.sync="crud.status.cu > 0"
|
||||||
|
:title="crud.status.title"
|
||||||
|
width="500px"
|
||||||
|
>
|
||||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px" size="small">
|
||||||
|
<el-form-item label="图片上传" prop="image_code">
|
||||||
|
<el-upload
|
||||||
|
:action="imagesUploadApi"
|
||||||
|
:before-upload="beforeUpload_u"
|
||||||
|
:file-list="fileList"
|
||||||
|
:headers="headers"
|
||||||
|
:limit="1"
|
||||||
|
list-type="picture"
|
||||||
|
:on-success="handleSuccess"
|
||||||
|
class="upload-demo"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<el-button size="small" type="primary">点击上传</el-button>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="背景图名称" prop="background_code">
|
||||||
|
<el-input v-model="form.background_code" style="width: 370px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="缩放比例" prop="zoom_ratio">
|
||||||
|
<el-input v-model="form.zoom_ratio" style="width: 370px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="坐标原点" prop="coordinate_origin">
|
||||||
|
<el-select v-model="form.coordinate_origin" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in options"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="X坐标最大值" prop="max_x">
|
||||||
|
<el-input v-model="form.max_x" style="width: 370px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Y坐标最大值" prop="max_y">
|
||||||
|
<el-input v-model="form.max_y" style="width: 370px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="刷新时间(秒)" prop="refresh_time">
|
||||||
|
<el-input v-model="form.refresh_time" style="width: 370px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="图片描述" prop="remark">
|
||||||
|
<el-input v-model="form.remark" style="width: 370px;" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="text" @click="crud.cancelCU">{{ $t('auto.common.Cancel') }}</el-button>
|
||||||
|
<el-button :loading="crud.cu === 2" type="primary" @click="crud.submitCU">{{ $t('auto.common.Confirm') }}</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
<!--表格渲染-->
|
||||||
|
<el-table
|
||||||
|
ref="table"
|
||||||
|
v-loading="crud.loading"
|
||||||
|
:data="crud.data"
|
||||||
|
size="small"
|
||||||
|
style="width: 100%;"
|
||||||
|
@selection-change="crud.selectionChangeHandler"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" />
|
||||||
|
<el-table-column label="背景图" prop="image_name">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-image
|
||||||
|
:preview-src-list="[baseApi + '/file/图片/' + row.image_code]"
|
||||||
|
:src=" baseApi + '/file/图片/' + row.image_code"
|
||||||
|
class="el-avatar"
|
||||||
|
fit="contain"
|
||||||
|
lazy
|
||||||
|
>
|
||||||
|
<div slot="error">
|
||||||
|
<i class="el-icon-document" />
|
||||||
|
</div>
|
||||||
|
</el-image>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="background_code" label="背景图名称" />
|
||||||
|
<el-table-column prop="image_code" label="背景图片编码" />
|
||||||
|
<el-table-column prop="image_name" label="背景图片地址" />
|
||||||
|
<el-table-column prop="zoom_ratio" label="缩放比例" />
|
||||||
|
<el-table-column prop="coordinate_origin" label="坐标原点">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<span v-if="options.length!==0">{{ getCoordinateOrigin(row.coordinate_origin) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="max_x" label="X坐标最大值" />
|
||||||
|
<el-table-column prop="max_y" label="Y坐标最大值" />
|
||||||
|
<el-table-column prop="refresh_time" label="刷新时间(秒)" />
|
||||||
|
<el-table-column label="是否启用" prop="is_active">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<span v-if="row.is_active === '1'"><el-tag type="success">启用</el-tag></span>
|
||||||
|
<span v-else><el-tag type="warning">未启用</el-tag></span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="create_name" label="创建人" />
|
||||||
|
<el-table-column prop="create_time" label="创建时间" min-width="135" />
|
||||||
|
<el-table-column label="备注" prop="remark" />
|
||||||
|
<el-table-column v-permission="['admin','stage:edit','stage:del']" :label="$t('task.select.Operation')" width="150px" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<udOperation
|
||||||
|
:data="scope.row"
|
||||||
|
:permission="permission"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!--分页组件-->
|
||||||
|
<pagination />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import crudTrajectory from '@/api/trajectory/trajectory_background'
|
||||||
|
import { get } from '@/views/system/dict/dictDetail'
|
||||||
|
|
||||||
|
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||||
|
import crudOperation from '@crud/CRUD.operation'
|
||||||
|
import udOperation from '@crud/UD.operation'
|
||||||
|
import pagination from '@crud/Pagination'
|
||||||
|
// import i18n from '@/i18n'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
|
||||||
|
const defaultForm = {
|
||||||
|
background_uuid: null,
|
||||||
|
background_code: null,
|
||||||
|
image_code: null,
|
||||||
|
image_name: null,
|
||||||
|
zoom_ratio: null,
|
||||||
|
coordinate_origin: null,
|
||||||
|
max_x: null,
|
||||||
|
max_y: null,
|
||||||
|
refresh_time: null,
|
||||||
|
is_active: null,
|
||||||
|
is_delete: null,
|
||||||
|
create_by: null,
|
||||||
|
create_time: null,
|
||||||
|
update_by: null,
|
||||||
|
update_time: null,
|
||||||
|
remark: null
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: 'Trajectory',
|
||||||
|
components: { pagination, crudOperation, udOperation },
|
||||||
|
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||||
|
cruds() {
|
||||||
|
return CRUD({
|
||||||
|
title: '轨迹背景图',
|
||||||
|
url: 'api/trajectoryBackground',
|
||||||
|
idField: 'background_uuid',
|
||||||
|
sort: 'background_uuid,desc',
|
||||||
|
crudMethod: { ...crudTrajectory },
|
||||||
|
optShow: {
|
||||||
|
add: true,
|
||||||
|
edit: true,
|
||||||
|
del: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
permission: {
|
||||||
|
add: ['admin', 'Trajectory:add'],
|
||||||
|
edit: ['admin', 'Trajectory:edit'],
|
||||||
|
del: ['admin', 'Trajectory:del']
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
background_code: [
|
||||||
|
{ required: true, message: '背景图名称不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
image_code: [
|
||||||
|
{ required: true, message: '背景图不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
zoom_ratio: [
|
||||||
|
{ required: true, message: '缩放比例不能为空,范围0-1', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
coordinate_origin: [
|
||||||
|
{ required: true, message: '坐标原点不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
max_x: [
|
||||||
|
{ required: true, message: 'X坐标最大值不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
max_y: [
|
||||||
|
{ required: true, message: 'Y坐标最大值不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
refresh_time: [
|
||||||
|
{ required: true, message: '刷新时间不能为空', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
fileList: [],
|
||||||
|
headers: { 'Authorization': getToken() },
|
||||||
|
options: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 获取坐标原点字典
|
||||||
|
get('coordinate_origin').then(data => {
|
||||||
|
console.log(data)
|
||||||
|
this.options = data.content
|
||||||
|
})
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters([
|
||||||
|
'imagesUploadApi',
|
||||||
|
'baseApi'
|
||||||
|
])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 钩子:在获取表格数据之前执行,false 则代表不获取数据
|
||||||
|
[CRUD.HOOK.beforeRefresh]() {
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
[CRUD.HOOK.afterSubmit]() {
|
||||||
|
this.fileList = []
|
||||||
|
}, [CRUD.HOOK.beforeToAdd]() {
|
||||||
|
this.fileList = []
|
||||||
|
},
|
||||||
|
[CRUD.HOOK.afterToEdit]() {
|
||||||
|
let new_lst = []
|
||||||
|
const image_code = this.form.image_code
|
||||||
|
const image_name = this.baseApi + '/file/图片/' + image_code
|
||||||
|
new_lst = [{ name: image_code, url: image_name }]
|
||||||
|
this.fileList = new_lst
|
||||||
|
},
|
||||||
|
beforeUpload_u(file) {
|
||||||
|
const testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
|
||||||
|
const extension = (testmsg === 'png' || testmsg === 'jpg' || testmsg === 'svg')
|
||||||
|
|
||||||
|
let bool = false
|
||||||
|
if (extension) {
|
||||||
|
bool = true
|
||||||
|
} else {
|
||||||
|
bool = false
|
||||||
|
}
|
||||||
|
if (!extension) {
|
||||||
|
this.$confirm(`上传文件只能是png/jpg/svg格式!`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return bool
|
||||||
|
},
|
||||||
|
handleSuccess(response) {
|
||||||
|
console.log(response)
|
||||||
|
this.form.image_code = response.real_name
|
||||||
|
this.form.image_name = response.path
|
||||||
|
},
|
||||||
|
getCoordinateOrigin(value) {
|
||||||
|
const item = this.options.find(item => item.value === value)
|
||||||
|
return item ? item.label : ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user