Selaa lähdekoodia

Merge remote-tracking branch 'origin/master'

Rmengdi 5 kuukautta sitten
vanhempi
sitoutus
e4284894d6
22 muutettua tiedostoa jossa 2259 lisäystä ja 284 poistoa
  1. 45 0
      sql/update20250415.sql
  2. 1 1
      uavps-admin/src/main/resources/application.yml
  3. 6 0
      uavps-common/src/main/java/com/uavps/common/config/RuoYiConfig.java
  4. 14 0
      uavps-framework/src/main/java/com/uavps/framework/FileUtils.java
  5. 0 78
      uavps-framework/src/main/java/com/uavps/framework/udp/CoordinateSystem.java
  6. 199 0
      uavps-framework/src/main/java/com/uavps/framework/udp/TaskInfo.java
  7. 47 10
      uavps-framework/src/main/java/com/uavps/framework/udp/UdpClientService.java
  8. 34 98
      uavps-framework/src/main/java/com/uavps/framework/udp/UdpServerService.java
  9. 0 55
      uavps-framework/src/main/java/com/uavps/framework/udp/UdpUtils.java
  10. 93 0
      uavps-framework/src/main/java/com/uavps/framework/utils/UdpUtils.java
  11. 137 42
      uavps-framework/src/main/java/com/uavps/framework/websocket/WebSocketServer.java
  12. 104 0
      uavps-system/src/main/java/com/uavps/system/controller/UavpsTaskController.java
  13. 352 0
      uavps-system/src/main/java/com/uavps/system/domain/UavpsTask.java
  14. 87 0
      uavps-system/src/main/java/com/uavps/system/domain/dto/CustomizedMultiTargetFormationDTO.java
  15. 112 0
      uavps-system/src/main/java/com/uavps/system/domain/dto/FixedMultiTargetFormationDTO.java
  16. 72 0
      uavps-system/src/main/java/com/uavps/system/domain/dto/PlatformUavDTO.java
  17. 61 0
      uavps-system/src/main/java/com/uavps/system/mapper/UavpsTaskMapper.java
  18. 61 0
      uavps-system/src/main/java/com/uavps/system/service/IUavpsTaskService.java
  19. 96 0
      uavps-system/src/main/java/com/uavps/system/service/impl/UavpsTaskServiceImpl.java
  20. 124 0
      uavps-system/src/main/resources/mapper/system/UavpsTaskMapper.xml
  21. 44 0
      uavps-web/src/api/system/task.js
  22. 570 0
      uavps-web/src/views/system/task/index.vue

+ 45 - 0
sql/update20250415.sql

