liulijun
21 小时以前 5270308151082506e0e6df2c72d278d2976ec860
ÏîÄ¿´úÂë/WCS/WCSClient/src/views/LineComponent.vue
@@ -1,17 +1,9 @@
<template>
  <div>
    <el-row>
      <template v-for="item in 32" :key="item">
        <el-col :span="0.9">
          <span class="image-text"></span>
          <img src="../../public/货架.jpeg" />
        </el-col>
      </template>
    </el-row>
    <el-row style="padding-bottom: 5px;">
      <template v-for="item in 32" :key="item">
        <el-col :span="0.9">
          <span class="image-text"></span>
      <template v-for="item in columnCount" :key="item">
        <el-col :span="columnWidth">
          <span class="image-text">{{ 91-item }}</span>
          <img src="../../public/货架.jpeg" />
        </el-col>
      </template>
@@ -19,146 +11,57 @@
  </div>
  <div class="line-container">
    <div class="line"></div>
    <!-- <div class="dot" :style="{ right: dotPosition + 'px' }" ref="childDot" @click="mouseClick"></div> -->
    <div :class="update()"
      :style="{ transform: `translateX(${StackerCrane.CurrentColumn < 33 ? StackerCrane.CurrentColumn * 30 - 59 : 0}px)` }"
    <div :class="update()" :style="{ transform: `translateX(${calculateDotPosition()}px)` }"
      ref="childDot" @click="mouseClick"></div>
  </div>
  <div>
    <el-row style="padding-top: 5px;">
      <template v-for="item in 32" :key="item">
        <el-col :span="0.9">
          <span class="image-text"></span>
      <template v-for="item in columnCount" :key="item">
        <el-col :span="columnWidth">
          <span class="image-text">{{ 91-item }}</span>
          <img src="../../public/货架.jpeg" />
        </el-col>
      </template>
    </el-row>
    <el-row style="padding-bottom: 5px;">
      <template v-for="item in 32" :key="item">
        <el-col :span="0.9">
          <span class="image-text"></span>
          <img src="../../public/货架.jpeg" />
        </el-col>
      </template>
      <div style="margin-top: 60px;"></div>
    </el-row>
  </div>
  <el-dialog v-model="dialogVisible" title="堆垛机信息查看" :before-close="handleClose">
    <el-form ref="$form" :model="StackerCrane" label-position="left" label-width="120px" size="medium">
      <el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
        <el-col :span="12" :offset="0" :push="0" :pull="0" tag="div">
          <el-form-item label="设备编号:">
            <j-el-description :value="StackerCrane.DeviceName" type="primary" ellipsis></j-el-description>
          </el-form-item>
        </el-col>
        <el-col :span="12" :offset="0" :push="0" :pull="0" tag="div">
          <el-form-item label="设备状态:">
            <j-el-description :value="StackerCrane.Fault" type="primary" ellipsis></j-el-description>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
        <el-col :span="12" :offset="0" :push="0" :pull="0" tag="div">
          <el-form-item label="工作模式:">
            <j-el-description :value="StackerCrane.Automatic" type="primary" ellipsis></j-el-description>
          </el-form-item>
        </el-col>
        <el-col :span="12" :offset="0" :push="0" :pull="0" tag="div">
          <el-form-item label="任务号:">
            <j-el-description :value="StackerCrane.CurrentTaskNum" type="primary" ellipsis></j-el-description>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20" type="flex" justify="start" align="top" tag="div" style="margin-bottom: 10px;">
        <el-col :span="12" :offset="0" :push="0" :pull="0" tag="div">
          <el-form-item label="作业状态:">
            <j-el-description :value="StackerCrane.Running" type="primary" ellipsis></j-el-description>
          </el-form-item>
        </el-col>
        <el-col :span="12" :offset="0" :push="0" :pull="0" tag="div">
          <el-form-item label="当前行列层:">
            <j-el-description
              :value="StackerCrane.CurrentRow + '-' + StackerCrane.CurrentLayer + '-' + StackerCrane.CurrentColumn "
              type="primary" ellipsis></j-el-description>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20" type="flex" justify="start" align="top" tag="div" style="margin-bottom: 10px;">
        <el-col :span="24" :offset="0" :push="0" :pull="0" tag="div">
          <el-form-item label="报警信息:">
            <j-el-description :value="StackerCrane.StackerAlarm" type="primary" ellipsis></j-el-description>
          </el-form-item>
        </el-col>
      </el-row>
      <el-divider />
      <h4 style="margin-bottom: 20px;">手动操作</h4>
      <el-form ref="form" :model="form" label-width="90px">
        <el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
          <el-col :span="16" :offset="0" :push="0" :pull="0" tag="div">
            <el-form-item label="任务命令"  prop="TargetAddress">
              <el-select size="large" v-model="form.TaskType" placeholder="请选择任务命令">
                <el-option label="入库" value="17" />
                <el-option label="出库" value="18" />
                <el-option label="移库" value="20" />
                <el-option label="取货" value="24" />
                <el-option label="放货" value="48" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
          <el-col :span="16" :offset="0" :push="0" :pull="0" tag="div">
            <el-form-item label="起点行列层:">
              <el-input size="large" v-model="form.SourceAddress" style="width: 800px" placeholder="请输入起点行列层" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
          <el-col :span="16" :offset="0" :push="0" :pull="0" tag="div">
            <el-form-item label="终点行列层:">
              <el-input size="large" v-model="form.TargetAddress" style="width: 800px" placeholder="请输入终点行列层" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <el-divider />
      <el-row :gutter="20" type="flex" justify="start" align="top" tag="div">
        <el-col :span="5" :offset="0" :push="0" :pull="0" tag="div">
          <el-button type="primary" size="small" plain @click="start">
            <i class="el-icon-check">启动</i>
          </el-button>
        </el-col>
        <el-col :span="5" :offset="0" :push="0" :pull="0" tag="div">
          <el-button type="warning" size="small" plain @click="reset">
            <i class="el-icon-check">复位</i>
          </el-button>
        </el-col>
        <el-col :span="5" :offset="0" :push="0" :pull="0" tag="div">
          <el-button type="danger" size="small" plain @click="disconnected">
            <i class="el-icon-check">中断</i>
          </el-button>
        </el-col>
        <el-col :span="5" :offset="0" :push="0" :pull="0" tag="div">
          <el-button type="danger" size="small" plain @click="emergencyStop">
            <i class="el-icon-check">急停</i>
          </el-button>
        </el-col>
        <el-col :span="4" :offset="0" :push="0" :pull="0" tag="div">
          <el-button type="danger" size="small" plain @click="StackerRecall">
            <i class="el-icon-check">召回</i>
          </el-button>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="dialogVisible = false">
          ç¡®è®¤
        </el-button>
  <el-dialog v-model="dialogVisible" :before-close="handleClose" width="520px" class="modern-dialog">
    <div class="dialog-header">
      <h3 class="dialog-title">堆垛机信息</h3>
    </div>
    <div class="dialog-content">
      <div class="info-list">
        <div class="info-item">
          <span class="item-label">设备编号</span>
          <span class="item-value">{{ yL_DB.R_PP_Status || '无' }}</span>
        </div>
        <div class="info-item">
          <span class="item-label">设备状态</span>
          <span :class="['item-value', statusClass]">{{ yL_DB.YL_Status || '无' }}</span>
        </div>
        <div class="info-item">
          <span class="item-label">工作模式</span>
          <span :class="['item-value', autoStatusClass]">{{ yL_DB.YL_AutoStatus || '无' }}</span>
        </div>
        <div class="info-item">
          <span class="item-label">任务号</span>
          <span class="item-value">{{ yL_DB.YL_TaskNum || '无' }}</span>
        </div>
        <div class="info-item">
          <span class="item-label">作业状态</span>
          <span class="item-value">{{ yL_DB.YL_WorkStatus || '无' }}</span>
        </div>
        <div class="info-item">
          <span class="item-label">当前行列层</span>
          <span class="item-value">{{ yL_DB.YL_Row + '-' + yL_DB.YL_Column + '-' + yL_DB.YL_Layer || '无' }}</span>
        </div>
        <div class="info-item">
          <span class="item-label">报警信息</span>
          <span class="item-value">{{ yL_DB.StackerAlarm || '无' }}</span>
        </div>
      </div>
    </template>
    </div>
  </el-dialog>
