<template>
  <div class="tray-binding-container" ref="container">
    <!-- 头部区域 -->
    <div class="header">
      <div class="back-button" @click="goBack">
        <i class="el-icon-back"></i> 返回托盘列表看板
      </div>
    </div>

    <!-- 托盘ID绑定区域 - 添加悬浮容器 -->
    <div
      class="tray-id-section-wrapper"
      :class="{ 'floating': isFloating }"
      :style="{ width: floatingWidth }"
    >
      <div class="tray-id-section">
        <div class="tray-info">
          <div class="tray-display">
            <div class="tray-label">当前托盘：</div>
            <div class="tray-id">{{ fTrayCode || 'TP-未绑定' }}</div>
          </div>

          <!-- 添加托盘状态 -->
          <div class="tray-status">
            <div class="status-label">托盘状态：</div>
            <el-tag
              :type="trayStatusTagType"
              size="medium"
              class="status-tag-bold"
            >
              <span class="status-text">{{ trayStatusText }}</span>
            </el-tag>
          </div>
        </div>

        <!-- 设备扫描区域 -->
        <!-- 调整点1: 修改扫描区域的显示条件 -->
        <div
          class="scan-section"
          style="align-items: center;"
          v-show="trayStatus !== '1' && trayStatus !== '2' && !(trayStatus === '3' && abnormalCount === 0)"
        >
          <input
            type="text"
            class="scan-input"
            :placeholder="scanPlaceholder"
            v-model="deviceInput"
            @keyup.enter="addDevice"
            ref="deviceInput"
            :disabled="trayStatus === '1' || (trayStatus === '3' && abnormalCount === 0)"
          >
          <div class="status-bar">
            <i class="fas fa-info-circle"></i>
            <!-- 调整点2: 修改状态栏显示逻辑 -->
            <span v-if="trayStatus === '0'">已绑定设备: <span class="filled-count">{{ filledCount }}</span>/72</span>
            <span v-if="trayStatus === '3' && abnormalCount > 0">
              待处理异常设备: <span class="filled-count">{{ abnormalCount }}</span>/{{ initialAbnormalCount }}
            </span>
            <span v-if="trayStatus === '3' && abnormalCount === 0">
              所有设备正常，可进行一键解绑
            </span>
          </div>
        </div>
      </div>
    </div>

    <!-- 设备矩阵容器 -->
    <div class="devices-content-wrapper">
      <!-- 设备矩阵区域 - 可滚动 -->
      <div class="devices-content" ref="devicesContent" :style="{ marginBottom: showControlButtons ? '95px' : '0' }">
        <div class="devices-grid-container">
          <div class="devices-grid">
            <div
              v-for="(device, index) in devices"
              :key="index"
              class="device-cell"
              :class="{
                'active': activeCell === index,
                'empty': !device.motherboardCode,
                'error': isDeviceError(device),
                'duplicate': device.isDuplicate
              }"
              @click="setActiveCell(index)"
              :ref="`deviceCell_${index}`"
            >
              <div class="device-id">
                <div class="device-id">
                  {{ (device.motherboardCode && device.calibrationUnbindStatus === '0') ? device.motherboardCode : '+' }}
                  <!-- 其他图标保持不变 -->
                </div>
                <!-- 添加错误状态图标 -->
                <i v-if="isDeviceError(device)" class="error-icon fas fa-exclamation-circle"></i>
                <!-- 添加重复状态图标 -->
                <i v-if="device.isDuplicate" class="duplicate-icon fas fa-exclamation-triangle"></i>
              </div>
              <div class="position-indicator">
                {{ getPositionLabel(index) }}
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 操作按钮区域 - 固定在设备矩阵容器底部 -->
      <div class="binding-controls-wrapper"
           v-if="showControlButtons">
        <div class="binding-controls">
          <button
            v-if="trayStatus === '0'"
            class="reset-btn"
            @click="resetAll"
          >
            <i class="fas fa-redo"></i> 重置所有
          </button>
          <button
            v-if="trayStatus === '0' || trayStatus === '4'"
            class="bind-btn"
            @click="bindTray"
            :disabled="bindButtonDisabled"
          >
            <i class="fas fa-paper-plane"></i>
            {{ '提交绑定' }}
          </button>
          <!-- 调整点3: 修改一键解绑按钮显示条件 -->
          <button
            v-if="trayStatus === '3' && abnormalCount === 0"
            class="unbind-btn"
            @click="unbindAll"
          >
            <i class="fas fa-unlink"></i> 一键解绑
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {
  batchAdd,
  unbindSingleDevice,
  getAllExcludeUnbindingTimeByTrayId, unbindAllDevice, batchUpdateDeviceCodeAndUnbindingTime
} from "@/api/palletDeviceBinding/binding"
import {resetAll} from "@/api/palletDeviceBinding/binding"
export default {
  name: "TrayBinding",
  props: {
    modbusDeviceData: {
      type: Object,
      default: () => ({})
    }
  },
  watch: {
    modbusDeviceData: {
      immediate: true,
      handler(newVal) {
        this.fTrayId = newVal.fTrayId;
        this.fTrayCode = newVal.fTrayCode;
        this.trayStatus = newVal.fStatus; // 从父组件获取托盘状态
        // 查询托盘是否有绑定的设备数据
        this.getAllBindingData(newVal.fTrayId);
      }
    },
    // 监听输入框内容变化，实现手动输入自动触发
    deviceInput(newVal) {
      // 清除上一次的计时器
      if (this.inputTimer) {
        clearTimeout(this.inputTimer);
      }
      // 输入为空时不触发
      if (!newVal.trim()) return;

      // 500ms内无输入变化，则视为输入完成，自动触发addDevice
      this.inputTimer = setTimeout(() => {
        this.addDevice();
      }, 500); // 可根据需求调整延迟时间（如300ms-1000ms）
    },
    // 监听激活单元格变化，实现自动滚动
    activeCell(newIndex) {
      this.$nextTick(() => {
        this.handleScroll(newIndex);
      });
    },
  },
  beforeDestroy() {
    // 组件销毁时清除计时器，避免内存泄漏
    if (this.inputTimer) {
      clearTimeout(this.inputTimer);
    }
    // 移除滚动监听
    if (this.$refs.devicesContent) {
      this.$refs.devicesContent.removeEventListener('scroll', this.handleScrollEvent);
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.$refs.deviceInput.focus();
      // 添加滚动监听
      if (this.$refs.devicesContent) {
        this.$refs.devicesContent.addEventListener('scroll', this.handleScrollEvent);
      }
    });
  },
  data() {
    return {
      // 托盘ID
      fTrayId: '',
      fTrayCode: '',
      trayInput: '',

      // 托盘状态
      trayStatus: '0', // 0:空闲, 1:运行中, 2:老化完成，3:标定完成

      // 异常设备计数
      abnormalCount: 0,
      initialAbnormalCount: 0,

      // 悬浮状态
      isFloating: false,
      floatingWidth: 'auto',

      // 设备矩阵数据 (8x9 = 72个设备)
      devices: Array(72).fill().map((_, i) => {
        const row = Math.floor(i / 9) + 1; // 1-8行
        const col = (i % 9) + 1; // 1-9列
        let number;

        // 计算属于第几段（0,1,2）
        const segment = Math.floor((row - 1) / 3); // 0:1-3行, 1:4-6行, 2:7-8行

        // 计算段内行号（0,1,2）
        const segmentRow = (row - 1) % 3;

        // 计算当前段的起始数字
        const segmentStart = segment * 27 + 1;

        // 每段内按照一条龙排列
        if (segmentRow % 2 === 0) {
          // 奇数行（第1、4、7行）：从左到右递增
          number = segmentStart + segmentRow * 9 + (col - 1);
        } else {
          // 偶数行（第2、5、8行）：从右到左递增
          number = segmentStart + (segmentRow + 1) * 9 - col;
        }

        return {
          index: i + 1,
          number: number,
          motherboardCode: '',
          row: row,
          col: col,
          isDuplicate: false // 添加重复标记属性
        }
      }),

      // 当前激活的单元格
      activeCell: 0,

      // 设备输入
      deviceInput: '',

      inputTimer: null, // 用于记录输入计时器
    };
  },
  computed: {
    // 计算是否需要显示操作按钮
    showControlButtons() {
      // 当托盘状态为"老化中"(1)或"老化完成"(2)时，不显示操作按钮
      // 调整点4: 在状态3时，只有当异常设备数量为0时才显示操作按钮（一键解绑）
      if (this.trayStatus === '3') {
        return this.abnormalCount === 0;
      }
      return this.trayStatus !== '1' && this.trayStatus !== '2';
    },
    // 计算已填充的设备数量
    filledCount() {
      return this.devices.filter(d => d.motherboardCode).length;
    },

    // 计算绑定按钮是否禁用
    bindButtonDisabled() {
      if (this.trayStatus === '0' || this.trayStatus === '4') {
        return this.filledCount === 0 || !this.fTrayCode;
      } else if (this.trayStatus === '3') {
        return this.abnormalCount > 0;
      }
      return true;
    },

    // 托盘状态标签类型
    trayStatusTagType() {
      const map = {
        '0': 'info',       // 空闲 - 灰色
        '1': 'success',    // 运行 - 绿色
        '2': 'warning',    // 老化完成 - 橙色（较浅）
        '3': 'danger',     // 标检完成 - 红色（更紧急）
        '4': 'primary',    // 已绑定 - 蓝色
      };
      return map[this.trayStatus] || 'info';
    },

    // 托盘状态文本
    trayStatusText() {
      const map = {
        '0': '空闲',
        '1': '老化中',
        '2': '老化完成',
        '3': '标定完成',
        '4': '已绑定'
      };
      return map[this.trayStatus] || '未知状态';
    },

    // 扫描输入框提示语
    scanPlaceholder() {
      return this.trayStatus === '3'
        ? '扫描异常设备条码进行解绑...'
        : '扫描设备条码...';
    }
  },
  methods: {
    // 处理滚动
    handleScroll(cellIndex) {
      if (!this.$refs.devicesContent) return;

      // 计算当前行（每行9个设备）
      const currentRow = Math.floor(cellIndex / 9);

      // 从第二排开始滚动（索引8是第一排最后一个，索引9是第二排第一个）
      if (currentRow >= 1) {
        // 滚动距离：每行90px
        const scrollTop = currentRow * 90;

        // 平滑滚动到指定位置
        this.$refs.devicesContent.scrollTo({
          top: scrollTop,
          behavior: 'smooth'
        });

        // 激活悬浮模式
        if (scrollTop > 50) {
          this.isFloating = true;
        }
      } else {
        // 回到第一排时，关闭悬浮
        this.isFloating = false;
      }
    },

    // 处理滚动事件
    handleScrollEvent() {
      if (this.$refs.devicesContent) {
        const scrollTop = this.$refs.devicesContent.scrollTop;
        this.isFloating = scrollTop > 50;
      }
    },

    isDeviceError(device) {
      // 如果设备已解绑，则不视为错误
      if (!device.motherboardCode || device.calibrationUnbindStatus === '1') return false;

      // 原有的异常判断逻辑保持不变
      return device.deviceStatus === '0' ||
        device.deviceStatus === '5' ||
        device.deviceStatus === '-9999' ||
        (device.realTimeStatus != null && device.realTimeStatus === '0') ||
        (device.calibrationConcentrationStatus != null && device.calibrationConcentrationStatus !== '4') ||
        (device.writeTimeStatus != null && device.writeTimeStatus === '0') ||
        (device.runTimeStatus != null && device.runTimeStatus === '0') ||
        (device.relayStatus != null && device.relayStatus === 0) ||
        (device.pulseStatus != null && device.pulseStatus === 0) ||
        device.moduleStatus === 0 || device.simCardStatus === 0 || device.networkStatus === 0;
    },

    getAllBindingData(trayId) {
      this.devices = [];
      getAllExcludeUnbindingTimeByTrayId(trayId).then(res => {
        if(res.code === 200 && res.data.length > 0) {
          this.devices = res.data.map(device => ({
            ...device,
            isDuplicate: false // 确保每个设备都有isDuplicate属性
          }));

          // 计算初始异常设备数量（标定完成状态）
          if (this.trayStatus === '3') {
            this.abnormalCount = this.devices.filter(d => this.isDeviceError(d)).length;
            this.initialAbnormalCount = this.abnormalCount;
          }

          // 检查重复设备
          this.checkDuplicateDevices();

          const firstDeviceCodeEmptyItem = this.devices.find(item =>
            item.motherboardCode === null ||
            item.motherboardCode === undefined ||
            (typeof item.motherboardCode === 'string' && item.motherboardCode.trim() === '')
          );

          if(firstDeviceCodeEmptyItem !== undefined) {
            // 自动移动到下一个单元格
            if (firstDeviceCodeEmptyItem.index < 72) {
              this.activeCell = firstDeviceCodeEmptyItem.index - 1;
            }
          } else {
            // 如果已经是最后一个，则回到第一个
            this.activeCell = 0;
          }

        } else {
          // 初始化设备矩阵数据 (8x9 = 72个设备)
          this.devices = Array(72).fill().map((_, i) => {
            const row = Math.floor(i / 9) + 1; // 1-8行
            const col = (i % 9) + 1; // 1-9列
            let number;

            // 计算属于第几段（0,1,2）
            const segment = Math.floor((row - 1) / 3); // 0:1-3行, 1:4-6行, 2:7-8行

            // 计算段内行号（0,1,2）
            const segmentRow = (row - 1) % 3;

            // 计算当前段的起始数字
            const segmentStart = segment * 27 + 1;

            // 每段内按照一条龙排列
            if (segmentRow % 2 === 0) {
              // 奇数行（第1、4、7行）：从左到右递增
              number = segmentStart + segmentRow * 9 + (col - 1);
            } else {
              // 偶数行（第2、5、8行）：从右到左递增
              number = segmentStart + (segmentRow + 1) * 9 - col;
            }

            return {
              trayId: this.fTrayId,
              index: i + 1,
              number: number,
              motherboardCode: '',
              row: row,
              col: col,
              calibrationUnbindStatus: '0', // 默认未解绑
              isDuplicate: false // 添加重复标记属性
            }
          })
        }
      })
    },

    // 返回托盘列表看板
    goBack() {
      this.$emit('go-back',1);
    },

    // 设置当前激活的单元格
    setActiveCell(index) {
      this.activeCell = index;
      this.$nextTick(() => {
        this.$refs.deviceInput.focus();
      });
    },

    // 添加设备到当前激活单元格
    addDevice() {
      // 清除计时器（避免重复触发）
      if (this.inputTimer) {
        clearTimeout(this.inputTimer);
        this.inputTimer = null;
      }

      // 原有逻辑：如果输入为空则不处理
      if (!this.deviceInput.trim()) return;

      if (this.deviceInput) {
        // 标定完成状态下的特殊处理 - 改为解绑操作
        if (this.trayStatus === '3') {
          // 检查扫描的设备是否存在
          const deviceIndex = this.devices.findIndex(
            d => d.motherboardCode === this.deviceInput
          );

          if (deviceIndex !== -1) {
            // 调整点5: 在标定完成状态下，只有异常设备才允许解绑
            const device = this.devices[deviceIndex];
            if (!this.isDeviceError(device)) {
              // 网络请求失败或业务逻辑失败时，播放失败音效
              this.$sound.playScanError();
              // 正常设备不允许解绑
              this.$message.warning(`设备 ${this.deviceInput} 状态正常，不能解绑`);
              this.deviceInput = '';
              return;
            }

            // 找到设备，直接解绑（不弹确认对话框）
            this.executeUnbind(deviceIndex);
          } else {
            // 网络请求失败或业务逻辑失败时，播放失败音效
            this.$sound.playScanError();
            // 设备不存在提示
            this.$message.warning(`设备 ${this.deviceInput} 不存在或未绑定`);
          }
        } else {
          // 空闲状态下的正常处理
          const trimmedInput = this.deviceInput.trim();

          // 检查设备号是否已存在（排除当前单元格自身）
          const existingIndex = this.devices.findIndex(
            (d, idx) => idx !== this.activeCell && d.motherboardCode === trimmedInput
          );

          if (existingIndex !== -1) {
            // 网络请求失败或业务逻辑失败时，播放失败音效
            this.$sound.playScanError();
            // 发现重复设备号
            this.$message.error({
              message: `设备 ${trimmedInput} 已存在于位置 ${existingIndex + 1} 中，请勿重复添加`,
              duration: 3000
            });

            // 高亮显示重复的单元格
            this.highlightDuplicateCell(existingIndex);

            // 清空输入框但不执行添加操作
            this.deviceInput = '';
            return;
          }

          // 如果没有重复，则正常添加设备
          this.devices[this.activeCell].motherboardCode = trimmedInput;
          this.devices[this.activeCell].calibrationUnbindStatus = '0';

          // 添加后重新检查重复状态
          this.checkDuplicateDevices();

          // 自动移动到下一个单元格
          if (this.activeCell < 71) {
            this.activeCell++;
          } else {
            this.activeCell = 0;
          }
        }

        this.deviceInput = '';
      }
    },

    // 检查所有设备的重复状态
    checkDuplicateDevices() {
      const deviceCodeMap = {};

      // 统计每个设备码出现的次数
      this.devices.forEach(device => {
        if (device.motherboardCode && device.motherboardCode.trim()) {
          deviceCodeMap[device.motherboardCode] = (deviceCodeMap[device.motherboardCode] || 0) + 1;
        }
      });

      // 标记重复的设备
      this.devices.forEach(device => {
        if (device.motherboardCode && device.motherboardCode.trim()) {
          device.isDuplicate = deviceCodeMap[device.motherboardCode] > 1;
        } else {
          device.isDuplicate = false;
        }
      });
    },

    // 高亮显示重复的单元格
    highlightDuplicateCell(index) {
      // 先清除之前可能存在的重复高亮
      this.clearDuplicateHighlights();

      // 为重复的单元格添加高亮标记
      this.devices[index].isDuplicate = true;

      // 设置一个定时器，2秒后清除高亮
      setTimeout(() => {
        this.clearDuplicateHighlights();
        // 重新检查重复状态
        this.checkDuplicateDevices();
      }, 2000);
    },

    // 清除所有重复高亮标记
    clearDuplicateHighlights() {
      this.devices.forEach(device => {
        if (device.isDuplicate) {
          device.isDuplicate = false;
        }
      });
    },

    // 执行解绑操作（不再需要确认对话框）
    executeUnbind(deviceIndex) {
      const device = this.devices[deviceIndex];

      // 调用解绑方法，传递设备信息和palletDeviceBindingId
      let palletDeviceBinding = {
        motherboardCode: device.motherboardCode,
        palletDeviceBindingId: device.palletDeviceBindingId,
        calibrationUnbindStatus: '1' // 标记为解绑
      }
      unbindSingleDevice(palletDeviceBinding).then(res => {
        if (res.code === 200) {
          // 解绑成功后的处理
          const wasErrorDevice = this.isDeviceError(this.devices[deviceIndex]);

          this.devices[deviceIndex].motherboardCode = '';
          this.devices[deviceIndex].calibrationUnbindStatus = '1'; // 标记为已解绑

          // 清除重复标记
          this.devices[deviceIndex].isDuplicate = false;

          // 重新检查重复状态
          this.checkDuplicateDevices();

          // 如果是异常设备，减少异常计数（使用完整的异常判断逻辑）
          if (wasErrorDevice) {
            this.abnormalCount--;

            // 调整点6: 当异常设备全部解绑完成后，输入框会自动变为readonly（通过disabled属性控制）
            if (this.abnormalCount === 0) {
              this.$message.success('所有异常设备已解绑完成，可进行一键解绑');
            }
          }

          this.$message.success(`设备 ${device.motherboardCode} 解绑成功`);
        } else {
          this.$message.error("解绑失败");
        }
      })
    },

    // 获取位置标签 (行-列)
    getPositionLabel(index) {
      const row = Math.floor(index / 9) + 1;
      const col = (index % 9) + 1;
      return `${row}-${col}`;
    },

    // 一键解绑所有设备
// 一键解绑所有设备
    unbindAll() {
      this.$confirm('确定要解绑当前托盘下所有设备吗?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'error'
      }).then(() => {
        // 创建loading实例
        const loadingInstance = this.$loading({
          lock: true,
          text: '正在解绑所有设备...',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });

        unbindAllDevice(this.fTrayId).then(res => {
          // 关闭loading
          loadingInstance.close();

          if (res.code === 200) {
            // 解绑成功后重置设备矩阵
            this.devices = this.devices.map(d => ({
              ...d,
              motherboardCode: '',
              deviceStatus: '1',
              isDuplicate: false
            }));
            this.abnormalCount = this.devices.length; // 重置异常计数为总设备数
            this.initialAbnormalCount = this.abnormalCount;
            this.deviceInput = '';
            this.activeCell = 0;
            this.trayStatus = '0';
            this.$message.success("一键解绑成功");
          } else {
            this.$message.error("解绑失败");
          }
        }).catch(error => {
          // 关闭loading
          loadingInstance.close();
          this.$message.error("解绑请求失败: " + error.message);
          console.error("一键解绑失败:", error);
        });
      }).catch(() => {
        // 用户点击取消，不做任何操作
      });
    },

    // 绑定托盘
    bindTray: function () {
      if (this.trayStatus === '0' || this.trayStatus === '4') {
        // 空闲状态 - 绑定设备
        const palletDeviceBindingId = this.devices[0].palletDeviceBindingId;
        if (this.filledCount > 0) {
          if(palletDeviceBindingId == null) {
            batchAdd(this.devices).then(res => {
              if (res.code === 200) {
                this.devices = res.data;
                this.trayStatus = '4';
                this.msgSuccess("绑定成功");
              } else {
                this.msgError("绑定失败");
              }
            })
          } else {
            batchUpdateDeviceCodeAndUnbindingTime(this.devices).then(res => {
              if (res.code === 200) {
                this.msgSuccess("绑定成功");
                if(this.trayStatus === '0') {
                  this.trayStatus = '4';
                }
              } else {
                this.msgError("绑定失败");
              }
            })
          }
        }
      } else if (this.trayStatus === '3') {
        // 标定完成状态 - 不再需要提交修复，改为解绑操作
        // 这里可以保留或移除，根据实际需求
      }
    },

    // 重置所有数据
    resetAll() {
      this.$confirm('确定要重置所有数据吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        resetAll(this.fTrayId).then(res => {
          if (res.code === 200) {
            this.deviceInput = '';
            // 重置时也清除重复标记
            this.devices = this.devices.map(d => ({
              ...d,
              motherboardCode: '',
              isDuplicate: false
            }));
            this.activeCell = 0;
            this.$nextTick(() => {
              this.$refs.deviceInput.focus();
            });
            this.msgSuccess("已重置");
          } else {
            this.msgError(res.msg);
          }
        })
      }).catch(() => {
      });
    }
  },
};
</script>