@@ -0,0 +1,45 @@
+DROP TABLE IF EXISTS `uavps_task`;
+CREATE TABLE `uavps_task`  (
+  `biz_id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '业务ID',
+  `biz_name` varchar(127) COMMENT '任务名称',
+  `biz_type` varchar(7) COMMENT '业务类型(start:开始,change:队形转换,disappear:消失出现)',
+  `multi_target` varchar(7) COMMENT '多目标类型',
+  `noise_type` varchar(127) COMMENT '噪声类型',
+  `noise_variance` DECIMAL(10,6) COMMENT '噪声方差',
+  `noise_mean` DECIMAL(12,6) COMMENT '噪声均值',
+  `platform_uav_str` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '固定翼平台无人机数据',
+  `fixed_multi_target_formation_str` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '固定编队目标数据',
+  `customized_multi_target_formation_str` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '自定义编队目标数据',
+  `status` varchar(7) COMMENT '状态',
+  `start_time` datetime(0) NULL DEFAULT NULL COMMENT '开始时间',
+  `end_time` datetime(0) NULL DEFAULT NULL COMMENT '结束时间',
+  `file_path` varchar(127) COMMENT '噪声数据文件路径',
+  `create_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人',
+  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人',
+  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`biz_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '任务数据表' ROW_FORMAT = Dynamic;
+
+-- 菜单 SQL
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('任务数据', '3', '1', 'task', 'system/task/index', 1, 0, 'C', '0', '0', 'system:task:list', '#', 'admin', sysdate(), '', null, '任务数据菜单');
+
+-- 按钮父菜单ID
+SELECT @parentId := LAST_INSERT_ID();
+
+-- 按钮 SQL
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('任务数据查询', @parentId, '1',  '#', '', 1, 0, 'F', '0', '0', 'system:task:query',        '#', 'admin', sysdate(), '', null, '');
+
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('任务数据新增', @parentId, '2',  '#', '', 1, 0, 'F', '0', '0', 'system:task:add',          '#', 'admin', sysdate(), '', null, '');
+
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('任务数据修改', @parentId, '3',  '#', '', 1, 0, 'F', '0', '0', 'system:task:edit',         '#', 'admin', sysdate(), '', null, '');
+
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('任务数据删除', @parentId, '4',  '#', '', 1, 0, 'F', '0', '0', 'system:task:remove',       '#', 'admin', sysdate(), '', null, '');
+
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('任务数据导出', @parentId, '5',  '#', '', 1, 0, 'F', '0', '0', 'system:task:export',       '#', 'admin', sysdate(), '', null, '');

+ 1 - 1
uavps-admin/src/main/resources/application.yml

@@ -7,7 +7,7 @@ ruoyi:
   # 版权年份
   copyrightYear: 2024
   # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
-  profile: D:/ruoyi/uploadPath
+  profile: D:/UavPs/uploadPath
   # 获取ip地址开关
   addressEnabled: false
   # 验证码类型 math 数字计算 char 字符验证

+ 6 - 0
uavps-common/src/main/java/com/uavps/common/config/RuoYiConfig.java

@@ -116,4 +116,10 @@ public class RuoYiConfig {
     public static String getUploadPath() {
         return getProfile() + "/upload";
     }
+    /**
+     * 获取上传路径
+     */
+    public static String getTaskPath() {
+        return getProfile() + "/task";
+    }
 }

+ 14 - 0
uavps-framework/src/main/java/com/uavps/framework/FileUtils.java

@@ -0,0 +1,14 @@
+package com.uavps.framework;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class FileUtils {
+    public static void addFileAndSave(String path, String message){
+
+    }
+    public static void addFileAndSave(FileOutputStream fos, byte[] message) throws IOException {
+        fos.write(message);
+        fos.flush();
+    }
+}

+ 0 - 78
uavps-framework/src/main/java/com/uavps/framework/udp/CoordinateSystem.java

@@ -1,78 +0,0 @@
-package com.uavps.framework.udp;
-
-public enum CoordinateSystem {
-    // 枚举实例,包含初始化坐标和转化比率
-    INSTANCE(0.0f, 0.0f, true, 1.0f);
-
-    // 枚举字段
-    private float x;
-    private float y;
-    private boolean initFlag;
-    private float conversionRate;
-    private final int initCenterPixel = 500;
-
-    // 枚举构造函数
-    private CoordinateSystem(float x, float y, boolean initFlag, float conversionRate) {
-        this.x = x;
-        this.y = y;
-        this.initFlag = initFlag;
-        this.conversionRate = conversionRate;
-    }
-
-    // 重置方法
-    public void reset() {
-        // 初始化
-        this.x = 0f;
-        this.y = 0f;
-        this.initFlag = true;
-        this.conversionRate = 0.00001f;
-    }
-
-    // Getter和Setter方法
-    public float getX() {
-        return x;
-    }
-
-    public void setX(float x) {
-        this.x = x;
-    }
-
-    public float getY() {
-        return y;
-    }
-
-    public void setY(float y) {
-        this.y = y;
-    }
-
-    public boolean getInitFlag() {
-        return initFlag;
-    }
-
-    public void setInitFlag(boolean initFlag) {
-        this.initFlag = initFlag;
-    }
-
-    public float getConversionRate() {
-        return conversionRate;
-    }
-
-    public void setConversionRate(float conversionRate) {
-        this.conversionRate = conversionRate;
-    }
-
-    // 转换坐标方法
-    public float convertValue(float value) {
-        return value * conversionRate;
-    }
-
-    public float getConversionCenterPixel() {
-        return initCenterPixel * conversionRate;
-    }
-
-    // 显示坐标信息
-    public void displayCoordinates() {
-        System.out.printf("%s 坐标系 - X: %.2f, Y: %.2f (初始化标识: %s, 转化比率: %.6f)%n",
-                this.name(), x, y, initFlag, conversionRate);
-    }
-}

+ 199 - 0
uavps-framework/src/main/java/com/uavps/framework/udp/TaskInfo.java

@@ -0,0 +1,199 @@
+package com.uavps.framework.udp;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public enum TaskInfo {
+    // 枚举实例,包含初始化坐标和转化比率
+    INSTANCE(0.0f, 0.0f, true, 1.0f);
+
+    // 枚举字段
+    private float x;
+    private float y;
+    private boolean initFlag;
+    private float conversionRate;
+    private final int initCenterPixel = 500;
+    private Long bizId;
+    private String filePath;
+    private Long lastTime = 0L;
+
+    private FileWriterThread writerThread;
+
+    // 用于存储待写入的UDP包数据
+    private final BlockingQueue<LogEntry> logQueue = new LinkedBlockingQueue<>();
+
+    // 枚举构造函数
+    private TaskInfo(float x, float y, boolean initFlag, float conversionRate) {
+        this.x = x;
+        this.y = y;
+        this.initFlag = initFlag;
+        this.conversionRate = conversionRate;
+    }
+
+    // 重置方法
+    public void reset(Long bizId, String filePath) {
+        // 初始化
+        this.x = 0f;
+        this.y = 0f;
+        this.initFlag = true;
+        this.conversionRate = 0.00001f;
+        this.bizId = bizId;
+        this.filePath = filePath;
+        logQueue.clear();
+        if(writerThread != null) {
+            writerThread.shutdown();
+            try {
+                writerThread.join(); // 等待写入线程完成
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            }
+        }
+        writerThread = new FileWriterThread();
+        writerThread.start();
+    }
+
+    // 日志条目类
+    public static class LogEntry {
+        final String data;
+        final long time;
+
+        LogEntry(String data, long time) {
+            this.data = data;
+            this.time = time;
+        }
+    }
+
+    // 文件写入线程
+    private class FileWriterThread extends Thread {
+        private volatile boolean running = true;
+
+        @Override
+        public void run() {
+            File file = new File(filePath);
+
+            // 创建父目录(如果不存在)
+            File parentDir = file.getParentFile();
+            if (!parentDir.exists()) {
+                parentDir.mkdirs(); // 创建所有必要的父目录
+            }
+            try (FileOutputStream fos = new FileOutputStream(TaskInfo.INSTANCE.getFilePath(), true)) {
+                while (running || !logQueue.isEmpty()) {
+                    LogEntry entry = logQueue.take(); // 阻塞直到有数据
+                    // 格式化时间戳(10位数字 + 冒号)
+                    String timestamp = String.format("%010d:", entry.time);
+                    // 先写入时间戳
+                    fos.write(timestamp.getBytes());
+                    // 再写入实际数据
+                    fos.write(entry.data.getBytes());
+                    // 可选: 每条记录后加换行
+                    fos.write('\n');
+                    fos.flush();
+                }
+            } catch (IOException | InterruptedException e) {
+                if (running) { // 仅在非正常关闭时打印错误
+                    System.err.println("File writer error: " + e.getMessage());
+                }
+            }
+        }
+
+        public void shutdown() {
+            running = false;
+            this.interrupt(); // 中断阻塞的take操作
+        }
+    }
+
+    // Getter和Setter方法
+    public float getX() {
+        return x;
+    }
+
+    public void setX(float x) {
+        this.x = x;
+    }
+
+    public float getY() {
+        return y;
+    }
+
+    public void setY(float y) {
+        this.y = y;
+    }
+
+    public boolean getInitFlag() {
+        return initFlag;
+    }
+
+    public void setInitFlag(boolean initFlag) {
+        this.initFlag = initFlag;
+    }
+
+    public float getConversionRate() {
+        return conversionRate;
+    }
+
+    public void setConversionRate(float conversionRate) {
+        this.conversionRate = conversionRate;
+    }
+
+    // 转换坐标方法
+    public float convertValue(float value) {
+        return value * conversionRate;
+    }
+
+    public float getConversionCenterPixel() {
+        return initCenterPixel * conversionRate;
+    }
+
+    public Long getBizId() {
+        return bizId;
+    }
+
+    public void setBizId(Long bizId) {
+        this.bizId = bizId;
+    }
+
+    public String getFilePath() {
+        return filePath;
+    }
+
+    public void setFilePath(String filePath) {
+        this.filePath = filePath;
+    }
+
+    public boolean isInitFlag() {
+        return initFlag;
+    }
+
+    public int getInitCenterPixel() {
+        return initCenterPixel;
+    }
+
+    public Long getLastTime() {
+        return lastTime;
+    }
+
+    public void setLastTime(Long lastTime) {
+        this.lastTime = lastTime;
+    }
+
+    public BlockingQueue<LogEntry> getLogQueue() {
+        return logQueue;
+    }
+
+    public FileWriterThread getWriterThread() {
+        return writerThread;
+    }
+
+    public void setWriterThread(FileWriterThread writerThread) {
+        this.writerThread = writerThread;
+    }
+
+    // 显示坐标信息
+    public void displayCoordinates() {
+        System.out.printf("%s 坐标系 - X: %.2f, Y: %.2f (初始化标识: %s, 转化比率: %.6f)%n",
+                this.name(), x, y, initFlag, conversionRate);
+    }
+}

+ 47 - 10
uavps-framework/src/main/java/com/uavps/framework/udp/UdpClientService.java

@@ -1,11 +1,15 @@
 package com.uavps.framework.udp;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
 
 /**
  * @Author MBQ
@@ -16,23 +20,56 @@ import java.net.InetAddress;
 @Component
 public class UdpClientService {
 
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private static final int BUFF_SIZE = 1000; // 总缓冲区大小 接收方设置的是1024,但是按1024发送回报错。。。
+    private static final int HEADER_SIZE = 4;   // 序号占4字节
+    private static final int DATA_SIZE = BUFF_SIZE - HEADER_SIZE; // 有效数据大小(1020字节)
+    private static final int PORT = 9010; // 有效数据大小(1020字节)
+
     public void send(String message) {
         try {
-            //创建客户端对象,随机一个端口
             DatagramSocket socket = new DatagramSocket();
-            System.out.println("udp客户端发送数据:" + message);
+            InetAddress address = InetAddress.getByName("localhost");
+
+            byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
+            int totalBytes = messageBytes.length;
+            int totalChunks = (int) Math.ceil((double) totalBytes / DATA_SIZE);
+
+            for (int index = 0; index < totalChunks; index++) {
+                // 生成4字节ASCII序号(如 "0001")
+                String indexStr = String.format("%04d", index); // 固定4位,前面补0
+                byte[] indexBytes = indexStr.getBytes(StandardCharsets.UTF_8);
+
+                // 计算当前分片的数据范围
+                int start = index * DATA_SIZE;
+                int end = Math.min(start + DATA_SIZE, totalBytes);
+                byte[] chunkData = new byte[end - start];
+                System.arraycopy(messageBytes, start, chunkData, 0, chunkData.length);
+
+                // 合并序号和数据
+                ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFF_SIZE);
+                baos.write(indexBytes); // 写入4字节ASCII序号
+                baos.write(chunkData);  // 写入数据
+
+                // 发送分片
+                byte[] sendData = baos.toByteArray();
+                DatagramPacket packet = new DatagramPacket(sendData, sendData.length, address, PORT);
+                socket.send(packet);
+                logger.info("Sent chunk: {}, size: {}", indexStr, sendData.length);
+            }
 
-            //封装数据
-            byte[] data = message.getBytes();
-            DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("localhost"), 9010);
+            // 发送结束包(序号为总块数,内容为 "END")
+//            String endIndexStr = String.format("%04d", totalChunks);
+            byte[] endDataBytes = "END".getBytes(StandardCharsets.UTF_8);
 
-            //发送数据
-            socket.send(packet);
+            DatagramPacket endPacket = new DatagramPacket(endDataBytes, endDataBytes.length, address, PORT);
+            socket.send(endPacket);
+            logger.info("Sent END chunk: {}", endDataBytes);
 
-            //释放资源
-            socket.close();
         } catch (IOException e) {
-            e.printStackTrace();
+            logger.error("UdpClientService send error", e);
+            throw new RuntimeException(e);
         }
     }
 }

+ 34 - 98
uavps-framework/src/main/java/com/uavps/framework/udp/UdpServerService.java

@@ -1,13 +1,10 @@
 package com.uavps.framework.udp;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.uavps.common.utils.spring.SpringUtils;
 import com.uavps.framework.config.UdpConfig;
 import com.uavps.framework.udp.utils.UdpDataUtils;
+import com.uavps.framework.utils.UdpUtils;
 import com.uavps.system.service.IUavpsAircraftService;
-import com.uavps.system.udp.vo.Aircraft;
-import com.uavps.system.udp.vo.AircraftFormation;
-import com.uavps.system.udp.vo.UdpData;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -16,6 +13,8 @@ import javax.websocket.Session;
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
+import java.net.SocketException;
+import java.time.Instant;
 
 
 /**
@@ -34,118 +33,55 @@ public class UdpServerService {
 
     private IUavpsAircraftService uavpsAircraftService = SpringUtils.getBean(IUavpsAircraftService.class);
 
-    /*public void receive(Session session) {
-        try {
-            //创建一个服务端对象,注册端口
-            DatagramSocket socket = new DatagramSocket(udpConfig.getPort());
-
-            //创建一个数据包对象,用于接收数据,限制64kb
-            byte[] data = new byte[1024 * 64];
-            DatagramPacket packet = new DatagramPacket(data, data.length);
+    private static final DatagramSocket INSTANCE;
 
-            String uavData = "";
-            boolean exit = false;
-            while (true) {
-                //使用数据包接收客户端发送的数据
-                socket.receive(packet);
-                uavData = new String(data, 0, packet.getLength());
-                //websocket 退出,关闭upd服务
-                if (uavData.length() == 4 && "EXIT".equals(uavData)) {
-                    socket.close();
-                    break;
-                }
-                JSONArray dataAry = JSON.parseArray(uavData);
-                if (dataAry != null) {
-                    UavpsAircraft uavpsAircraft = null;
-                    for (int i = 0; i < dataAry.size(); i++) {
-                        UdpData udpData = JSON.parseObject(dataAry.getString(i), UdpData.class);
-                        uavpsAircraft = new UavpsAircraft();
-                        uavpsAircraft.setBizId(udpData.getBizId());
-                        uavpsAircraft.setDataTime(BigDecimal.valueOf(udpData.getTime()));
-                        uavpsAircraft.setAircraftData(dataAry.getString(i));
-                        uavpsAircraft.setCreateBy("python");
-
-                        //入库
-                        //uavpsAircraftService.insertUavpsAircraft(uavpsAircraft);
-
-                        //数据发送页面展示
-                        session.getBasicRemote().sendText(dataAry.getString(i));
-                        Thread.sleep(20);
-
-                        //判断数据是否发送完毕
-                        if ("true".equals(udpData.getFinished())) {
-                            exit = true;
-                            break;
-                        }
-                    }
-                }
-                if (exit) {
-                    socket.close();
-                    break;
-                }
-            }
-        } catch (IOException | InterruptedException e) {
-            e.printStackTrace();
+    static {
+        try {
+            Integer port = SpringUtils.getBean(UdpConfig.class).getPort();
+            INSTANCE = new DatagramSocket(port);
+            log.info("UDP Server started on port:  {}", port);
+        } catch (SocketException e) {
+            throw new RuntimeException("Failed to start UDP server", e);
         }
-    }*/
+    }
 
     public void receive(Session session) {
         try {
             //创建一个服务端对象,注册端口
-            DatagramSocket socket = new DatagramSocket(udpConfig.getPort());
             //创建一个数据包对象,用于接收数据
             byte[] data = new byte[1024];
             DatagramPacket packet = new DatagramPacket(data, data.length);
 
             String uavData = "";
-            int i = 0;
+            long initMilli = Instant.now().toEpochMilli();
+
             while (true) {
+                // 设置初始时间,用于计算每个数据的时间差
+                if(TaskInfo.INSTANCE.getInitFlag()){
+                    initMilli = Instant.now().toEpochMilli();
+                    log.info("任务Id:{},任务开始,开始时间是:{}", TaskInfo.INSTANCE.getBizId(), initMilli);
+                }
+
                 //使用数据包接收客户端发送的数据
-                socket.receive(packet);
+                INSTANCE.receive(packet);
                 uavData = new String(data, 0, packet.getLength());
-                //websocket 退出,关闭upd服务
-                if (uavData.length() == 4 && "EXIT".equals(uavData)) {
-                    socket.close();
-                    break;
-                }
                 byte[] remoteData = UdpDataUtils.hexStringToBytes(uavData);
-                //byte[] remoteData = packet.getData();
-                if (remoteData != null && remoteData.length > 3) {
-                    UdpData udpData = UdpDataUtils.parseFrame(remoteData);
-                    //System.out.println(UdpDataUtils.bizId);
-                    if (udpData != null) {
-                        UdpDataUtils.time += 1;
-                        udpData.setTime(UdpDataUtils.time);
-                        if(udpData.getTargetAircraft() != null){
-                            for (AircraftFormation aircraftFormation : udpData.getTargetAircraft()) {
-                                for (Aircraft aircraft : aircraftFormation.getAircrafts()) {
-                                    if(CoordinateSystem.INSTANCE.getInitFlag()){
-                                        CoordinateSystem.INSTANCE.setX(aircraft.getCoordinateX() - CoordinateSystem.INSTANCE.getConversionCenterPixel());
-                                        CoordinateSystem.INSTANCE.setY(aircraft.getCoordinateY() - CoordinateSystem.INSTANCE.getConversionCenterPixel());
-                                        CoordinateSystem.INSTANCE.setInitFlag(false);
-                                    }
-                                    getNewXYAircraftCoordinate(aircraft);
-                                }
-                            }
-                        }
-                        ObjectMapper mapper = new ObjectMapper();
-                        String json = mapper.writeValueAsString(udpData);
-                        session.getBasicRemote().sendText(json);
-                        //System.out.println(json);
-                    }
-//                    log.info("loop:"+(i++)+":"+udpData.getTargetAircraftsString());
-                }
+                // 将日志条目放入队列
+                // 复制数据以避免后续修改影响
+//                int length = remoteData.length;
+//                byte[] dataCopy = new byte[length];
+//                System.arraycopy(remoteData, 0, dataCopy, 0, length);
+                long lastTime = Instant.now().toEpochMilli() - initMilli;
+                String jsonResult = UdpUtils.getJson(remoteData);
+                TaskInfo.INSTANCE.getLogQueue().add(new TaskInfo.LogEntry(jsonResult, lastTime));
+                TaskInfo.INSTANCE.setLastTime(lastTime);
+                session.getBasicRemote().sendText(jsonResult);
             }
         } catch (IOException e) {
-            e.printStackTrace();
+            log.error("UdpServerService.receive error", e);
+            throw new RuntimeException(e);
         }
     }
 
-    private void getNewXYAircraftCoordinate(Aircraft aircraft) {
-        aircraft.setCoordinateOX(aircraft.getCoordinateX());
-        aircraft.setCoordinateOY(aircraft.getCoordinateY());
-        aircraft.setCoordinateOZ(aircraft.getCoordinateZ());
-        aircraft.setCoordinateX((aircraft.getCoordinateX()-CoordinateSystem.INSTANCE.getX())/CoordinateSystem.INSTANCE.getConversionRate());
-        aircraft.setCoordinateY((aircraft.getCoordinateY()-CoordinateSystem.INSTANCE.getY())/CoordinateSystem.INSTANCE.getConversionRate());
-    }
+
 }

+ 0 - 55
uavps-framework/src/main/java/com/uavps/framework/udp/UdpUtils.java

@@ -1,55 +0,0 @@
-package com.uavps.framework.udp;
-
-import com.uavps.common.utils.uuid.IdUtils;
-import com.uavps.system.udp.vo.TargetAircraft;
-import com.uavps.system.udp.vo.UdpInitParameter;
-import com.uavps.system.udp.vo.UnmannedAerialVehicle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @Author MBQ
- * @Date: 2025/1/15
- * @Description:
- * @Version: 1.0
- **/
-public class UdpUtils {
-    public UdpInitParameter initParameter() {
-        UdpInitParameter parameter = new UdpInitParameter();
-        parameter.setBizId(IdUtils.simpleUUID());
-        parameter.setRefreshRate("20");
-
-        UnmannedAerialVehicle unmannedAerialVehicle = new UnmannedAerialVehicle();
-        unmannedAerialVehicle.setInitialPositionX(135);
-        unmannedAerialVehicle.setInitialPositionY(175);
-        unmannedAerialVehicle.setInitialPositionZ(100);
-        unmannedAerialVehicle.setInitialSpeed(20.33f);
-        unmannedAerialVehicle.setInitialPoseX(2.33f);
-        unmannedAerialVehicle.setInitialPoseY(2.33f);
-        unmannedAerialVehicle.setInitialPoseZ(2.33f);
-        parameter.setUnmannedAerialVehicle(unmannedAerialVehicle);
-
-        TargetAircraft targetAircraft = new TargetAircraft();
-        targetAircraft.setAircraftType("固定翼无人机");
-        targetAircraft.setFormationAircraftCount(50);
-        targetAircraft.setLeadAircraftSpeed(11.20f);
-        targetAircraft.setInitialPositionX(100.00f);
-        targetAircraft.setInitialPositionY(100.00f);
-        targetAircraft.setInitialPositionZ(100.00f);
-        targetAircraft.setFlightPathType("直线");
-        targetAircraft.setPositionNoise(18.20f);
-        targetAircraft.setFormationShape("V");
-        targetAircraft.setFollowAircraftDistance(20.00f);
-
-        List<TargetAircraft> multiTargetFormation = new ArrayList<>();
-        multiTargetFormation.add(targetAircraft);
-
-        parameter.setMultiTargetFormation(multiTargetFormation);
-        return parameter;
-    }
-
-    public static void main(String[] args) {
-        System.out.printf(IdUtils.simpleUUID());
-    }
-}

+ 93 - 0
uavps-framework/src/main/java/com/uavps/framework/utils/UdpUtils.java

@@ -0,0 +1,93 @@
+package com.uavps.framework.utils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.uavps.common.utils.uuid.IdUtils;
+import com.uavps.framework.udp.TaskInfo;
+import com.uavps.framework.udp.utils.UdpDataUtils;
+import com.uavps.system.udp.vo.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author MBQ
+ * @Date: 2025/1/15
+ * @Description:
+ * @Version: 1.0
+ **/
+public class UdpUtils {
+    public UdpInitParameter initParameter() {
+        UdpInitParameter parameter = new UdpInitParameter();
+        parameter.setBizId(IdUtils.simpleUUID());
+        parameter.setRefreshRate("20");
+
+        UnmannedAerialVehicle unmannedAerialVehicle = new UnmannedAerialVehicle();
+        unmannedAerialVehicle.setInitialPositionX(135);
+        unmannedAerialVehicle.setInitialPositionY(175);
+        unmannedAerialVehicle.setInitialPositionZ(100);
+        unmannedAerialVehicle.setInitialSpeed(20.33f);
+        unmannedAerialVehicle.setInitialPoseX(2.33f);
+        unmannedAerialVehicle.setInitialPoseY(2.33f);
+        unmannedAerialVehicle.setInitialPoseZ(2.33f);
+        parameter.setUnmannedAerialVehicle(unmannedAerialVehicle);
+
+        TargetAircraft targetAircraft = new TargetAircraft();
+        targetAircraft.setAircraftType("固定翼无人机");
+        targetAircraft.setFormationAircraftCount(50);
+        targetAircraft.setLeadAircraftSpeed(11.20f);
+        targetAircraft.setInitialPositionX(100.00f);
+        targetAircraft.setInitialPositionY(100.00f);
+        targetAircraft.setInitialPositionZ(100.00f);
+        targetAircraft.setFlightPathType("直线");
+        targetAircraft.setPositionNoise(18.20f);
+        targetAircraft.setFormationShape("V");
+        targetAircraft.setFollowAircraftDistance(20.00f);
+
+        List<TargetAircraft> multiTargetFormation = new ArrayList<>();
+        multiTargetFormation.add(targetAircraft);
+
+        parameter.setMultiTargetFormation(multiTargetFormation);
+        return parameter;
+    }
+
+    public static void main(String[] args) {
+        System.out.printf(IdUtils.simpleUUID());
+    }
+
+    public static String getJson(byte[] remoteData) throws JsonProcessingException {
+//        uavData = new String(data, 0, packet.getLength());
+        //byte[] remoteData = packet.getData();
+        String json = "";
+        if (remoteData != null && remoteData.length > 3) {
+            UdpData udpData = UdpDataUtils.parseFrame(remoteData);
+            if (udpData != null) {
+//                        UdpDataUtils.time += 1;
+//                        udpData.setTime(UdpDataUtils.time);
+                if(udpData.getTargetAircraft() != null){
+                    for (AircraftFormation aircraftFormation : udpData.getTargetAircraft()) {
+                        for (Aircraft aircraft : aircraftFormation.getAircrafts()) {
+                            if(TaskInfo.INSTANCE.getInitFlag()){
+                                TaskInfo.INSTANCE.setX(aircraft.getCoordinateX() - TaskInfo.INSTANCE.getConversionCenterPixel());
+                                TaskInfo.INSTANCE.setY(aircraft.getCoordinateY() - TaskInfo.INSTANCE.getConversionCenterPixel());
+                                TaskInfo.INSTANCE.setInitFlag(false);
+                            }
+                            getNewXYAircraftCoordinate(aircraft);
+                        }
+                    }
+                }
+                ObjectMapper mapper = new ObjectMapper();
+                json = mapper.writeValueAsString(udpData);
+            }
+        }
+        return json;
+    }
+
+    private static void getNewXYAircraftCoordinate(Aircraft aircraft) {
+        aircraft.setCoordinateOX(aircraft.getCoordinateX());
+        aircraft.setCoordinateOY(aircraft.getCoordinateY());
+        aircraft.setCoordinateOZ(aircraft.getCoordinateZ());
+        aircraft.setCoordinateX((aircraft.getCoordinateX()- TaskInfo.INSTANCE.getX())/ TaskInfo.INSTANCE.getConversionRate());
+        aircraft.setCoordinateY((aircraft.getCoordinateY()- TaskInfo.INSTANCE.getY())/ TaskInfo.INSTANCE.getConversionRate());
+    }
+}

+ 137 - 42
uavps-framework/src/main/java/com/uavps/framework/websocket/WebSocketServer.java

@@ -1,33 +1,34 @@
 package com.uavps.framework.websocket;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.uavps.common.config.RuoYiConfig;
+import com.uavps.common.utils.StringUtils;
 import com.uavps.common.utils.spring.SpringUtils;
-import com.uavps.common.utils.uuid.IdUtils;
-import com.uavps.framework.udp.CoordinateSystem;
+import com.uavps.common.utils.uuid.Seq;
+import com.uavps.framework.udp.TaskInfo;
 import com.uavps.framework.udp.UdpClientService;
 import com.uavps.framework.udp.UdpServerService;
 import com.uavps.framework.udp.utils.UdpDataUtils;
-import com.uavps.system.domain.UavpsAircraft;
-import com.uavps.system.domain.UavpsAlgorithmParameter;
+import com.uavps.system.domain.UavpsTask;
 import com.uavps.system.service.IUavpsAircraftService;
 import com.uavps.system.service.IUavpsAlgorithmParameterService;
+import com.uavps.system.service.IUavpsTaskService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
 
-import javax.websocket.OnClose;
-import javax.websocket.OnError;
-import javax.websocket.OnMessage;
-import javax.websocket.OnOpen;
-import javax.websocket.Session;
+import javax.websocket.*;
 import javax.websocket.server.ServerEndpoint;
+import java.io.BufferedReader;
+import java.io.FileReader;
 import java.io.IOException;
-import java.math.BigDecimal;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
-import java.util.List;
+import java.time.Instant;
+import java.util.Date;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
 
 /**
  * websocket 消息处理
@@ -37,6 +38,8 @@ import java.util.concurrent.CompletableFuture;
 @Component
 @ServerEndpoint("/websocket/message")
 public class WebSocketServer {
+
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
     private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
 
     UdpServerService udpServerService = new UdpServerService();
@@ -47,6 +50,8 @@ public class WebSocketServer {
 
     private IUavpsAlgorithmParameterService algorithmParameterService = SpringUtils.getBean(IUavpsAlgorithmParameterService.class);
 
+    private IUavpsTaskService uavpsTaskService = SpringUtils.getBean(IUavpsTaskService.class);;
+
     /**
      * 连接建立成功调用的方法
      */
@@ -91,49 +96,139 @@ public class WebSocketServer {
         if (session != null) {
             try {
                 if (message.startsWith("REPLAY:")) {
+                    long baseTime = Instant.now().toEpochMilli();
                     //重放,获取数据库轨迹数据
                     String bizId = message.substring(7);
-                    List<UavpsAircraft> dataList = uavpsAircraftService.selectUavpsAircraftByBizId(bizId);
-                    if (!CollectionUtils.isEmpty(dataList)) {
-                        for (UavpsAircraft data : dataList) {
-                            session.getBasicRemote().sendText(data.getAircraftData());
-                            Thread.sleep(20);
+                    UavpsTask uavpsTask = uavpsTaskService.selectUavpsTaskByBizId(Long.parseLong(bizId));
+                    String filePath = uavpsTask.getFilePath();
+                    try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
+                        String line;
+                        while ((line = reader.readLine()) != null) {
+                            // 解析时间戳和数据
+                            if (line.length() > 11 && line.charAt(10) == ':') {
+                                    long timestamp = Long.parseLong(line.substring(0, 10));
+                                    String json = line.substring(11);
+                                    long currentTime = Instant.now().toEpochMilli();
+                                    long targetTime = baseTime + timestamp;
+                                    // 计算需要等待的时间
+                                    long waitTime = targetTime - currentTime;
+                                    if (waitTime > 0) {
+                                        TimeUnit.MILLISECONDS.sleep(waitTime);
+                                    }
+                                    session.getBasicRemote().sendText(json);
+                            } else {
+                                System.err.println("Invalid line format: " + line);
+                            }
                         }
+                    } catch (IOException e) {
+                        log.error("File reading error id : {}", bizId, e);
                     }
                 } else if (message.startsWith("RUN:")) {
-                    // 初始化 坐标转换参数
-                    CoordinateSystem.INSTANCE.reset();
-
                     String paramId = message.substring(4);
-                    UavpsAlgorithmParameter param = algorithmParameterService.selectUavpsAlgorithmParameterById(Long.parseLong(paramId));
-                    String parameter = UdpDataUtils.initAlgorithmParams(param);
-                    System.out.println("parameter:====" + parameter);
-                    System.out.println("param.toString():====" + param);
-                    udpClientService.send(parameter);
-                    /*String str = "BB14030101010100B6EA5F459C96C9172B0001000200030015CD5B070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A01B";
-                    udpClientService.send(str);*/
-                    UdpDataUtils.bizId = IdUtils.simpleUUID();
+//                    UavpsAlgorithmParameter param = algorithmParameterService.selectUavpsAlgorithmParameterById(Long.parseLong(paramId));
+                    long bizId = Long.parseLong(paramId);
+
+                    UavpsTask uavpsTask = uavpsTaskService.selectUavpsTaskByBizId(bizId);
+                    uavpsTask.setBizType(UavpsTask.START);
+                    ObjectMapper mapper = new ObjectMapper();
+                    String json = null;
+                    try {
+                        json = mapper.writeValueAsString(uavpsTask);
+                        logger.info("json :{}", json);
+                    } catch (Exception e) {
+                        logger.error("WebSocketServer.onMessage to json error", e);
+                    }
+                    String filePath = StringUtils.format("{}/{}/{}.{}", RuoYiConfig.getTaskPath(),
+                            bizId, Seq.getId(Seq.uploadSeqType), "txt");
+                    uavpsTask.setFilePath(filePath);
+                    uavpsTask.setStartTime(new Date());
+                    uavpsTask.setStatus(UavpsTask.RUNNING);
+                    uavpsTaskService.updateUavpsTask(uavpsTask);
+                    // 初始化 坐标转换参数
+                    TaskInfo.INSTANCE.reset(bizId, filePath);
+                    assert json != null;
+                    udpClientService.send(json);
+//                    UdpDataUtils.bizId = IdUtils.simpleUUID();
                 } else if (message.startsWith("TRANSFORMATION:")) {
-                    closeUdpServer();
+//                    closeUdpServer();
 
                     String param = message.substring(15);
                     String[] paramAry = param.split(",");
-                    UavpsAlgorithmParameter parameter = algorithmParameterService.selectUavpsAlgorithmParameterById(Long.parseLong(paramAry[0]));
-                    if(!"null".equals(paramAry[1])){
-                        parameter.setLongitude(new BigDecimal(paramAry[1]));
+                    UavpsTask uavpsTask = new UavpsTask();
+                    uavpsTask.setBizId(Long.parseLong(paramAry[0]));
+                    uavpsTask.setBizType(UavpsTask.CHANGE);
+                    ObjectMapper mapper = new ObjectMapper();
+                    String json = null;
+                    try {
+                        json = mapper.writeValueAsString(uavpsTask);
+                        logger.info("json :{}", json);
+                    } catch (Exception e) {
+                        logger.error("WebSocketServer.onMessage to json error", e);
+                    }
+                    assert json != null;
+                    udpClientService.send(json);
+//                    this.onOpen(session);
+                } else if (message.startsWith("DISAPPEAR:")) {
+                    String param = message.substring(10);
+                    String[] paramAry = param.split(",");
+                    UavpsTask uavpsTask = new UavpsTask();
+                    uavpsTask.setBizId(Long.parseLong(paramAry[0]));
+                    uavpsTask.setBizType(UavpsTask.DISAPPEAR);
+                    for (int i = 0; i <= paramAry.length; i++) {
+                        if (i != 0) {
+                            uavpsTask.getNumbers().add(Integer.parseInt(paramAry[i]));
+                        }
+                    }
+                    ObjectMapper mapper = new ObjectMapper();
+                    String json = null;
+                    try {
+                        json = mapper.writeValueAsString(uavpsTask);
+                        logger.info("json :{}", json);
+                    } catch (Exception e) {
+                        logger.error("WebSocketServer.onMessage to json error", e);
+                    }
+                    assert json != null;
+                    udpClientService.send(json);
+                } else if (message.startsWith("SHOW:")) {
+                    String param = message.substring(5);
+                    String[] paramAry = param.split(",");
+                    UavpsTask uavpsTask = new UavpsTask();
+                    uavpsTask.setBizId(Long.parseLong(paramAry[0]));
+                    uavpsTask.setBizType(UavpsTask.SHOW);
+                    for (int i = 0; i <= paramAry.length; i++) {
+                        if (i != 0) {
+                            uavpsTask.getNumbers().add(Integer.parseInt(paramAry[i]));
+                        }
                     }
-                    if(!"null".equals(paramAry[2])){
-                        parameter.setLatitude(new BigDecimal(paramAry[2]));
+                    ObjectMapper mapper = new ObjectMapper();
+                    String json = null;
+                    try {
+                        json = mapper.writeValueAsString(uavpsTask);
+                        logger.info("json :{}", json);
+                    } catch (Exception e) {
+                        logger.error("WebSocketServer.onMessage to json error", e);
                     }
-                    if(!"null".equals(paramAry[3])){
-                        parameter.setAltitude(Long.parseLong(paramAry[3]));
+                    assert json != null;
+                    udpClientService.send(json);
+                } else if (message.startsWith("END:")) {
+                    Long bizId = Long.parseLong(message.substring(5));
+                    UavpsTask uavpsTask = new UavpsTask();
+                    uavpsTask.setBizId(bizId);
+                    uavpsTask.setBizType(UavpsTask.END);
+                    ObjectMapper mapper = new ObjectMapper();
+                    String json = null;
+                    try {
+                        json = mapper.writeValueAsString(uavpsTask);
+                        logger.info("json :{}", json);
+                    } catch (Exception e) {
+                        logger.error("WebSocketServer.onMessage to json error", e);
                     }
-                    String transParam = UdpDataUtils.initAlgorithmParams(parameter);
-                    System.out.println("transParam:====" + transParam);
-                    System.out.println("param.toString():====" + parameter);
-                    udpClientService.send(transParam);
-                    this.onOpen(session);
-                    //String str = "BB14030101010100B6EA5F459C96C9172B0001000200030015CD5B070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A01B";
+                    assert json != null;
+                    udpClientService.send(json);
+                    uavpsTask = uavpsTaskService.selectUavpsTaskByBizId(bizId);
+                    uavpsTask.setEndTime(new Date());
+                    uavpsTask.setStatus(UavpsTask.COMPLETED);
+                    uavpsTaskService.updateUavpsTask(uavpsTask);
                 } else {
                     session.getBasicRemote().sendText(message);
                 }

+ 104 - 0
uavps-system/src/main/java/com/uavps/system/controller/UavpsTaskController.java

@@ -0,0 +1,104 @@
+package com.uavps.system.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.uavps.common.annotation.Log;
+import com.uavps.common.core.controller.BaseController;
+import com.uavps.common.core.domain.AjaxResult;
+import com.uavps.common.enums.BusinessType;
+import com.uavps.system.domain.UavpsTask;
+import com.uavps.system.service.IUavpsTaskService;
+import com.uavps.common.utils.poi.ExcelUtil;
+import com.uavps.common.core.page.TableDataInfo;
+
+/**
+ * 任务数据Controller
+ * 
+ * @author ruoyi
+ * @date 2025-04-17
+ */
+@RestController
+@RequestMapping("/system/task")
+public class UavpsTaskController extends BaseController
+{
+    @Autowired
+    private IUavpsTaskService uavpsTaskService;
+
+    /**
+     * 查询任务数据列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:task:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(UavpsTask uavpsTask)
+    {
+        startPage();
+        List<UavpsTask> list = uavpsTaskService.selectUavpsTaskList(uavpsTask);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出任务数据列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:task:export')")
+    @Log(title = "任务数据", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, UavpsTask uavpsTask)
+    {
+        List<UavpsTask> list = uavpsTaskService.selectUavpsTaskList(uavpsTask);
+        ExcelUtil<UavpsTask> util = new ExcelUtil<UavpsTask>(UavpsTask.class);
+        util.exportExcel(response, list, "任务数据数据");
+    }
+
+    /**
+     * 获取任务数据详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:task:query')")
+    @GetMapping(value = "/{bizId}")
+    public AjaxResult getInfo(@PathVariable("bizId") Long bizId)
+    {
+        return success(uavpsTaskService.selectUavpsTaskByBizId(bizId));
+    }
+
+    /**
+     * 新增任务数据
+     */
+    @PreAuthorize("@ss.hasPermi('system:task:add')")
+    @Log(title = "任务数据", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody UavpsTask uavpsTask)
+    {
+        return toAjax(uavpsTaskService.insertUavpsTask(uavpsTask));
+    }
+
+    /**
+     * 修改任务数据
+     */
+    @PreAuthorize("@ss.hasPermi('system:task:edit')")
+    @Log(title = "任务数据", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody UavpsTask uavpsTask)
+    {
+        return toAjax(uavpsTaskService.updateUavpsTask(uavpsTask));
+    }
+
+    /**
+     * 删除任务数据
+     */
+    @PreAuthorize("@ss.hasPermi('system:task:remove')")
+    @Log(title = "任务数据", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{bizIds}")
+    public AjaxResult remove(@PathVariable Long[] bizIds)
+    {
+        return toAjax(uavpsTaskService.deleteUavpsTaskByBizIds(bizIds));
+    }
+}

+ 352 - 0
uavps-system/src/main/java/com/uavps/system/domain/UavpsTask.java

@@ -0,0 +1,352 @@
+package com.uavps.system.domain;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.uavps.common.annotation.Excel;
+import com.uavps.common.core.domain.BaseEntity;
+import com.uavps.system.domain.dto.CustomizedMultiTargetFormationDTO;
+import com.uavps.system.domain.dto.FixedMultiTargetFormationDTO;
+import com.uavps.system.domain.dto.PlatformUavDTO;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 任务数据对象 uavps_task
+ * 
+ * @author ruoyi
+ * @date 2025-04-17
+ */
+public class UavpsTask extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    public static final String START = "start";
+    public static final String CHANGE = "change";
+    public static final String DISAPPEAR = "disappear";
+    public static final String SHOW = "show";
+    public static final String END = "end";
+    // 未开始
+    public static final String NOT_STARTED = "0";
+    // 进行中
+    public static final String RUNNING = "1";
+    // 已完成
+    public static final String COMPLETED = "2";
+    // 失败
+    public static final String FAILED = "3";
+
+    /** 业务ID */
+    private Long bizId;
+
+    /** 任务名称 */
+    @Excel(name = "任务名称")
+    private String bizName;
+
+    /** 业务类型 */
+    private String bizType;
+
+    /** 多目标类型 */
+    private String multiTarget;
+
+    /** 噪声类型 */
+    private String noiseType;
+
+    /** 噪声方差 */
+    private BigDecimal noiseVariance;
+
+    /** 噪声均值 */
+    private BigDecimal noiseMean;
+
+    /** 固定翼平台无人机数据 */
+    @JsonIgnore
+    private String platformUavStr;
+
+    /** 固定编队目标数据 */
+    @JsonIgnore
+    private String fixedMultiTargetFormationStr;
+
+    /** 自定义编队目标数据 */
+    @JsonIgnore
+    private String customizedMultiTargetFormationStr;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private String status;
+
+    /** 开始时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date startTime;
+
+    /** 结束时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date endTime;
+
+    /** 噪声数据文件路径 */
+    private String filePath;
+
+    /** 固定翼平台无人机数据 */
+    private PlatformUavDTO platformUav;
+
+    /** 固定编队目标数据 */
+    private FixedMultiTargetFormationDTO fixedMultiTargetFormation;
+
+    /** 自定义编队目标数据 */
+    private List<CustomizedMultiTargetFormationDTO> customizedMultiTargetFormation;
+
+    private List<Integer> numbers = new ArrayList<>();
+
+    public void setBizId(Long bizId) 
+    {
+        this.bizId = bizId;
+    }
+
+    public Long getBizId() 
+    {
+        return bizId;
+    }
+    public void setBizName(String bizName) 
+    {
+        this.bizName = bizName;
+    }
+
+    public String getBizName() 
+    {
+        return bizName;
+    }
+    public void setBizType(String bizType) 
+    {
+        this.bizType = bizType;
+    }
+
+    public String getBizType() 
+    {
+        return bizType;
+    }
+    public void setMultiTarget(String multiTarget) 
+    {
+        this.multiTarget = multiTarget;
+    }
+
+    public String getMultiTarget() 
+    {
+        return multiTarget;
+    }
+    public void setNoiseType(String noiseType)
+    {
+        this.noiseType = noiseType;
+    }
+
+    public String getNoiseType()
+    {
+        return noiseType;
+    }
+    public void setNoiseVariance(BigDecimal noiseVariance)
+    {
+        this.noiseVariance = noiseVariance;
+    }
+
+    public BigDecimal getNoiseVariance()
+    {
+        return noiseVariance;
+    }
+    public void setNoiseMean(BigDecimal noiseMean)
+    {
+        this.noiseMean = noiseMean;
+    }
+
+    public BigDecimal getNoiseMean()
+    {
+        return noiseMean;
+    }
+    public void setPlatformUavStr(String platformUavStr) 
+    {
+        this.platformUavStr = platformUavStr;
+    }
+
+    public String getPlatformUavStr() 
+    {
+        return platformUavStr;
+    }
+    public void setFixedMultiTargetFormationStr(String fixedMultiTargetFormationStr) 
+    {
+        this.fixedMultiTargetFormationStr = fixedMultiTargetFormationStr;
+    }
+
+    public String getFixedMultiTargetFormationStr() 
+    {
+        return fixedMultiTargetFormationStr;
+    }
+    public void setCustomizedMultiTargetFormationStr(String customizedMultiTargetFormationStr) 
+    {
+        this.customizedMultiTargetFormationStr = customizedMultiTargetFormationStr;
+    }
+
+    public String getCustomizedMultiTargetFormationStr() 
+    {
+        return customizedMultiTargetFormationStr;
+    }
+    public void setStatus(String status) 
+    {
+        this.status = status;
+    }
+
+    public String getStatus() 
+    {
+        return status;
+    }
+    public void setStartTime(Date startTime)
+    {
+        this.startTime = startTime;
+    }
+
+    public Date getStartTime() 
+    {
+        return startTime;
+    }
+    public void setEndTime(Date endTime) 
+    {
+        this.endTime = endTime;
+    }
+
+    public Date getEndTime() 
+    {
+        return endTime;
+    }
+    public void setFilePath(String filePath) 
+    {
+        this.filePath = filePath;
+    }
+
+    public String getFilePath() 
+    {
+        return filePath;
+    }
+
+
+    public PlatformUavDTO getPlatformUav() {
+        if (platformUav == null && StringUtils.isNotEmpty(platformUavStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                this.platformUav = mapper.readValue(this.platformUavStr, PlatformUavDTO.class);
+            } catch (Exception e) {
+                logger.error("UavpsTask.getPlatformUav error", e);
+            }
+        }
+        return platformUav;
+    }
+
+    public void setPlatformUav(PlatformUavDTO platformUav) {
+        this.platformUav = platformUav;
+        if (platformUav != null && StringUtils.isEmpty(this.platformUavStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                String json = mapper.writeValueAsString(platformUav);
+                this.platformUavStr = json;
+            } catch (Exception e) {
+                logger.error("UavpsTask.setPlatformUav error", e);
+            }
+        }
+    }
+
+    public FixedMultiTargetFormationDTO getFixedMultiTargetFormation() {
+        if (fixedMultiTargetFormation == null && StringUtils.isNotEmpty(fixedMultiTargetFormationStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                fixedMultiTargetFormation = mapper.readValue(this.fixedMultiTargetFormationStr, FixedMultiTargetFormationDTO.class);
+            } catch (Exception e) {
+                logger.error("UavpsTask.getPlatformUav error", e);
+            }
+        }
+        return fixedMultiTargetFormation;
+    }
+
+    public void setFixedMultiTargetFormation(FixedMultiTargetFormationDTO fixedMultiTargetFormation) {
+        this.fixedMultiTargetFormation = fixedMultiTargetFormation;
+        if (fixedMultiTargetFormation != null && StringUtils.isEmpty(this.fixedMultiTargetFormationStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            String json = null;
+            try {
+                json = mapper.writeValueAsString(fixedMultiTargetFormation);
+            } catch (Exception e) {
+                logger.error("UavpsTask.setPlatformUav error", e);
+            }
+            this.fixedMultiTargetFormationStr = json;
+        }
+    }
+
+    public List<CustomizedMultiTargetFormationDTO> getCustomizedMultiTargetFormation() {
+        if (customizedMultiTargetFormation == null && StringUtils.isNotEmpty(customizedMultiTargetFormationStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                this.customizedMultiTargetFormation = mapper.readValue(customizedMultiTargetFormationStr, new TypeReference<List<CustomizedMultiTargetFormationDTO>>() {});
+            } catch (Exception e) {
+                logger.error("UavpsTask.getCustomizedMultiTargetFormation error", e);
+            }
+        }
+        return customizedMultiTargetFormation;
+    }
+
+    public void setCustomizedMultiTargetFormation(List<CustomizedMultiTargetFormationDTO> customizedMultiTargetFormation) {
+        this.customizedMultiTargetFormation = customizedMultiTargetFormation;
+        if (customizedMultiTargetFormation != null && StringUtils.isEmpty(this.customizedMultiTargetFormationStr)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                customizedMultiTargetFormationStr = mapper.writeValueAsString(customizedMultiTargetFormation);
+            } catch (Exception e) {
+                logger.error("UavpsTask.setCustomizedMultiTargetFormation error", e);
+            }
+        }
+    }
+
+    public List<Integer> getNumbers() {
+        return numbers;
+    }
+
+    public void setNumbers(List<Integer> numbers) {
+        this.numbers = numbers;
+    }
+
+    public Long getTotalDuration() {
+        if (COMPLETED.equals(this.status) && startTime != null && endTime != null) {
+            return endTime.getTime() - startTime.getTime();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "UavpsTask{" +
+                "bizId=" + bizId +
+                ", bizName='" + bizName + '\'' +
+                ", bizType='" + bizType + '\'' +
+                ", multiTarget='" + multiTarget + '\'' +
+                ", noiseType='" + noiseType + '\'' +
+                ", noiseVariance=" + noiseVariance +
+                ", noiseMean=" + noiseMean +
+                ", platformUavStr='" + platformUavStr + '\'' +
+                ", fixedMultiTargetFormationStr='" + fixedMultiTargetFormationStr + '\'' +
+                ", customizedMultiTargetFormationStr='" + customizedMultiTargetFormationStr + '\'' +
+                ", status='" + status + '\'' +
+                ", startTime=" + startTime +
+                ", endTime=" + endTime +
+                ", filePath='" + filePath + '\'' +
+                ", platformUav=" + platformUav +
+                ", fixedMultiTargetFormation=" + fixedMultiTargetFormation +
+                ", customizedMultiTargetFormation=" + customizedMultiTargetFormation +
+                ", numbers=" + numbers +
+                '}';
+    }
+}

+ 87 - 0
uavps-system/src/main/java/com/uavps/system/domain/dto/CustomizedMultiTargetFormationDTO.java

@@ -0,0 +1,87 @@
+package com.uavps.system.domain.dto;
+
+import java.math.BigDecimal;
+
+public class CustomizedMultiTargetFormationDTO {
+    private Integer number;
+    private BigDecimal longitude;
+    private BigDecimal latitude;
+    private BigDecimal altitude;
+    private BigDecimal eastSpeed;
+    private BigDecimal northSpeed;
+    private BigDecimal skySpeed;
+    private String flightPathType;
+    private BigDecimal positionNoise;
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public BigDecimal getLongitude() {
+        return longitude;
+    }
+
+    public void setLongitude(BigDecimal longitude) {
+        this.longitude = longitude;
+    }
+
+    public BigDecimal getLatitude() {
+        return latitude;
+    }
+
+    public void setLatitude(BigDecimal latitude) {
+        this.latitude = latitude;
+    }
+
+    public BigDecimal getAltitude() {
+        return altitude;
+    }
+
+    public void setAltitude(BigDecimal altitude) {
+        this.altitude = altitude;
+    }
+
+    public BigDecimal getEastSpeed() {
+        return eastSpeed;
+    }
+
+    public void setEastSpeed(BigDecimal eastSpeed) {
+        this.eastSpeed = eastSpeed;
+    }
+
+    public BigDecimal getNorthSpeed() {
+        return northSpeed;
+    }
+
+    public void setNorthSpeed(BigDecimal northSpeed) {
+        this.northSpeed = northSpeed;
+    }
+
+    public BigDecimal getSkySpeed() {
+        return skySpeed;
+    }
+
+    public void setSkySpeed(BigDecimal skySpeed) {
+        this.skySpeed = skySpeed;
+    }
+
+    public String getFlightPathType() {
+        return flightPathType;
+    }
+
+    public void setFlightPathType(String flightPathType) {
+        this.flightPathType = flightPathType;
+    }
+
+    public BigDecimal getPositionNoise() {
+        return positionNoise;
+    }
+
+    public void setPositionNoise(BigDecimal positionNoise) {
+        this.positionNoise = positionNoise;
+    }
+}

+ 112 - 0
uavps-system/src/main/java/com/uavps/system/domain/dto/FixedMultiTargetFormationDTO.java

@@ -0,0 +1,112 @@
+package com.uavps.system.domain.dto;
+
+import java.math.BigDecimal;
+
+public class FixedMultiTargetFormationDTO {
+    private Integer targetTotal;
+    private BigDecimal longitude;
+    private BigDecimal latitude;
+    private BigDecimal altitude;
+    private BigDecimal eastSpeed;
+    private BigDecimal northSpeed;
+    private BigDecimal skySpeed;
+    private String flightPathType;
+    private String formationShape;
+    private BigDecimal followAircraftDistance;
+
+    public Integer getTargetTotal() {
+        return targetTotal;
+    }
+
+    public void setTargetTotal(Integer targetTotal) {
+        this.targetTotal = targetTotal;
+    }
+
+    public BigDecimal getLongitude() {
+        return longitude;
+    }
+
+    public void setLongitude(BigDecimal longitude) {
+        this.longitude = longitude;
+    }
+
+    public BigDecimal getLatitude() {
+        return latitude;
+    }
+
+    public void setLatitude(BigDecimal latitude) {
+        this.latitude = latitude;
+    }
+
+    public BigDecimal getAltitude() {
+        return altitude;
+    }
+
+    public void setAltitude(BigDecimal altitude) {
+        this.altitude = altitude;
+    }
+
+    public BigDecimal getEastSpeed() {
+        return eastSpeed;
+    }
+
+    public void setEastSpeed(BigDecimal eastSpeed) {
+        this.eastSpeed = eastSpeed;
+    }
+
+    public BigDecimal getNorthSpeed() {
+        return northSpeed;
+    }
+
+    public void setNorthSpeed(BigDecimal northSpeed) {
+        this.northSpeed = northSpeed;
+    }
+
+    public BigDecimal getSkySpeed() {
+        return skySpeed;
+    }
+
+    public void setSkySpeed(BigDecimal skySpeed) {
+        this.skySpeed = skySpeed;
+    }
+
+    public String getFlightPathType() {
+        return flightPathType;
+    }
+
+    public void setFlightPathType(String flightPathType) {
+        this.flightPathType = flightPathType;
+    }
+
+    public String getFormationShape() {
+        return formationShape;
+    }
+
+    public void setFormationShape(String formationShape) {
+        this.formationShape = formationShape;
+    }
+
+    public BigDecimal getFollowAircraftDistance() {
+        return followAircraftDistance;
+    }
+
+    public void setFollowAircraftDistance(BigDecimal followAircraftDistance) {
+        this.followAircraftDistance = followAircraftDistance;
+    }
+
+    @Override
+    public String toString() {
+        return "FixedMultiTargetFormationDTO{" +
+                "targetTotal=" + targetTotal +
+                ", longitude=" + longitude +
+                ", latitude=" + latitude +
+                ", altitude=" + altitude +
+                ", eastSpeed=" + eastSpeed +
+                ", northSpeed=" + northSpeed +
+                ", skySpeed=" + skySpeed +
+                ", flightPathType='" + flightPathType + '\'' +
+                ", formationShape='" + formationShape + '\'' +
+                ", followAircraftDistance=" + followAircraftDistance +
+                '}';
+    }
+}

+ 72 - 0
uavps-system/src/main/java/com/uavps/system/domain/dto/PlatformUavDTO.java

@@ -0,0 +1,72 @@
+package com.uavps.system.domain.dto;
+
+import java.math.BigDecimal;
+
+public class PlatformUavDTO {
+    private BigDecimal longitude;
+    private BigDecimal latitude;
+    private BigDecimal altitude;
+    private BigDecimal eastSpeed;
+    private BigDecimal northSpeed;
+    private BigDecimal skySpeed;
+
+    public BigDecimal getLongitude() {
+        return longitude;
+    }
+
+    public void setLongitude(BigDecimal longitude) {
+        this.longitude = longitude;
+    }
+
+    public BigDecimal getLatitude() {
+        return latitude;
+    }
+
+    public void setLatitude(BigDecimal latitude) {
+        this.latitude = latitude;
+    }
+
+    public BigDecimal getAltitude() {
+        return altitude;
+    }
+
+    public void setAltitude(BigDecimal altitude) {
+        this.altitude = altitude;
+    }
+
+    public BigDecimal getEastSpeed() {
+        return eastSpeed;
+    }
+
+    public void setEastSpeed(BigDecimal eastSpeed) {
+        this.eastSpeed = eastSpeed;
+    }
+
+    public BigDecimal getNorthSpeed() {
+        return northSpeed;
+    }
+
+    public void setNorthSpeed(BigDecimal northSpeed) {
+        this.northSpeed = northSpeed;
+    }
+
+    public BigDecimal getSkySpeed() {
+        return skySpeed;
+    }
+
+    public void setSkySpeed(BigDecimal skySpeed) {
+        this.skySpeed = skySpeed;
+    }
+
+    @Override
+    public String toString() {
+        return "PlatformUavDTO{" +
+                "longitude=" + longitude +
+                ", latitude=" + latitude +
+                ", altitude=" + altitude +
+                ", eastSpeed=" + eastSpeed +
+                ", northSpeed=" + northSpeed +
+                ", skySpeed=" + skySpeed +
+                '}';
+    }
+}

+ 61 - 0
uavps-system/src/main/java/com/uavps/system/mapper/UavpsTaskMapper.java

@@ -0,0 +1,61 @@
+package com.uavps.system.mapper;
+
+import java.util.List;
+import com.uavps.system.domain.UavpsTask;
+
+/**
+ * 任务数据Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-04-17
+ */
+public interface UavpsTaskMapper 
+{
+    /**
+     * 查询任务数据
+     * 
+     * @param bizId 任务数据主键
+     * @return 任务数据
+     */
+    public UavpsTask selectUavpsTaskByBizId(Long bizId);
+
+    /**
+     * 查询任务数据列表
+     * 
+     * @param uavpsTask 任务数据
+     * @return 任务数据集合
+     */
+    public List<UavpsTask> selectUavpsTaskList(UavpsTask uavpsTask);
+
+    /**
+     * 新增任务数据
+     * 
+     * @param uavpsTask 任务数据
+     * @return 结果
+     */
+    public int insertUavpsTask(UavpsTask uavpsTask);
+
+    /**
+     * 修改任务数据
+     * 
+     * @param uavpsTask 任务数据
+     * @return 结果
+     */
+    public int updateUavpsTask(UavpsTask uavpsTask);
+
+    /**
+     * 删除任务数据
+     * 
+     * @param bizId 任务数据主键
+     * @return 结果
+     */
+    public int deleteUavpsTaskByBizId(Long bizId);
+
+    /**
+     * 批量删除任务数据
+     * 
+     * @param bizIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteUavpsTaskByBizIds(Long[] bizIds);
+}

+ 61 - 0
uavps-system/src/main/java/com/uavps/system/service/IUavpsTaskService.java

@@ -0,0 +1,61 @@
+package com.uavps.system.service;
+
+import java.util.List;
+import com.uavps.system.domain.UavpsTask;
+
+/**
+ * 任务数据Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-04-17
+ */
+public interface IUavpsTaskService 
+{
+    /**
+     * 查询任务数据
+     * 
+     * @param bizId 任务数据主键
+     * @return 任务数据
+     */
+    public UavpsTask selectUavpsTaskByBizId(Long bizId);
+
+    /**
+     * 查询任务数据列表
+     * 
+     * @param uavpsTask 任务数据
+     * @return 任务数据集合
+     */
+    public List<UavpsTask> selectUavpsTaskList(UavpsTask uavpsTask);
+
+    /**
+     * 新增任务数据
+     * 
+     * @param uavpsTask 任务数据
+     * @return 结果
+     */
+    public int insertUavpsTask(UavpsTask uavpsTask);
+
+    /**
+     * 修改任务数据
+     * 
+     * @param uavpsTask 任务数据
+     * @return 结果
+     */
+    public int updateUavpsTask(UavpsTask uavpsTask);
+
+    /**
+     * 批量删除任务数据
+     * 
+     * @param bizIds 需要删除的任务数据主键集合
+     * @return 结果
+     */
+    public int deleteUavpsTaskByBizIds(Long[] bizIds);
+
+    /**
+     * 删除任务数据信息
+     * 
+     * @param bizId 任务数据主键
+     * @return 结果
+     */
+    public int deleteUavpsTaskByBizId(Long bizId);
+}

+ 96 - 0
uavps-system/src/main/java/com/uavps/system/service/impl/UavpsTaskServiceImpl.java

@@ -0,0 +1,96 @@
+package com.uavps.system.service.impl;
+
+import java.util.List;
+import com.uavps.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.uavps.system.mapper.UavpsTaskMapper;
+import com.uavps.system.domain.UavpsTask;
+import com.uavps.system.service.IUavpsTaskService;
+
+/**
+ * 任务数据Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-04-17
+ */
+@Service
+public class UavpsTaskServiceImpl implements IUavpsTaskService 
+{
+    @Autowired
+    private UavpsTaskMapper uavpsTaskMapper;
+
+    /**
+     * 查询任务数据
+     * 
+     * @param bizId 任务数据主键
+     * @return 任务数据
+     */
+    @Override
+    public UavpsTask selectUavpsTaskByBizId(Long bizId)
+    {
+        return uavpsTaskMapper.selectUavpsTaskByBizId(bizId);
+    }
+
+    /**
+     * 查询任务数据列表
+     * 
+     * @param uavpsTask 任务数据
+     * @return 任务数据
+     */
+    @Override
+    public List<UavpsTask> selectUavpsTaskList(UavpsTask uavpsTask)
+    {
+        return uavpsTaskMapper.selectUavpsTaskList(uavpsTask);
+    }
+
+    /**
+     * 新增任务数据
+     * 
+     * @param uavpsTask 任务数据
+     * @return 结果
+     */
+    @Override
+    public int insertUavpsTask(UavpsTask uavpsTask)
+    {
+        uavpsTask.setCreateTime(DateUtils.getNowDate());
+        return uavpsTaskMapper.insertUavpsTask(uavpsTask);
+    }
+
+    /**
+     * 修改任务数据
+     * 
+     * @param uavpsTask 任务数据
+     * @return 结果
+     */
+    @Override
+    public int updateUavpsTask(UavpsTask uavpsTask)
+    {
+        uavpsTask.setUpdateTime(DateUtils.getNowDate());
+        return uavpsTaskMapper.updateUavpsTask(uavpsTask);
+    }
+
+    /**
+     * 批量删除任务数据
+     * 
+     * @param bizIds 需要删除的任务数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteUavpsTaskByBizIds(Long[] bizIds)
+    {
+        return uavpsTaskMapper.deleteUavpsTaskByBizIds(bizIds);
+    }
+
+    /**
+     * 删除任务数据信息
+     * 
+     * @param bizId 任务数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteUavpsTaskByBizId(Long bizId)
+    {
+        return uavpsTaskMapper.deleteUavpsTaskByBizId(bizId);
+    }
+}

+ 124 - 0
uavps-system/src/main/resources/mapper/system/UavpsTaskMapper.xml

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.uavps.system.mapper.UavpsTaskMapper">
+    
+    <resultMap type="UavpsTask" id="UavpsTaskResult">
+        <result property="bizId"    column="biz_id"    />
+        <result property="bizName"    column="biz_name"    />
+        <result property="bizType"    column="biz_type"    />
+        <result property="multiTarget"    column="multi_target"    />
+        <result property="noiseType"    column="noise_type"    />
+        <result property="noiseVariance"    column="noise_variance"    />
+        <result property="noiseMean"    column="noise_mean"    />
+        <result property="platformUavStr"    column="platform_uav_str"    />
+        <result property="fixedMultiTargetFormationStr"    column="fixed_multi_target_formation_str"    />
+        <result property="customizedMultiTargetFormationStr"    column="customized_multi_target_formation_str"    />
+        <result property="status"    column="status"    />
+        <result property="startTime"    column="start_time"    />
+        <result property="endTime"    column="end_time"    />
+        <result property="filePath"    column="file_path"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectUavpsTaskVo">
+        select biz_id, biz_name, biz_type, multi_target, noise_type, noise_variance, noise_mean, platform_uav_str, fixed_multi_target_formation_str, customized_multi_target_formation_str, status, start_time, end_time, file_path, create_by, create_time, update_by, update_time from uavps_task
+    </sql>
+
+    <select id="selectUavpsTaskList" parameterType="UavpsTask" resultMap="UavpsTaskResult">
+        <include refid="selectUavpsTaskVo"/>
+        <where>  
+            <if test="bizName != null  and bizName != ''"> and biz_name like concat('%', #{bizName}, '%')</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+            <if test="startTime != null "> and start_time = #{startTime}</if>
+            <if test="endTime != null "> and end_time = #{endTime}</if>
+            <if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''"> and create_time between #{params.beginCreateTime} and #{params.endCreateTime}</if>
+        </where>
+    </select>
+    
+    <select id="selectUavpsTaskByBizId" parameterType="Long" resultMap="UavpsTaskResult">
+        <include refid="selectUavpsTaskVo"/>
+        where biz_id = #{bizId}
+    </select>
+
+    <insert id="insertUavpsTask" parameterType="UavpsTask" useGeneratedKeys="true" keyProperty="bizId">
+        insert into uavps_task
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="bizName != null">biz_name,</if>
+            <if test="bizType != null">biz_type,</if>
+            <if test="multiTarget != null">multi_target,</if>
+            <if test="noiseType != null">noise_type,</if>
+            <if test="noiseVariance != null">noise_variance,</if>
+            <if test="noiseMean != null">noise_mean,</if>
+            <if test="platformUavStr != null">platform_uav_str,</if>
+            <if test="fixedMultiTargetFormationStr != null">fixed_multi_target_formation_str,</if>
+            <if test="customizedMultiTargetFormationStr != null">customized_multi_target_formation_str,</if>
+            <if test="status != null">status,</if>
+            <if test="startTime != null">start_time,</if>
+            <if test="endTime != null">end_time,</if>
+            <if test="filePath != null">file_path,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="bizName != null">#{bizName},</if>
+            <if test="bizType != null">#{bizType},</if>
+            <if test="multiTarget != null">#{multiTarget},</if>
+            <if test="noiseType != null">#{noiseType},</if>
+            <if test="noiseVariance != null">#{noiseVariance},</if>
+            <if test="noiseMean != null">#{noiseMean},</if>
+            <if test="platformUavStr != null">#{platformUavStr},</if>
+            <if test="fixedMultiTargetFormationStr != null">#{fixedMultiTargetFormationStr},</if>
+            <if test="customizedMultiTargetFormationStr != null">#{customizedMultiTargetFormationStr},</if>
+            <if test="status != null">#{status},</if>
+            <if test="startTime != null">#{startTime},</if>
+            <if test="endTime != null">#{endTime},</if>
+            <if test="filePath != null">#{filePath},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateUavpsTask" parameterType="UavpsTask">
+        update uavps_task
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="bizName != null">biz_name = #{bizName},</if>
+            <if test="bizType != null">biz_type = #{bizType},</if>
+            <if test="multiTarget != null">multi_target = #{multiTarget},</if>
+            <if test="noiseType != null">noise_type = #{noiseType},</if>
+            <if test="noiseVariance != null">noise_variance = #{noiseVariance},</if>
+            <if test="noiseMean != null">noise_mean = #{noiseMean},</if>
+            <if test="platformUavStr != null">platform_uav_str = #{platformUavStr},</if>
+            <if test="fixedMultiTargetFormationStr != null">fixed_multi_target_formation_str = #{fixedMultiTargetFormationStr},</if>
+            <if test="customizedMultiTargetFormationStr != null">customized_multi_target_formation_str = #{customizedMultiTargetFormationStr},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="startTime != null">start_time = #{startTime},</if>
+            <if test="endTime != null">end_time = #{endTime},</if>
+            <if test="filePath != null">file_path = #{filePath},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where biz_id = #{bizId}
+    </update>
+
+    <delete id="deleteUavpsTaskByBizId" parameterType="Long">
+        delete from uavps_task where biz_id = #{bizId}
+    </delete>
+
+    <delete id="deleteUavpsTaskByBizIds" parameterType="String">
+        delete from uavps_task where biz_id in 
+        <foreach item="bizId" collection="array" open="(" separator="," close=")">
+            #{bizId}
+        </foreach>
+    </delete>
+</mapper>

+ 44 - 0
uavps-web/src/api/system/task.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询任务数据列表
+export function listTask(query) {
+  return request({
+    url: '/system/task/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询任务数据详细
+export function getTask(bizId) {
+  return request({
+    url: '/system/task/' + bizId,
+    method: 'get'
+  })
+}
+
+// 新增任务数据
+export function addTask(data) {
+  return request({
+    url: '/system/task',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改任务数据
+export function updateTask(data) {
+  return request({
+    url: '/system/task',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除任务数据
+export function delTask(bizId) {
+  return request({
+    url: '/system/task/' + bizId,
+    method: 'delete'
+  })
+}

+ 570 - 0
uavps-web/src/views/system/task/index.vue

@@ -0,0 +1,570 @@
+<template>
+  <div class="app-container">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      v-show="showSearch"
+      label-width="68px"
+    >
+      <el-form-item label="任务名称" prop="bizName">
+        <el-input
+          v-model="queryParams.bizName"
+          placeholder="请输入任务名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select
+          v-model="queryParams.status"
+          placeholder="请选择状态"
+          clearable
+        >
+          <el-option
+            v-for="dict in dict.type.uavps_task_status"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="开始时间" prop="startTime">
+        <el-date-picker
+          clearable
+          v-model="queryParams.startTime"
+          type="date"
+          value-format="yyyy-MM-dd"
+          placeholder="请选择开始时间"
+        >
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="结束时间" prop="endTime">
+        <el-date-picker
+          clearable
+          v-model="queryParams.endTime"
+          type="date"
+          value-format="yyyy-MM-dd"
+          placeholder="请选择结束时间"
+        >
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="创建时间">
+        <el-date-picker
+          v-model="daterangeCreateTime"
+          style="width: 240px"
+          value-format="yyyy-MM-dd"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+        ></el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['system:task:add']"
+          >新增</el-button
+        >
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['system:task:edit']"
+          >修改</el-button
+        >
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['system:task:remove']"
+          >删除</el-button
+        >
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['system:task:export']"
+          >导出</el-button
+        >
+      </el-col>
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+
+    <el-table
+      v-loading="loading"
+      :data="taskList"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="业务ID" align="center" prop="bizId" />
+      <el-table-column label="任务名称" align="center" prop="bizName" />
+      <el-table-column label="状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag
+            :options="dict.type.uavps_task_status"
+            :value="scope.row.status"
+          />
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="开始时间"
+        align="center"
+        prop="startTime"
+        width="180"
+      >
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.startTime, "{y}-{m}-{d}") }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="结束时间"
+        align="center"
+        prop="endTime"
+        width="180"
+      >
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.endTime, "{y}-{m}-{d}") }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="创建时间"
+        align="center"
+        prop="createTime"
+        width="180"
+      >
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime, "{y}-{m}-{d}") }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="更新时间"
+        align="center"
+        prop="updateTime"
+        width="180"
+      >
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.updateTime, "{y}-{m}-{d}") }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="操作"
+        align="center"
+        class-name="small-padding fixed-width"
+      >
+        <template slot-scope="scope">
+          <el-button
+            v-hasPermi="['system:task:edit']"
+            size="mini"
+            type="text"
+            icon="el-icon-s-operation"
+            @click="handleRun(scope.row)"
+            >运行</el-button
+          >
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['system:task:edit']"
+            >修改</el-button
+          >
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['system:task:remove']"
+            >删除</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改任务数据对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="任务名称" prop="bizName">
+          <el-input v-model="form.bizName" placeholder="请输入任务名称" />
+        </el-form-item>
+        <el-form-item label="多目标类型" prop="multiTarget">
+          <el-select v-model="form.multiTarget" placeholder="请选择多目标类型">
+            <el-option
+              v-for="dict in dict.type.uavps_target_formation_type"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="噪声类型" prop="noiseType">
+          <el-select v-model="form.noiseType" placeholder="请选择噪声类型">
+            <el-option
+              v-for="dict in dict.type.uavps_task_nose_type"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="噪声方差" prop="noiseVariance">
+          <el-input v-model="form.noiseVariance" placeholder="请输入噪声方差" />
+        </el-form-item>
+        <el-form-item label="噪声均值" prop="noiseMean">
+          <el-input v-model="form.noiseMean" placeholder="请输入噪声均值" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog
+      :title="title"
+      :visible.sync="showTrajectory"
+      @opened="initTrajectory"
+      :before-close="destroyTrajectory"
+      :fullscreen="true"
+      append-to-body
+      destroy-on-close
+    >
+      <div class="container">
+        <div>
+          <el-row type="flex" align="middle" style="height: 40px">
+            <el-col :span="7">
+              <el-button @click="transFormation" type="danger"
+                >转换队形</el-button
+              >
+              <el-button @click="" type="success">回放</el-button>
+            </el-col>
+            <el-col :span="17">
+              <!--              <el-progress v-show="isShow" :percentage="percentage"></el-progress>-->
+            </el-col>
+          </el-row>
+          <el-row>
+            <div ref="pixiContainer" class="pixi-container"></div>
+          </el-row>
+        </div>
+        <!-- <div class="right-board">
+          <div style="float: right">
+            <el-link type="primary" @click="showConfig">显示配置</el-link>
+          </div>
+          <el-divider content-position="left">目标无人机群</el-divider>
+          <li v-for="(item, index) in targetLblAry" :key="index">
+            <div @click="showSprite(item.id)" style="cursor: pointer">
+              <span>编号:&nbsp;&nbsp;</span><label>{{ item.showNo }}</label>
+              <span style="margin-left: 10px" v-if="hideList.includes(item.id)"
+                >( 隐 藏 )</span
+              >
+            </div>
+            <div v-if="configList.includes('经度')">
+              <span>经度:&nbsp;&nbsp;</span><label>{{ item.longitude }}</label>
+            </div>
+            <div v-if="configList.includes('纬度')">
+              <span>纬度:&nbsp;&nbsp;</span><label>{{ item.latitude }}</label>
+            </div>
+            <div v-if="configList.includes('海拔')">
+              <span>海拔:&nbsp;&nbsp;</span><label>{{ item.altitude }}</label>
+            </div>
+            <div v-if="configList.includes('东向速度')">
+              <span>东向速度:&nbsp;&nbsp;</span
+              ><label>{{ item.eastSpeed }}</label>
+            </div>
+            <div v-if="configList.includes('北向速度')">
+              <span>北向速度:&nbsp;&nbsp;</span
+              ><label>{{ item.northSpeed }}</label>
+            </div>
+            <div v-if="configList.includes('天向速度')">
+              <span>天向速度:&nbsp;&nbsp;</span
+              ><label>{{ item.skySpeed }}</label>
+            </div>
+          </li>
+        </div> -->
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listTask,
+  getTask,
+  delTask,
+  addTask,
+  updateTask,
+} from "@/api/system/task";
+
+export default {
+  name: "Task",
+  dicts: [
+    "uavps_task_status",
+    "uavps_target_formation_type",
+    "uavps_task_nose_type",
+  ],
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 任务数据表格数据
+      taskList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 噪声数据文件路径时间范围
+      daterangeCreateTime: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        bizName: null,
+        status: null,
+        startTime: null,
+        endTime: null,
+        createTime: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {},
+      parameterId: 0,
+      showTrajectory: false,
+      webSocket: null,
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询任务数据列表 */
+    getList() {
+      this.loading = true;
+      this.queryParams.params = {};
+      if (null != this.daterangeCreateTime && "" != this.daterangeCreateTime) {
+        this.queryParams.params["beginCreateTime"] =
+          this.daterangeCreateTime[0];
+        this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
+      }
+      listTask(this.queryParams).then((response) => {
+        this.taskList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        bizId: null,
+        bizName: null,
+        bizType: null,
+        multiTarget: null,
+        noiseType: null,
+        noiseVariance: null,
+        noiseMean: null,
+        platformUavStr: null,
+        fixedMultiTargetFormationStr: null,
+        customizedMultiTargetFormationStr: null,
+        status: null,
+        startTime: null,
+        endTime: null,
+        filePath: null,
+        createBy: null,
+        createTime: null,
+        updateBy: null,
+        updateTime: null,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.daterangeCreateTime = [];
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map((item) => item.bizId);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加任务数据";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const bizId = row.bizId || this.ids;
+      getTask(bizId).then((response) => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改任务数据";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          if (this.form.bizId != null) {
+            updateTask(this.form).then((response) => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addTask(this.form).then((response) => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const bizIds = row.bizId || this.ids;
+      this.$modal
+        .confirm('是否确认删除任务数据编号为"' + bizIds + '"的数据项?')
+        .then(function () {
+          return delTask(bizIds);
+        })
+        .then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        })
+        .catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download(
+        "system/task/export",
+        {
+          ...this.queryParams,
+        },
+        `task_${new Date().getTime()}.xlsx`
+      );
+    },
+    handleRun(row) {
+      this.parameterId = row.bizId || this.ids;
+      this.showTrajectory = true;
+      this.title = "飞行轨迹";
+    },
+    initWebSocket() {
+      const wsUri = "ws://127.0.0.1:8080/websocket/message";
+      this.webSocket = new WebSocket(wsUri);
+      const self = this;
+      this.webSocket.onopen = function (event) {
+        self.webSocket.send("RUN:" + self.parameterId);
+        console.log("WebSocket连接成功!");
+      };
+
+      this.webSocket.onmessage = function (event) {
+        self.processMessage(JSON.parse(event.data));
+      };
+
+      this.webSocket.onclose = function (event) {
+        console.log("WebSocket连接断开!");
+      };
+
+      this.webSocket.onerror = function (event) {
+        console.log(
+          "WebSocket连接异常: " +
+            event.code +
+            " " +
+            event.reason +
+            " " +
+            event.wasClean
+        );
+      };
+    },
+    transFormation() {
+      // debugger;
+      let msg = "TRANSFORMATION:" + this.parameterId;
+      console.info("transFormation", msg);
+      this.webSocket.send(msg);
+      // this.pixiApp.stage.removeChildren();
+      // this.clearAllAry();
+    },
+    destroyTrajectory() {
+      if (this.webSocket) {
+        this.webSocket.close();
+      }
+      this.showTrajectory = false;
+    },
+    initTrajectory() {
+      this.initWebSocket();
+    },
+    processMessage(json) {
+      console.info(json);
+    },
+  },
+};
+</script>