</template>
@@ -171,20 +74,45 @@
  },
  data() {
    return {
      YLDBMap: {
        YL_Status: {
          0: "不在线",
          1: "在线",
          2: "急停",
          3: "未知",
        },
        YL_AutoStatus: {
          1: "半自动",
          2: "单步",
          3: "自动",
          4: "手动",
          5: "脱机",
        },
        YL_WorkStatus: {
          1: "待命",
          2: "取货完成",
          3: "取货中",
          5: "放货中",
          6: "任务执行错误",
          7: "未知",
          9: "任务完成",
        },
      },
      x: 0, // åˆå§‹x值
      url: "api/Equipment/GetStackerInfoByNo",
      dialogVisible: false,
      StackerCrane: {
        Automatic: "",
        Fault: "",
        CurrentLayer: "1",
        CurrentRow: "1",
        CurrentColumn: "1",
        CurrentTaskNum: "",
        Running: "",
        DeviceName: "",
        DeviceCode: "",
        StackerAlarm:"",
      timer1: null,
      yL_DB: {
        R_PP_Status: "",
        YL_Status: "",
        YL_AutoStatus: "",
        YL_TaskNum: "",
        YL_WorkStatus: "",
        YL_WorkType: "",
        YL_Row: "",
        YL_Column: "",
        YL_Layer: "",
        StackerAlarm: "",
        CurrentColumn: "1"
      },
      form: {
        TaskType: "",
@@ -194,6 +122,7 @@
      },
    };
  },
  props: {
    equipNo: {
      type: String,
@@ -204,33 +133,194 @@
    dotPosition() {
      return this.x;
    },
    // åˆ—数:原料库90列
    columnCount() {
      return 90;
    },
    // åˆ—宽:根据90列计算
    columnWidth() {
      return 24 / 90;
    },
    // æ¯åˆ—的实际宽度(像素)
    pixelPerColumn() {
      return 30;
    },
    // ä»“库最大列数
    maxColumn() {
      return 90;
    },
    // è®¾å¤‡çŠ¶æ€æ–‡å­—é¢œè‰²
    statusClass() {
      const status = this.yL_DB.YL_Status;
      if (status === '不在线') {
        return 'status-red';
      } else if (status === '在线') {
        return 'status-green';
      }
      return '';
    },
    // å·¥ä½œæ¨¡å¼æ–‡å­—颜色
    autoStatusClass() {
      const status = this.yL_DB.YL_AutoStatus;
      if (status === '自动' || status === '半自动') {
        return 'status-green';
      } else if (status === '手动') {
        return 'status-blue';
      } else if (status === '脱机') {
        return 'status-red';
      }
      return '';
    }
  },
  mounted() {
    this.moveDot(this.x);
    // åˆå§‹åŒ–时传递空对象,避免类型不匹配错误
    this.moveDot({});
    // å¯åŠ¨å®šæ—¶å™¨ï¼Œæ¯ç§’æ›´æ–°ä¸€æ¬¡æ•°æ®
    this.timer1 = setInterval(() => {
      this.updateData();
    }, 1000);
  },
  beforeUnmount() {
    // æ¸…除定时器
    if (this.timer1) {
      clearInterval(this.timer1);
      this.timer1 = null;
    }
  },
  watch: {
    '$root.stackerData': {
      handler() {
        this.updateData();
      },
      deep: true
    }
  },
  methods: {
    updateData() {
      const equipNoStr = String(this.equipNo);
      if (this.$root.stackerData && this.$root.stackerData[equipNoStr]) {
        const stackerData = this.$root.stackerData[equipNoStr];
        this.moveDot(stackerData);
      }
    },
    // è®¡ç®—指示器位置
    calculateDotPosition() {
      // æœªæ”¶åˆ°ä¿¡æ¯æˆ–CurrentColumn为0,指示器在外面
      if (!this.yL_DB.CurrentColumn || this.yL_DB.CurrentColumn == "0") {
        return -30; // æ˜¾ç¤ºåœ¨è´§ä½åŒºåŸŸå·¦ä¾§å¤–面
      }
      // è®¡ç®—指示器位置,确保与对应列对齐
      const currentColumn = parseInt(this.yL_DB.CurrentColumn);
      // å®žé™…货位宽度(图片宽度)
      const columnWidth = 30; // è´§ä½å›¾ç‰‡å®½åº¦ä¸º30px
      const dotWidth = 25; // æŒ‡ç¤ºå™¨å®½åº¦ä¸º25px
      // ç”±äºŽåˆ—号是从右到左递减显示的,需要计算实际索引
      // ä¾‹å¦‚:第90列在最左边,第1列在最右边
      // æ¨¡æ¿ä¸­æ˜¾ç¤ºçš„列号是 91-item,所以第1个el-col显示90,第90个el-col显示1
      // å½“前列号为currentColumn,对应的索引为 maxColumn - currentColumn
      const actualIndex = this.maxColumn - currentColumn;
      // è®¡ç®—位置:
      // (实际索引 * è´§ä½å®½åº¦) = è¯¥åˆ—的起始位置
      // + (货位宽度 / 2) = è¯¥åˆ—的中心位置
      // - (指示器宽度 / 2) = å°†æŒ‡ç¤ºå™¨ä¸­å¿ƒä¸Žåˆ—中心对齐
      const position = actualIndex * columnWidth + (columnWidth / 2) - (dotWidth / 2);
      // è°ƒè¯•信息
      console.log('当前列:', currentColumn, '实际索引:', actualIndex);
      console.log('货位宽度:', columnWidth, '指示器宽度:', dotWidth);
      console.log('计算位置:', position);
      return position;
    },
    moveDot(x) {
      this.StackerCrane.Automatic = x.Automatic == null ? "故障" : x.Automatic;
      this.StackerCrane.Fault = x.Fault == null ? "故障" : x.Fault;
      this.StackerCrane.Running = x.Running == null ? "故障" : x.Running;
      this.StackerCrane.CurrentColumn = x.CurrentColumn == undefined ? 1 : x.CurrentColumn;
      this.StackerCrane.CurrentLayer = x.CurrentLayer == undefined ? 1 : x.CurrentLayer;
      this.StackerCrane.LevelPoint = x.LevelPoint;
      this.StackerCrane.DeviceName = x.DeviceName;
      this.StackerCrane.CurrentTaskNum = x.CurrentTaskNum;
      this.StackerCrane.StackerAlarm = x.StackerAlarm;
      this.form.DeviceCode = x.DeviceCode;
      // æ˜ å°„工作模式
      const autoStatusCode = x.YL_AutoStatus;
      if (autoStatusCode !== undefined) {
        this.yL_DB.YL_AutoStatus = this.YLDBMap.YL_AutoStatus[autoStatusCode] || autoStatusCode;
      } else {
        this.yL_DB.YL_AutoStatus = "无";
      }
      // æ˜ å°„设备状态
      const statusCode = parseInt(x.YL_Status);
      if (!isNaN(statusCode)) {
        this.yL_DB.YL_Status = this.YLDBMap.YL_Status[statusCode] || statusCode.toString();
      } else {
        this.yL_DB.YL_Status = "无";
      }
      // æ˜ å°„工作状态
      const workStatusCode = x.YL_WorkStatus;
      if (workStatusCode !== undefined) {
        this.yL_DB.YL_WorkStatus = this.YLDBMap.YL_WorkStatus[workStatusCode] || workStatusCode;
      } else {
        this.yL_DB.YL_WorkStatus = "无";
      }
      // å…¶ä»–数据赋值
      this.yL_DB.R_PP_Status = x.DeviceCode || "无";
      this.yL_DB.YL_WorkType = x.YL_WorkType || "无";
      this.yL_DB.YL_TaskNum = x.YL_TaskNum || "无";
      // å¤„理行号
      const rowValue = parseInt(x.YL_Row);
      this.yL_DB.YL_Row = (!isNaN(rowValue) && rowValue > 0) ? rowValue.toString() : "0";
      // æ ¹æ®å°è´§ä½å·è®¡ç®—列号
      // ç›´æŽ¥ä½¿ç”¨åŽŸå§‹å°è´§ä½å·
      const smallColumn = parseInt(x.YL_Column);
      let displayColumn;
      if (!isNaN(smallColumn) && smallColumn > 0) {
        // ç›´æŽ¥ä½¿ç”¨å°è´§ä½å·ï¼Œä¸è¿›è¡Œè½¬æ¢
        displayColumn = smallColumn;
      } else {
        // æ²¡æœ‰æ”¶åˆ°ä¿¡æ¯ï¼ŒæŒ‡ç¤ºå™¨åœ¨å¤–面
        displayColumn = 0;
      }
      // å¤„理列号
      this.yL_DB.YL_Column = (!isNaN(smallColumn) && smallColumn > 0) ? smallColumn.toString() : "0";
      // å¤„理层号
      const layerValue = parseInt(x.YL_Layer);
      this.yL_DB.YL_Layer = (!isNaN(layerValue) && layerValue > 0) ? layerValue.toString() : "0";
      // å¤„理后端新参数,显示到报警信息中
      this.yL_DB.StackerAlarm = x.StackerAlarm || "无";
      this.yL_DB.CurrentColumn = displayColumn.toString();
      this.form.DeviceCode = x.DeviceCode || "";
    },
    update() {
      if (this.StackerCrane.Automatic == "联机模式" && this.StackerCrane.Fault != "故障" && this.StackerCrane.Running == "待机") {
      // èŽ·å–StackerAlarm的值,转换为字符串进行比较
      const alarmValue = String(this.yL_DB.StackerAlarm).trim();
      // å½“StackerAlarm字段的值不为0或空时,就故障报警(显示红色)
      if (alarmValue !== '' && alarmValue !== '0' && alarmValue !== '无') {
        return 'dot-Fault ';
      }
      if (this.yL_DB.YL_Status == "在线" && (this.yL_DB.YL_AutoStatus == "自动" || this.yL_DB.YL_AutoStatus == "半自动")) {
        return 'dot-Automatic ';
      }
      else if (this.StackerCrane.Automatic == "联机模式" && this.StackerCrane.Fault != "故障" && this.StackerCrane.Running == "运行中") {
      else if (this.yL_DB.YL_Status == "在线" && this.yL_DB.YL_AutoStatus == "手动") {
        return 'dot-Running ';
      } else if (this.StackerCrane.Fault == "故障") {
        return 'dot-Fault ';
      } else {
        return 'dot-Fault ';
      }
    },
    status() {
      const statusText = this.ConveyorLineInfo.YL_Status;
      if (statusText === '手动') {
        return 'custom-img-blue';
      } else if (statusText === '自动') {
        return 'custom-img-green';
      } else if (statusText === '脱机') {
        return 'custom-img-red';
      } else {
        return '';
      }
    },
    mouseClick() {
@@ -238,85 +328,85 @@
      this.dialogVisible = true;
      this.fullscreenLoading = false;
    },
    start() {
      this.fullscreenLoading = true;
      this.http.post("api/DeviceInfo/StackerHandTask", this.form)
        .then((x) => {
          if (!x.status) {
            this.$message.error(x.message);
          } else {
            this.$Message.success("堆垛机命令已下发");
            // $vue.success("成功.");
            this.show = false;
            $vue.refresh();
          }
        })
        .finally(() => {
          this.fullscreenLoading = false;
        });
    }, reset() {
      this.fullscreenLoading = true;
      this.http.post("api/DeviceInfo/StackerReset?DeviceCode=" + this.form.DeviceCode)
        .then((x) => {
          if (!x.status) {
            this.$message.error(x.message);
          } else {
            this.$Message.success("复位成功");
            // $vue.success("成功.");
            this.show = false;
            $vue.refresh();
          }
        })
        .finally(() => {
          this.fullscreenLoading = false;
        });
    },
    emergencyStop() {
      this.fullscreenLoading = true;
      this.http.post("api/DeviceInfo/StackerEmergencyStop?DeviceCode=" + this.form.DeviceCode)
        .then((x) => {
          if (!x.status) {
            this.$message.error(x.message);
          } else {
            this.$Message.success("急停已按下");
            // $vue.success("成功.");
            // this.show = false;
            // $vue.refresh();
          }
        })
        .finally(() => {
          this.fullscreenLoading = false;
        });
    },
    disconnected() {
      this.fullscreenLoading = true;
      this.http.post("api/DeviceInfo/StackerDisconnected?DeviceCode=" + this.form.DeviceCode)
        .then((x) => {
          if (!x.status) {
            this.$message.error(x.message);
          } else {
            this.$Message.success("中断堆垛机任务");
          }
        })
        .finally(() => {
          this.fullscreenLoading = false;
        });
    },
    StackerRecall() {
      this.fullscreenLoading = true;
      this.http.post("api/DeviceInfo/StackerRecall?DeviceCode=" + this.form.DeviceCode)
        .then((x) => {
          if (!x.status) {
            this.$message.error(x.message);
          } else {
            this.$Message.success("召回堆垛机");
          }
        })
        .finally(() => {
          this.fullscreenLoading = false;
        });
    }
    // start() {
    //   this.fullscreenLoading = true;
    //   this.http.post("api/DeviceInfo/StackerHandTask", this.form)
    //     .then((x) => {
    //       if (!x.status) {
    //         this.$message.error(x.message);
    //       } else {
    //         this.$Message.success("堆垛机命令已下发");
    //         // $vue.success("成功.");
    //         this.show = false;
    //         $vue.refresh();
    //       }
    //     })
    //     .finally(() => {
    //       this.fullscreenLoading = false;
    //     });
    // }, reset() {
    //   this.fullscreenLoading = true;
    //   this.http.post("api/DeviceInfo/StackerReset?DeviceCode=" + this.form.DeviceCode)
    //     .then((x) => {
    //       if (!x.status) {
    //         this.$message.error(x.message);
    //       } else {
    //         this.$Message.success("复位成功");
    //         // $vue.success("成功.");
    //         this.show = false;
    //         $vue.refresh();
    //       }
    //     })
    //     .finally(() => {
    //       this.fullscreenLoading = false;
    //     });
    // },
    // emergencyStop() {
    //   this.fullscreenLoading = true;
    //   this.http.post("api/DeviceInfo/StackerEmergencyStop?DeviceCode=" + this.form.DeviceCode)
    //     .then((x) => {
    //       if (!x.status) {
    //         this.$message.error(x.message);
    //       } else {
    //         this.$Message.success("急停已按下");
    //         // $vue.success("成功.");
    //         // this.show = false;
    //         // $vue.refresh();
    //       }
    //     })
    //     .finally(() => {
    //       this.fullscreenLoading = false;
    //     });
    // },
    // disconnected() {
    //   this.fullscreenLoading = true;
    //   this.http.post("api/DeviceInfo/StackerDisconnected?DeviceCode=" + this.form.DeviceCode)
    //     .then((x) => {
    //       if (!x.status) {
    //         this.$message.error(x.message);
    //       } else {
    //         this.$Message.success("中断堆垛机任务");
    //       }
    //     })
    //     .finally(() => {
    //       this.fullscreenLoading = false;
    //     });
    // },
    // StackerRecall() {
    //   this.fullscreenLoading = true;
    //   this.http.post("api/DeviceInfo/StackerRecall?DeviceCode=" + this.form.DeviceCode)
    //     .then((x) => {
    //       if (!x.status) {
    //         this.$message.error(x.message);
    //       } else {
    //         this.$Message.success("召回堆垛机");
    //       }
    //     })
    //     .finally(() => {
    //       this.fullscreenLoading = false;
    //     });
    // }
  },
};
</script>
@@ -324,9 +414,10 @@
<style scoped>
.line-container {
  position: relative;
  height: 20px;
  height: 25px;
  background-color: #ecf5ff;
  width: 960px;
  width: 2720px;
  /* 90列 * 30px每列 */
}
.line {
@@ -334,13 +425,13 @@
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  height: 0px;
  background-color: #a0cfff;
}
.dot-Running {
  position: absolute;
  top: -5px;
  top: 0px;
  width: 25px;
  height: 25px;
  border-radius: 50%;
@@ -356,7 +447,7 @@
.dot-Automatic {
  position: absolute;
  top: -5px;
  top: 0px;
  width: 25px;
  height: 25px;
  border-radius: 50%;
@@ -372,7 +463,7 @@
.dot-Fault {
  position: absolute;
  top: -5px;
  top: 0px;
  width: 25px;
  height: 25px;
  border-radius: 50%;
@@ -388,19 +479,111 @@
img {
  width: 30px;
  height: 25px;
  height: 30px;
}
.image-text {
  position: absolute;
  top: 5px;
  /* left: 10px;  */
  color: white;
  /* æ–‡å­—颜色 */
  color: #000000;
  font-size: 12px;
  /* å­—号大小 */
  font-weight: bold;
  /* å­—体粗细 */
  font-family: 'Microsoft YaHei', Arial, sans-serif;
  margin-left: 5px;
}
</style>
.modern-dialog {
  border-radius: 16px !important;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
}
.modern-dialog .el-dialog__header {
  display: none;
}
.modern-dialog .el-dialog__body {
  padding: 0;
  margin: 0;
}
.dialog-header {
  background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
  padding: 20px 24px;
  text-align: center;
}
.dialog-title {
  color: #fff;
  font-size: 18px;
  font-weight: 600;
  margin: 0;
  letter-spacing: 2px;
}
.dialog-content {
  padding: 28px;
  background: #f8fafc;
  display: flex;
  justify-content: center;
}
.info-list {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.info-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  transition: all 0.3s ease;
}
.info-item:hover {
  transform: translateX(4px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}
.item-label {
  font-size: 14px;
  color: #6b7280;
  font-weight: 500;
  min-width: 80px;
  text-align: left;
}
.item-value {
  font-size: 15px;
  color: #1f2937;
  font-weight: 500;
  text-align: right;
  flex: 1;
  margin-left: 20px;
  word-break: break-all;
  padding-left: 20px;
  border-left: 1px solid #e5e7eb;
}
.status-blue {
   color: #409eff !important;
   font-weight: 600;
}
.status-green {
   color: #67c23a !important;
   font-weight: 600;
}
.status-red {
   color: #f56c6c !important;
   font-weight: 600;
}
</style>