<style scoped>
/* 修改容器结构 */
.tray-binding-container {
  width: 100%;
  height: 100%;
  background: rgba(10, 20, 40, 0.85);
  border-radius: 20px;
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  border: 1px solid rgba(100, 180, 255, 0.3);
  padding: 10px;
  position: relative;
  display: flex;
  flex-direction: column;
}

/* 添加悬浮包装器样式 */
.tray-id-section-wrapper {
  width: calc(100% - 20px); /* 减去左右 margin */
  margin-left: 10px;
  margin-right: 10px;
  transition: all 0.3s ease;
  z-index: 10;
  position: sticky;
  flex-shrink: 0;
  box-sizing: border-box;
}

.tray-id-section-wrapper.floating {
  z-index: 1000;
  width: calc(100% - 20px); /* 悬浮状态保持相同宽度 */
  background: rgba(10, 20, 40, 0.95);
  border-radius: 0 0 15px 15px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
  border: 1px solid rgba(64, 158, 255, 0.4);
  border-top: none;
  padding: 15px;
  margin-left: 10px;
  margin-right: 10px; /* 悬浮状态也要保持对称边距 */
}

/* 设备矩阵包装器 - 包含设备矩阵和操作按钮 */
.devices-content-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  margin-top: 15px;
  position: relative;
  overflow: hidden; /* 隐藏超出部分 */
  margin-left: 10px;
  margin-right: 10px; /* 添加右边距，与左边距对称 */
  box-sizing: border-box; /* 确保内边距包含在宽度内 */
}

