张世豪
6 小时以前 8d3989dff1164588d45dbb30506da1a6e1094005
src/zhuye/Shouye.java
@@ -9,9 +9,11 @@
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Point2D;
import chuankou.dellmessage;
import chuankou.sendmessage;
import chuankou.DataListener;
import chuankou.SerialPortService;
import dikuai.Dikuai;
import dikuai.Dikuaiguanli;
@@ -32,11 +34,12 @@
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
// import java.util.function.Consumer;
import chuankou.DataListener;
import java.awt.geom.Point2D;
import publicway.Gpstoxuzuobiao;
import sendMQTT.ControlCommandSender;
import sendMQTT.Server;
import user.Usrdell;
import dikuai.Dikuaiguanli;
import publicway.Fanhuibutton;
import publicway.Gpstoxuzuobiao;
/**
 * 首页界面 - 适配6.5寸竖屏,使用独立的MapRenderer进行绘制
@@ -1782,6 +1785,17 @@
            return;
         }
         
         // 检查路径ID是否匹配
         if (!checkPathIdMatch()) {
            startButtonShowingPause = true;
            statusLabel.setText("待机");
            updateStartButtonAppearance();
            return;
         }
         // 发送开始指令
         sendControlCommand("start");
         statusLabel.setText("作业中");
         if (stopButtonActive) {
            stopButtonActive = false;
@@ -1794,6 +1808,8 @@
         return;
      }
      } else {
         // 发送暂停指令
         sendControlCommand("pause");
         statusLabel.setText("暂停中");
         pauseMowingSession();
      }
@@ -1801,6 +1817,169 @@
   }
   /**
    * 检查路径ID是否匹配
    * @return 如果匹配返回true,否则返回false
    */
   private boolean checkPathIdMatch() {
      Device device = Device.getGecaoji();
      if (device == null) {
         showCustomMessageDialog("无法获取割草机信息,请检查设备连接", "提示");
         return false;
      }
      String savedPathId = device.getPath_id_saved();
      String currentLandNumber = Dikuaiguanli.getCurrentWorkLandNumber();
      if (currentLandNumber == null) {
         showCustomMessageDialog("请先选择作业地块", "提示");
         return false;
      }
      // 如果路径ID不匹配(注意处理null和-1的情况)
      boolean isMatch = savedPathId != null && savedPathId.equals(currentLandNumber);
      if (!isMatch) {
         showPathMismatchDialog(currentLandNumber);
         return false;
      }
      return true;
   }
   /**
    * 显示路径不匹配对话框
    */
   private void showPathMismatchDialog(String landNumber) {
      Window parentWindow = SwingUtilities.getWindowAncestor(this);
      JDialog dialog = new JDialog(parentWindow, "路径不匹配", Dialog.ModalityType.APPLICATION_MODAL);
      dialog.setLayout(new BorderLayout(20, 20));
      dialog.setResizable(false);
      JPanel contentPanel = new JPanel(new BorderLayout(0, 15));
      contentPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 10, 20));
      contentPanel.setBackground(Color.WHITE);
      JLabel messageLabel = new JLabel("<html><div style='text-align: center;'>当前割草机路径与选中地块不一致<br>是否立即发送地块 " + landNumber + " 的路径信息?</div></html>");
      messageLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
      messageLabel.setHorizontalAlignment(SwingConstants.CENTER);
      contentPanel.add(messageLabel, BorderLayout.CENTER);
      JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 0));
      buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
      buttonPanel.setOpaque(false);
      JButton sendButton = buttonset.createStyledButton("立即发送", THEME_COLOR);
      JButton cancelButton = buttonset.createStyledButton("取消", new Color(150, 150, 150));
      sendButton.addActionListener(e -> {
         dialog.dispose();
         sendMowingPathAndCheck(landNumber);
      });
      cancelButton.addActionListener(e -> dialog.dispose());
      buttonPanel.add(sendButton);
      buttonPanel.add(cancelButton);
      contentPanel.add(buttonPanel, BorderLayout.SOUTH);
      dialog.add(contentPanel, BorderLayout.CENTER);
      dialog.pack();
      dialog.setLocationRelativeTo(this);
      dialog.setVisible(true);
   }
   /**
    * 发送割草路径并检查结果
    */
   private void sendMowingPathAndCheck(String expectedLandNumber) {
      // 显示发送中提示
      JDialog progressDialog = new JDialog(SwingUtilities.getWindowAncestor(this), "发送中", Dialog.ModalityType.MODELESS);
      progressDialog.setLayout(new BorderLayout());
      JLabel label = new JLabel("正在发送路径信息...", SwingConstants.CENTER);
      label.setBorder(BorderFactory.createEmptyBorder(20, 40, 20, 40));
      progressDialog.add(label);
      progressDialog.pack();
      progressDialog.setLocationRelativeTo(this);
      progressDialog.setVisible(true);
      // 异步发送
      new Thread(() -> {
         try {
            Server.sendMowingPath();
            // 轮询检查路径ID是否更新
            int maxRetries = 10; // 最多等待10秒
            boolean success = false;
            for (int i = 0; i < maxRetries; i++) {
               Thread.sleep(1000);
               Device device = Device.getGecaoji();
               if (device != null) {
                  // 刷新设备数据
                  device.initFromProperties();
                  String currentPathId = device.getPath_id_saved();
                  if (expectedLandNumber.equals(currentPathId)) {
                     success = true;
                     break;
                  }
               }
            }
            final boolean finalSuccess = success;
            SwingUtilities.invokeLater(() -> {
               progressDialog.dispose();
               if (finalSuccess) {
                  showCustomMessageDialog("路径发送成功!", "提示");
               } else {
                  // 即使超时也提示发送完成,让用户再次尝试开始
                  showCustomMessageDialog("路径发送指令已发出,请稍后重试开始作业", "提示");
               }
            });
         } catch (Exception e) {
            SwingUtilities.invokeLater(() -> {
               progressDialog.dispose();
               showCustomMessageDialog("发送失败: " + e.getMessage(), "错误");
            });
         }
      }).start();
   }
   /**
    * 发送控制指令
    * @param command start/stop/pause/resume
    */
   private void sendControlCommand(String command) {
      new Thread(() -> {
         try {
            String userId = Usrdell.getUserEmail();
            String deviceId = Setsys.getMowerIdValue();
            String msgId = "hxzkcontrol_" + System.currentTimeMillis();
            if (userId == null || deviceId == null) {
               System.err.println("无法发送指令:用户ID或设备ID为空");
               return;
            }
            // 特殊处理:如果是resume指令(即从暂停状态再次点击开始)
            String finalCommand = command;
            if ("start".equals(command) && "暂停中".equals(statusLabel.getText())) {
               finalCommand = "resume";
            }
            ControlCommandSender sender = ControlCommandSender.createDefault();
            sender.sendControlCommand(msgId, userId, deviceId, finalCommand, 0.0, "", 0);
         } catch (Exception e) {
            e.printStackTrace();
            SwingUtilities.invokeLater(() ->
               showCustomMessageDialog("指令发送失败: " + e.getMessage(), "错误"));
         }
      }).start();
   }
   /**
    * 检查割草机是否在当前选中的作业地块边界范围内
    * @return 如果割草机在边界内返回true,否则返回false并显示提示
    */
@@ -1895,6 +2074,8 @@
      stopButtonActive = !stopButtonActive;
      updateStopButtonIcon();
      if (stopButtonActive) {
         // 发送停止指令
         sendControlCommand("stop");
         statusLabel.setText("已结束");
         startButtonShowingPause = false;
         stopMowingSession();