/* 设备内容区域 - 可滚动 */
.devices-content {
  overflow-y: auto;
  overflow-x: hidden;
  position: relative;
  flex: 1; /* 占据剩余空间 */
  border-radius: 15px;
  background: rgba(0, 40, 80, 0.3);
  border: 1px solid rgba(64, 158, 255, 0.4);
  box-sizing: border-box; /* 确保内边距包含在宽度内 */

  /* 自定义滚动条样式 */
  scrollbar-width: thin; /* Firefox */
  scrollbar-color: rgba(64, 158, 255, 0.6) rgba(0, 40, 80, 0.3); /* Firefox */
}

/* Chrome, Edge, Safari 滚动条样式 */
.devices-content::-webkit-scrollbar {
  width: 10px; /* 滚动条宽度 */
}

.devices-content::-webkit-scrollbar-track {
  background: rgba(0, 40, 80, 0.3); /* 轨道背景色 - 与设备矩阵背景一致 */
  border-radius: 10px; /* 轨道圆角 */
  margin: 5px 0; /* 轨道上下边距 */
}

.devices-content::-webkit-scrollbar-thumb {
  background: rgba(64, 158, 255, 0.6); /* 滑块背景色 */
  border-radius: 10px; /* 滑块圆角 */
  border: 2px solid rgba(0, 40, 80, 0.3); /* 滑块边框，与轨道背景融合 */
  background-clip: padding-box; /* 背景延伸到边框内边距 */
}

.devices-content::-webkit-scrollbar-thumb:hover {
  background: rgba(64, 158, 255, 0.8); /* 鼠标悬停时滑块颜色 */
}

/* 操作按钮包装器 */
.binding-controls-wrapper {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 50;
  background: linear-gradient(to bottom, transparent, rgba(10, 20, 40, 0.9) 30%);
  padding: 5px 0;
  pointer-events: none; /* 让点击穿透到下面的内容 */
  box-sizing: border-box; /* 确保内边距包含在宽度内 */
}

/* 操作按钮区域 */
.binding-controls {
  display: flex;
  justify-content: center;
  gap: 30px;
  pointer-events: auto; /* 恢复按钮的点击事件 */
  padding: 5px 15px;
  background: rgba(0, 40, 80, 0.8);
  border-radius: 15px;
  border: 1px solid rgba(64, 158, 255, 0.4);
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
  box-sizing: border-box; /* 确保内边距包含在宽度内 */
}

/* 调整托盘信息区域间距 */
.tray-info {
  display: flex;
  flex-direction: column;
  gap: 15px;
  min-width: 300px;
}

.tray-status {
  display: flex;
  align-items: center;
  gap: 10px;
}

.status-label {
  font-size: 1.1rem;
  color: #64c8ff;
  font-weight: bold;
}

/* 其他样式保持不变 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.header {
  text-align: right;
  position: relative;
  flex-shrink: 0; /* 防止收缩 */
  padding: 0 10px; /* 对齐内边距 */
}

.back-button {
  cursor: pointer;
  margin-bottom: 20px;
  width: 200px;
  color: #409EFF;
  display: inline-flex;
  align-items: center;
  transition: all 0.3s;
  padding: 8px 15px;
  background: rgba(0, 40, 80, 0.4);
  border-radius: 8px;
  font-size: 1.1rem;
}

.back-button:hover {
  color: #66b1ff;
  background: rgba(0, 60, 120, 0.6);
  transform: translateX(-5px);
}

.tray-id-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 30px;
  background: rgba(0, 40, 80, 0.3);
  border-radius: 15px;
  padding: 10px;
  border: 1px solid rgba(64, 158, 255, 0.4);
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
  transition: all 0.3s ease;
  box-sizing: border-box; /* 确保内边距包含在宽度内 */
}

.tray-display {
  display: flex;
  align-items: center;
  gap: 20px;
  min-width: 300px;
}

.tray-label {
  font-size: 1.4rem;
  color: #64c8ff;
  font-weight: bold;
}

.tray-id {
  font-size: 2.2rem;
  font-weight: bold;
  letter-spacing: 3px;
  background: linear-gradient(to right, #64c8ff, #3a7bd5);
  -webkit-background-clip: text;
  color: transparent;
  text-align: center;
}

.scan-section {
  display: flex;
  flex-direction: column;
  gap: 15px;
  min-width: 400px;
}

.scan-input {
  background: rgba(0, 30, 60, 0.5);
  border: 2px solid #409EFF;
  border-radius: 50px;
  padding: 15px 25px;
  color: white;
  font-size: 1.2rem;
  width: 100%;
  transition: all 0.3s;
}

.scan-input:focus {
  outline: none;
  border-color: #64c8ff;
  box-shadow: 0 0 15px rgba(100, 200, 255, 0.5);
}

.status-bar {
  text-align: center;
  padding: 15px;
  background: rgba(0, 30, 60, 0.5);
  border-radius: 10px;
  font-size: 1.2rem;
  color: #64ffda;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 15px;
}

.filled-count {
  font-weight: bold;
  color: #64c8ff;
  font-size: 1.4rem;
}

.devices-grid-container {
  padding: 25px;
}

.grid-title {
  text-align: center;
  font-size: 1.8rem;
  color: #64ffda;
  margin-bottom: 25px;
  text-shadow: 0 0 10px rgba(100, 255, 218, 0.3);
}

.devices-grid {
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  gap: 15px;
  margin: 0 auto;
  max-width: 100%;
}

/* 长方形设备单元格样式 */
.device-cell {
  background: rgba(30, 60, 100, 0.4);
  border: 2px solid rgba(64, 158, 255, 0.5);
  border-radius: 8px;
  height: 80px; /* 高度固定 */
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  transition: all 0.3s;
  position: relative;
  overflow: hidden;
  padding: 5px;
}

.device-cell:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 15px rgba(0, 0, 0, 0.3);
  border-color: #64c8ff;
  background: rgba(40, 80, 140, 0.5);
}

.device-cell.active {
  border-color: #64ffda;
  background: rgba(100, 255, 218, 0.15);
  box-shadow: 0 0 15px rgba(100, 255, 218, 0.4);
  transform: scale(1.05);
}

.device-id {
  font-size: 0.85rem;
  font-weight: bold;
  color: #fff;
  text-align: center;
  word-break: break-all;
  width: 100%;
  padding: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  max-height: 40px;
  position: relative;
}

.device-cell.empty .device-id {
  color: #a0d2ff;
  font-size: 1.8rem;
  opacity: 0.7;
}

.position-indicator {
  position: absolute;
  bottom: 5px;
  right: 5px;
  font-size: 0.7rem;
  color: rgba(255, 255, 255, 0.6);
}

.bind-btn {
  background: linear-gradient(to right, #11998e, #38ef7d);
  color: white;
  border: none;
  padding: 18px 45px;
  font-size: 1.4rem;
  font-weight: bold;
  border-radius: 50px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 15px;
  transition: all 0.3s;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

.bind-btn:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 20px rgba(17, 153, 142, 0.5);
}

.bind-btn:disabled {
  background: linear-gradient(to right, #555, #777);
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.reset-btn {
  background: linear-gradient(to right, #ff416c, #ff4b2b);
  color: white;
  border: none;
  padding: 18px 45px;
  font-size: 1.4rem;
  font-weight: bold;
  border-radius: 50px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 15px;
  transition: all 0.3s;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

.reset-btn:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 20px rgba(255, 65, 108, 0.5);
}

.scanner-icon {
  color: #64ffda;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { opacity: 0.6; }
  50% { opacity: 1; }
  100% { opacity: 0.6; }
}

.highlight {
  background: rgba(100, 255, 218, 0.2);
  padding: 2px 5px;
  border-radius: 4px;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .devices-grid {
    grid-template-columns: repeat(6, 1fr);
  }
}

@media (max-width: 900px) {
  .devices-grid {
    grid-template-columns: repeat(4, 1fr);
  }

  .tray-id-section {
    flex-direction: column;
    align-items: stretch;
  }

  .tray-display, .scan-section {
    min-width: 100%;
  }

  .binding-controls {
    flex-direction: column;
    align-items: center;
    gap: 15px;
  }

  .bind-btn, .reset-btn, .unbind-btn {
    padding: 15px 30px;
    font-size: 1.2rem;
    width: 80%;
    justify-content: center;
  }
}

@media (max-width: 600px) {
  .devices-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .tray-display {
    flex-direction: column;
    text-align: center;
  }

  .bind-btn, .reset-btn, .unbind-btn {
    padding: 12px 25px;
    font-size: 1.1rem;
    width: 90%;
  }
}

.matrix-info {
  text-align: center;
  margin-top: 15px;
  color: #64c8ff;
  font-size: 1.1rem;
}

/* 设备单元格错误状态样式 */
.device-cell.error {
  border-color: #ff4d4f !important;
  box-shadow: 0 0 8px rgba(255, 77, 79, 0.5);
  position: relative;
  overflow: visible;
}

.device-cell.error::after {
  content: '';
  position: absolute;
  top: -3px;
  left: -3px;
  right: -3px;
  bottom: -3px;
  border: 2px solid #ff4d4f;
  border-radius: 8px;
  animation: pulseError 1.5s infinite;
  z-index: 1;
}

@keyframes pulseError {
  0% { opacity: 0.8; }
  50% { opacity: 0.3; }
  100% { opacity: 0.8; }
}

.error-icon {
  position: absolute;
  top: -8px;
  right: -8px;
  color: #ff4d4f;
  font-size: 16px;
  background: rgba(10, 20, 40, 0.9);
  border-radius: 50%;
  z-index: 2;
  animation: pulseIcon 1.5s infinite;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}

@keyframes pulseIcon {
  0% { transform: scale(1); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

/* 设备单元格重复状态样式 */
.device-cell.duplicate {
  border-color: #ff9800 !important;
  box-shadow: 0 0 10px rgba(255, 152, 0, 0.6) !important;
  background: rgba(255, 152, 0, 0.1) !important;
}

/* 重复状态图标 */
.duplicate-icon {
  position: absolute;
  top: -8px;
  left: -8px;
  color: #ff9800;
  font-size: 16px;
  background: rgba(10, 20, 40, 0.9);
  border-radius: 50%;
  z-index: 2;
  animation: pulseDuplicate 1s infinite;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}

@keyframes pulseDuplicate {
  0% { transform: scale(1); color: #ff9800; }
  50% { transform: scale(1.2); color: #ff5722; }
  100% { transform: scale(1); color: #ff9800; }
}

/* 调整设备ID显示区域，为重复图标留出空间 */
.device-id {
  position: relative;
  padding-top: 5px;
  padding-right: 15px;
  padding-left: 15px; /* 增加左侧内边距，防止文字与图标重叠 */
}

/* 一键解绑按钮样式 */
.unbind-btn {
  background: linear-gradient(to right, #9d4edd, #7b2cbf);
  color: white;
  border: none;
  padding: 18px 45px;
  font-size: 1.4rem;
  font-weight: bold;
  border-radius: 50px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 15px;
  transition: all 0.3s;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

.unbind-btn:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 20px rgba(157, 78, 221, 0.5);
}

/* 托盘状态区域 */
.tray-status {
  display: flex;
  align-items: center;
  gap: 10px;
}

.status-label {
  font-size: 1.1rem;
  color: #64c8ff;
  font-weight: bold;
}

/* 状态标签样式优化 */
.status-tag-bold {
  font-weight: 700 !important; /* 加粗 */
  letter-spacing: 0.5px; /* 字间距 */
}

.status-text {
  font-size: 14px; /* 适当调大字体 */
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); /* 文字阴影增强可读性 */
  padding: 0 2px; /* 添加内边距 */
}
</style>
