<template>
  <div v-loading="loading">
    <el-form label-width="80px" :model="formLabelAlign">
      <el-row>
        <!-- 新增查询条件 -->
        <el-col :span="6">
          <el-form-item label="班组:">
            <el-select
              v-model="formLabelAlign.teamName"
              clearable
              filterable
              placeholder="请选择"
              size="medium"
              value-key="id"
              @change="teamChange"
            >
              <el-option
                v-for="(item, index) in selectTeamOptions"
                :label="item.tsName"
                :value="item"
                :key="item"
              ></el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="设备:">
            <el-select
              v-model="formLabelAlign.equipName"
              clearable
              filterable
              placeholder="请选择"
              size="medium"
              value-key="id"
              @change="equipChange"
            >
              <el-option
                v-for="(item, index) in selectEquipOptions"
                :label="item.deviceName"
                :value="item"
                :key="index"
              ></el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="工序:">
            <el-select
              v-model="formLabelAlign.processId"
              clearable
              filterable
              placeholder="请选择"
              size="medium"
              @change="processChange"
              value-key="id"
            >
              <el-option
                v-for="(item, index) in selectProcessOptions"
                :label="item.name"
                :value="item"
                :key="index"
              ></el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="时间:">
            <el-date-picker
              v-model="formLabelAlign.timeRange"
              type="daterange"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              size="medium"
              :clearable="false"
              :shortcuts="pickerOptions.shortcuts"
            ></el-date-picker>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="零件号:">
            <el-input v-model="formLabelAlign.partCode" placeholder="请输入"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="批次号:">
            <el-input v-model="formLabelAlign.batchNo" placeholder="请输入"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="接收时间:">
            <el-date-picker
              v-model="formLabelAlign.receiveTime"
              type="date"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              placeholder="请选择"
              size="medium"
              :clearable="true"
              style="width: 100%"
            ></el-date-picker>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <div style="float: right">
            <el-button type="primary" icon="el-icon-search" @click="handleSubmit" size="medium">
              搜索
            </el-button>
            <el-button icon="el-icon-delete" @click="handleReset" size="medium"> 清空 </el-button>
            <el-button type="primary" size="medium" @click="exportXls">导出</el-button>
          </div>
        </el-col>
      </el-row>
    </el-form>

    <div class="gantt-container">
      <!-- 头部标题和图例 -->
      <div class="gantt-header">
        <div class="status-legend">
          <div class="legend-item">
            <el-checkbox
              v-model="legendStatus.pending"
              :style="{ '--checkbox-color': '#6c757d' }"
              @change="handleLegendChange('pending')"
            >
              <span class="legend-text" style="color: #6c757d">未开始</span>
            </el-checkbox>
          </div>

          <div class="legend-item">
            <el-checkbox
              v-model="legendStatus.processing"
              :style="{ '--checkbox-color': '#28a745' }"
              @change="handleLegendChange('processing')"
            >
              <span class="legend-text" style="color: #28a745">进行中</span>
            </el-checkbox>
          </div>
          <div class="legend-item">
            <el-checkbox
              v-model="legendStatus.completed"
              :style="{ '--checkbox-color': '#007bff' }"
              @change="handleLegendChange('completed')"
            >
              <span class="legend-text" style="color: #007bff">已完成</span>
            </el-checkbox>
          </div>
        </div>
      </div>

      <!-- 甘特图主体 -->
      <div class="gantt-wrapper">
        <!-- 左侧信息列表 - 展示车间订单号等信息 -->
        <div class="info-list" :style="{ height: ganttWrapperHeightLeft }">
          <div class="info-item-title">
            <div class="info-title-cell info-title-num">#</div>
            <div class="info-title-cell">订单信息</div>
          </div>
          <div class="info-container" ref="leftScrollContainer">
            <div
              v-for="(order, index) in currentPageOrders"
              :key="index"
              :style="{
                height: getRowHeight(order.woCode) + 'px',
                borderBottom: '1px solid #ccc',
                lineHeight: getRowHeight(order.woCode) + 'px',
              }"
            >
              <div class="info-item">
                <div class="info-cell info-title-num">{{ index + 1 }}</div>
                <el-row>
                  <el-col :span="24">
                    <div class="info-item-txt info-item-info">
                      <span class="order-code" style="font-weight: 600">{{ order.woCode }}</span>
                      <span class="part-code">{{ order.partCode }}</span>
                    </div>
                  </el-col>
                  <el-col :span="24">
                    <div class="info-item-txt info-item-orderInfo">
                      <div class="info-item-content">
                        <span class="batch-no">{{ order.batchNo }}</span>
                        <span class="make-qty">{{ order.makeQty }}</span>
                        <span class="product-ident">{{ order.productIdent }}</span>
                        <span v-if="order.priorityAps != ''" class="priority-aps">{{
                          order.priorityAps
                        }}</span>
                      </div>
                    </div>
                  </el-col>
                </el-row>
              </div>
            </div>
          </div>
        </div>

        <!-- 右侧时间轴 @wheel.prevent="handleWheel"-->
        <div
          class="timeline-container"
          ref="timelineContainer"
          :style="{ height: ganttWrapperHeight }"
        >
          <!-- 图表X轴区域 -->
          <div class="chart-axis">
            <!-- 日期行 -->
            <div class="date-labels" :style="{ width: `${timelineWidth}%` }">
              <template v-for="(dateInfo, dateIndex) in dateLabels" :key="dateIndex">
                <div
                  class="date-label"
                  :style="{
                    left: `${dateInfo.position}%`,
                    width:
                      dateIndex < dateLabels.length - 1
                        ? `${dateLabels[dateIndex + 1].position - dateInfo.position}%`
                        : `${100 - dateInfo.position}%`,
                    borderRight: dateIndex < dateLabels.length - 1 ? '1px solid #fff' : 'none',
                  }"
                >
                  <div class="date-main">{{ dateInfo.label }}</div>
                </div>
              </template>
            </div>

            <!-- 时间标签行 -->
            <div class="time-labels" :style="{ width: `${timelineWidth}%` }">
              <div
                v-for="(time, index) in majorTickLabels"
                :key="index"
                class="major-label"
                :style="{ left: `${time.position}%` }"
              >
                {{ formatHourLabel(time.label) }}
              </div>
              <div v-if="zoomLevel >= 1.5" class="minor-labels">
                <div
                  v-for="(time, index) in minorTickLabels"
                  :key="'minor-' + index"
                  class="minor-label"
                  :style="{ left: `${time.position}%` }"
                >
                  {{ time.label }}
                </div>
              </div>
            </div>

            <!-- 刻度线 -->
            <div class="tick-lines" :style="{ width: `${timelineWidth}%` }">
              <div
                v-for="(time, index) in majorTickLabels"
                :key="'tick-' + index"
                class="major-tick-line"
                :style="{ left: `${time.position || (index / 72) * 100}%` }"
              ></div>
              <div v-if="zoomLevel >= 1.5" class="minor-tick-lines">
                <div
                  v-for="(time, index) in minorTickLabels"
                  :key="'minor-tick-' + index"
                  class="minor-tick-line"
                  :style="{ left: `${time.position}%` }"
                ></div>
              </div>
              <div class="axis-base-line"></div>

              <!-- 当前时间线 -->
              <div
                class="current-time-line"
                :style="{ left: `${currentTimePosition}%` }"
                v-if="currentTimePosition >= 0"
              >
                <div class="current-time-indicator">现在</div>
              </div>
            </div>
          </div>

          <!-- 甘特图内容区域 -->
          <div
            class="chart-content"
            ref="timelineContainerTest"
            :style="{ width: `${timelineWidth}%` }"
          >
            <div class="grid-lines">
              <div
                v-for="(time, index) in majorTickLabels"
                :key="index"
                class="grid-line"
                :style="{ left: `${time.position}%` }"
              ></div>
            </div>

            <div class="tasks-container">
              <div
                v-for="(order, index) in currentPageOrders"
                :key="index"
                class="device-task-row"
                :style="{ height: getRowChartHeight(order.woCode) + 'px' }"
              >
                <template
                  v-for="(layer, layerIndex) in getLayeredTasks(order.woCode)"
                  :key="layerIndex"
                >
                  <div
                    v-for="(task, taskIndex) in layer"
                    :key="taskIndex"
                    class="task-bar"
                    @click="showTaskDetail(task)"
                    :class="{
                      'task-bar-narrow':
                        getWidthPercent(task.planStartTime, task.planEndTime) < 2.1,
                    }"
                    :style="{
                      left: `${getPositionPercent(task.planStartTime)}%`,
                      width: `${getWidthPercent(task.planStartTime, task.planEndTime)}%`,
                      backgroundColor: getStatusColor(task),
                      top: `${getLayerOffset(
                        layerIndex,
                        getLayerTaskHeight(getLayeredTasks(order.woCode).length, order.woCode),
                        order.woCode
                      )}px`,
                      height: `${getLayerTaskHeight(
                        getLayeredTasks(order.woCode).length,
                        order.woCode
                      )}px`,
                    }"
                    @mouseenter="showTooltip($event, task, order.woCode)"
                    @mouseleave="hideTooltip()"
                  >
                    <div
                      class="task-label"
                      v-if="getWidthPercent(task.planStartTime, task.planEndTime) >= 1.5"
                    >
                      <span class="task-label-txt task-label-txt-inside">{{
                        task.processName
                      }}</span>
                    </div>

                    <!-- 为窄任务添加带偏移的文本显示   task.processName-->

                    <div
                      v-else
                      class="task-overlay-text"
                      :style="{
                        width: `${getWidthPercent(task.planStartTime, task.planEndTime)}%`,
                        top: `${getNarrowTaskOffsetByLayer(layerIndex)}px`,
                        left: `${getNarrowTaskOffsetByLayerLeft(
                          task.processName,
                          getWidthPercent(task.planStartTime, task.planEndTime),
                          layerIndex
                        )}px`,
                      }"
                    >
                      {{ task.processName }}
                    </div>
                  </div>
                </template>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 分页控件   :page-sizes="[10, 20, 50]" ,sizes-->
      <div class="pagination-container">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="currentPage"
          :page-size="pageSize"
          :page-sizes="[10, 20, 50]"
          layout="total,sizes, prev, pager, next, jumper"
          :total="totalOrders"
        ></el-pagination>
      </div>

      <!-- 悬浮提示框 -->
      <div
        v-if="tooltipVisible"
        class="tooltip"
        :style="{
          left: `${tooltipX}px`,
          top: `${tooltipY}px`,
        }"
      >
        <div class="tooltip-content">
          <div class="wo-code-title">{{ tooltipData.woCode }}</div>
          <ul class="detail-list">
            <li class="detail-item">
              <span class="label">工序：</span>
              <span class="value">{{ tooltipData.processName || '-' }}</span>
            </li>
            <li class="detail-item">
              <span class="label">班组：</span>
              <span class="value">{{ tooltipData.teamName || '-' }}</span>
            </li>
            <li class="detail-item">
              <span class="label">设备：</span>
              <span class="value">{{ tooltipData.equipName || '-' }}</span>
            </li>
            <li class="detail-item">
              <span class="label">零件号：</span>
              <span class="value">{{ tooltipData.partCode || '-' }}</span>
            </li>
            <li class="detail-item">
              <span class="label">批次号：</span>
              <span class="value">{{ tooltipData.batchNo || '-' }}</span>
            </li>
            <li class="detail-item">
              <span class="label">数量：</span>
              <span class="value">{{ tooltipData.makeQty || '-' }}</span>
            </li>
            <li class="detail-item">
              <span class="label">计划开始：</span>
              <span class="value">{{ tooltipData.planStartTime || '-' }}</span>
            </li>
            <li class="detail-item">
              <span class="label">计划完成：</span>
              <span class="value">{{ tooltipData.planEndTime || '-' }}</span>
            </li>
            <li class="detail-item">
              <span class="label">实际开始：</span>
              <span class="value">{{ tooltipData.factStartTime || '-' }}</span>
            </li>
            <li class="detail-item">
              <span class="label">实际完成：</span>
              <span class="value">{{ tooltipData.factEndTime || '-' }}</span>
            </li>
            <li class="detail-item">
              <span class="label">工序状态：</span>
              <span class="value">
                <el-tag :type="getStatusTagType(tooltipData)">
                  <i v-if="tooltipData.planStatus == '1'">未开始</i>
                  <i v-if="tooltipData.planStatus == '2'">加工中</i>
                  <i v-if="tooltipData.planStatus == '3'">报工完成</i>
                  <i v-if="tooltipData.planStatus == '5'">已完成</i>
                  <i v-if="tooltipData.planStatus == '6'">已返工</i>
                </el-tag>
              </span>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { getData, selectEquip, selectTeam } from '@/api/productionSchedulingPlan/scheduling';
import {
  getProcessSet,
  exportBlob,
  getEquipment,
  getTeamSet,
} from '@/api/productionSchedulingPlan/basic';
import { downloadXls } from '@/utils/util';
// import { exportBlob } from '@/api/common';
export default {
  name: 'GanttChart',
  data() {
    return {
      valuerrr: '铜合金化学镀镍', //
      loading: false,
      formLabelAlign: {
        startTime: null, //时间
        teamName: '', //班组
        teamId: '', //班组
        equipName: '', //设备
        equipId: '', //设备
        processName: '', //工序
        processId: '', //工序
        woCode: '', //车间订单号
        timeRange: [], //时间范围
        receiveTime: '', //接收时间
        partCode: '', //订单号
        batchNo: '', //批次号
        planStatusList: [], //工序状态
      },
      zoomLevel: 1, // 缩放级别 (1-4)
      minZoom: 1,
      maxZoom: 4,

      // 订单列表和任务数据
      allOrders: [], // 所有订单信息
      currentPageOrders: [], // 当前页订单
      taskData: [],
      totalOrders: 0,

      // 分页参数
      currentPage: 1,
      pageSize: 10,

      // 提示框相关
      tooltipVisible: false,
      tooltipData: {},
      tooltipX: 0,
      tooltipY: 0,

      // 样式相关
      baseRowHeight: 50,
      baseRowChartHeight: 50,
      rowHeights: {},
      selectTeamOptions: [],
      selectEquipOptions: [],
      selectProcessOptions: [],

      // 当前时间位置
      currentTimePosition: 0,

      timelineWidth: 300, // 3天的宽度 (每天100%)
      baseStartTime: null, // 基准开始时间
      currentViewStartTime: null, // 当前视图开始时间
      currentViewEndTime: null, // 当前视图结束时间

      legendStatus: {
        completed: false,
        processing: true,
        pending: true,
      },
      handleRightScrollBound: null,
      handleLeftScrollBound: null,
      pickerOptions: {
        shortcuts: [
          {
            text: '最近三天',
            value: [new Date(), new Date(new Date().getTime() + 3 * 24 * 60 * 60 * 1000)],
          },
          {
            text: '最近七天',
            value: [new Date(), new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000)],
          },
        ],
      },
    };
  },
  watch: {
    // 监听参数变化
    '$route.query': {
      handler(newQuery) {
        this.handleParamsChange();
      },
      immediate: true,
    },
  },
  computed: {
    // 通过 Vue Router 获取查询参数
    tsId() {
      return this.$route.query.tsId || '';
    },
    tsName() {
      return this.$route.query.tsName || '';
    },
    // 计算基准开始时间（今天0点）
    baseDate() {
      if (this.formLabelAlign.timeRange && this.formLabelAlign.timeRange.length === 2) {
        const start = new Date(this.formLabelAlign.timeRange[0]);
        start.setHours(0, 0, 0, 0);
        return start;
      }
      // 默认显示当前日期
      const now = new Date();
      const base = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
      return base;
    },
    // 计算结束日期
    endDate() {
      if (this.formLabelAlign.timeRange && this.formLabelAlign.timeRange.length === 2) {
        const end = new Date(this.formLabelAlign.timeRange[1]);
        end.setHours(23, 59, 59, 999);
        return end;
      }
      // 默认显示当前日期+2天
      const now = new Date();
      const base = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 2, 23, 59, 59, 999);
      return base;
    },
    // 计算总小时数
    totalHours() {
      const diffTime = this.endDate - this.baseDate;
      return Math.ceil(diffTime / (1000 * 60 * 60)); // 计算总小时数
    },

    // 计算当前视图开始时间（当前小时）
    viewStartTime() {
      return this.baseDate;
    },

    // 生成3天的时间刻度
    timelineHours() {
      const hours = [];
      const start = new Date(this.baseDate);

      for (let i = 0; i < this.totalHours; i++) {
        const hour = new Date(start);
        hour.setHours(start.getHours() + i);
        hours.push(hour);
      }
      return hours;
    },

    // 生成主要时间标签（每小时）
    majorTickLabels() {
      const labels = [];
      const start = new Date(this.baseDate);
      const end = new Date(this.endDate);

      for (let i = 0; i < this.totalHours; i++) {
        const hour = new Date(start);
        hour.setHours(start.getHours() + i);

        // 检查时间是否超出结束时间
        if (hour > end) {
          break; // 如果超出结束时间则停止添加
        }

        // 计算时间点在时间轴上的位置百分比
        const timeDiff = hour - this.baseDate;
        const totalDuration = this.totalHours * 60 * 60 * 1000; // 总毫秒数
        const positionPercent = (timeDiff / totalDuration) * 100;

        labels.push({
          time: hour,
          label: `${hour.getMonth() + 1}-${hour.getDate()} ${hour.getHours()}:00`,
          position: Math.min(100, positionPercent), // 确保不超过100%
        });
      }
      return labels;
    },

    // 生成日期标签
    dateLabels() {
      const dates = [];
      const start = new Date(this.baseDate);
      const end = new Date(this.endDate);

      // 计算总天数
      const totalDays = Math.ceil((end - start) / (1000 * 60 * 60 * 24));

      for (let i = 0; i <= totalDays; i++) {
        const date = new Date(start);
        date.setDate(start.getDate() + i);

        // 检查日期是否超出结束日期
        if (date > end) {
          break; // 如果超出结束日期则停止添加
        }

        // 计算每个日期在时间轴上的开始位置百分比
        const timeDiff = date - this.baseDate;
        const totalDuration = this.totalHours * 60 * 60 * 1000; // 总毫秒数
        const positionPercent = (timeDiff / totalDuration) * 100;

        // 确保位置在有效范围内
        if (positionPercent <= 100) {
          dates.push({
            date: date,
            position: Math.max(0, Math.min(100, positionPercent)),
            label: `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日`, // 显示年/月/日
            dayName: this.getDayName(date.getDay()),
          });
        }
      }
      return dates;
    },

    // 生成次要时间标签（每半小时）
    minorTickLabels() {
      const labels = [];
      const start = new Date(this.baseDate);
      const end = new Date(this.endDate); // 添加结束时间变量
      const totalHalfHours = this.totalHours * 2; // 每小时2个刻度

      for (let i = 0; i < totalHalfHours; i++) {
        const halfHour = new Date(start);
        halfHour.setHours(start.getHours() + Math.floor(i / 2), (i % 2) * 30, 0, 0);

        // 检查时间是否超出结束时间
        if (halfHour > end) {
          break; // 如果超出结束时间则停止添加
        }

        // 计算时间点在时间轴上的位置百分比
        const timeDiff = halfHour - this.baseDate;
        const totalDuration = this.totalHours * 60 * 60 * 1000; // 总毫秒数
        const positionPercent = (timeDiff / totalDuration) * 100;

        if (i % 2 === 1) {
          // 只显示半小时标记
          labels.push({
            time: halfHour,
            label: `${halfHour.getMonth() + 1}-${halfHour.getDate()} ${halfHour.getHours()}:30`,
            position: Math.min(100, positionPercent), // 确保不超过100%
          });
        }
      }
      return labels;
    },

    // 当前时间位置
    currentTimePosition() {
      const now = new Date();
      const viewStart = this.baseDate;
      const viewEnd = this.endDate;

      // 如果当前时间不在显示范围内，返回-1表示不显示
      if (now < viewStart || now > viewEnd) {
        return -1;
      }

      const diffMs = now - viewStart;
      const totalDuration = this.totalHours * 60 * 60 * 1000;
      const positionPercent = (diffMs / totalDuration) * 100;

      return Math.max(0, Math.min(100, positionPercent));
    },
    // 动态计算时间轴宽度
    timelineWidth() {
      // 根据时间范围动态调整时间轴宽度
      return Math.max(100, this.totalHours * (100 / 24)); // 每24小时为100%宽度，最小为100%
    },
    // 右侧动态计算甘特图容器高度
    ganttWrapperHeightLeft() {
      if (this.$route.path == '/productionSchedulingPlan/schedulingDashboard/index') {
        // 根据实际页面元素计算可用高度
        return `calc(100vh - 250px - 120px - 40px)`; // 调整数值以适应您的页面布局
      } else {
        // 根据实际页面元素计算可用高度
        return `calc(100vh - 250px)`; // 调整数值以适应您的页面布局
      }
    },
    // 动态计算甘特图容器高度
    ganttWrapperHeight() {
      if (this.$route.path == '/productionSchedulingPlan/schedulingDashboard/index') {
        // 根据实际页面元素计算可用高度
        return `calc(100vh - 250px - 120px - 40px)`; // 调整数值以适应您的页面布局
      } else {
        // 根据实际页面元素计算可用高度
        return `calc(100vh - 250px)`; // 调整数值以适应您的页面布局
      }
    },
  },

  mounted() {
    this.getSelectTeam();
    this.getSelectEquip();
    this.getProcessSet();
    // this.updateTime();
    this.updateTimeAxis();
    this.$nextTick(() => {
      this.calcCurrentTimePosition();
      // 添加滚动事件监听器
      if (this.$refs.timelineContainerTest) {
        this.$refs.timelineContainerTest.addEventListener('scroll', this.handleRightScrollBound);
      }
      if (this.$refs.leftScrollContainer) {
        this.$refs.leftScrollContainer.addEventListener('scroll', this.handleLeftScrollBound);
      }
    });

    // 定时更新当前时间线位置
    // setInterval(() => {
    //   this.calcCurrentTimePosition();
    // }, 60000);
  },
  created() {
    // 绑定方法，确保this指向正确
    this.handleRightScrollBound = this.handleRightScroll.bind(this);
    this.handleLeftScrollBound = this.handleLeftScroll.bind(this);
  },
  beforeDestroy() {
    // 移除事件监听器
    if (this.$refs.timelineContainerTest) {
      this.$refs.timelineContainerTest.removeEventListener('scroll', this.handleRightScrollBound);
    }
    if (this.$refs.leftScrollContainer) {
      this.$refs.leftScrollContainer.removeEventListener('scroll', this.handleLeftScrollBound);
    }
  },
  methods: {
    showTaskDetail(task) {
      console.log('showTaskDetail', task);
      // 4. 通过 postMessage 通知父页面
      window.parent.postMessage(
        {
          type: 'TASK_DETAILS',
          batchNo: task.batchNo,
          woCode: task.woCode,
          partCode: task.partCode,
          cardNo: task.cardNo
        },
        '*' // 生产环境建议指定父页面域名（如 "https://parent-domain.com"），避免安全风险
      );
    },
    // 根据层索引确定窄任务文本的垂直偏移
    getNarrowTaskOffsetByLayer(layerIndex) {
      // 偶数层在上方显示（负值），奇数层在下方显示（正值）
      const offset = layerIndex % 2 === 0 ? -20 : 15; // -20px 在上方，5px 在下方
      return offset;
    },
    // 根据层索引确定窄任务文本的垂直偏移
    getNarrowTaskOffsetByLayerLeft(processName, widthPercent, layerIndex) {
      // 偶数层在上方显示（负值），奇数层在下方显示（正值）
      const textWidth = processName.length * 2;
      const timeLine = this.$refs.timelineContainer.clientWidth;
      const taskBarWidth = (timeLine * widthPercent) / 100;

      if (textWidth > taskBarWidth) {
        if (processName <= 4) {
          return -7; // 文字超出任务条时，向左偏移一半文字宽度
        } else {
          return -textWidth * 1.5; // 文字超出任务条时，向左偏移一半文字宽度
        }
      } else {
        // console.log('小于宽度的', textWidth, taskBarWidth,processName);
        if (processName <= 4) {
          return -7; // 文字超出任务条时，向左偏移一半文字宽度
        } else {
          return -textWidth; // 文字超出任务条时，向左偏移一半文字宽度
        }
      }
      // return -7; // 默认偏移
    },
    handleParamsChange() {
      // 参数变化时的处理逻辑
      this.formLabelAlign.teamId = this.tsId;
      this.formLabelAlign.teamName = this.tsName;
      this.updateTime();
      // 根据参数加载数据
      this.getData();
    },
    // 计算重叠的窄任务的垂直偏移量
    getNarrowTaskOffset(orderWoCode, taskIndex, layerIndex) {
      const tasks = this.getDeviceTasks(orderWoCode);
      const currentTask = tasks[taskIndex];

      // 获取当前任务的时间段
      const currentStart = this.parseTimeToHours(currentTask.planStartTime);
      const currentEnd = this.parseTimeToHours(currentTask.planEndTime);
      const currentWidth = this.getWidthPercent(currentTask.planStartTime, currentTask.planEndTime);

      // 如果宽度大于等于1%，不需要偏移
      if (currentWidth >= 1) {
        return 0;
      }

      // 查找在同一时间段内的其他窄任务
      const overlappingTasks = [];
      for (let i = 0; i < tasks.length; i++) {
        const task = tasks[i];
        const taskWidth = this.getWidthPercent(task.planStartTime, task.planEndTime);

        if (taskWidth < 1) {
          // 只考虑窄任务
          const taskStart = this.parseTimeToHours(task.planStartTime);
          const taskEnd = this.parseTimeToHours(task.planEndTime);

          // 检查时间是否重叠（考虑浮点数精度）
          if (Math.max(currentStart, taskStart) <= Math.min(currentEnd, taskEnd) + 0.01) {
            overlappingTasks.push({ index: i, task, start: taskStart, end: taskEnd });
          }
        }
      }

      // 按开始时间排序
      overlappingTasks.sort((a, b) => a.start - b.start);

      // 创建层来分配任务，避免同一层中的任务重叠
      const layers = [];
      for (const overlapTask of overlappingTasks) {
        let assigned = false;

        // 尝试将任务分配到现有层
        for (let layerIdx = 0; layerIdx < layers.length; layerIdx++) {
          const lastTask = layers[layerIdx][layers[layerIdx].length - 1];
          // 检查是否与该层最后一个任务重叠
          if (
            Math.max(lastTask.start, overlapTask.start) > Math.min(lastTask.end, overlapTask.end)
          ) {
            // 不重叠，可以分配到这一层
            layers[layerIdx].push(overlapTask);
            assigned = true;
            break;
          }
        }

        // 如果没有合适的层，创建新层
        if (!assigned) {
          layers.push([overlapTask]);
        }
      }

      // 找到当前任务所在的层索引
      const currentTaskLayerIndex = layers.findIndex(layer =>
        layer.some(item => item.index === taskIndex)
      );

      // 根据层索引返回偏移量
      const offsetStep = 20; // 每个任务之间的偏移量
      return currentTaskLayerIndex * offsetStep;
    },

    // 检查任务是否为窄任务
    isNarrowTask(task) {
      return this.getWidthPercent(task.planStartTime, task.planEndTime) < 1;
    },
    // 右侧滚动时同步左侧滚动
    handleRightScroll(event) {
      if (this.$refs.leftScrollContainer) {
        const rightScrollTop = event.target.scrollTop;
        this.$refs.leftScrollContainer.scrollTop = rightScrollTop;
      }
    },

    // 左侧滚动时同步右侧滚动
    handleLeftScroll(event) {
      if (this.$refs.timelineContainerTest) {
        const leftScrollTop = event.target.scrollTop;
        this.$refs.timelineContainerTest.scrollTop = leftScrollTop;
      }
    },
    updateTime() {
      // 设置默认时间范围为今天到后两天
      const today = new Date();
      const endDay = new Date(today);
      endDay.setDate(today.getDate() + 2);
      // 设置日期范围，格式为 YYYY-MM-DD
      const startDate = today.toISOString().split('T')[0];
      const endDate = endDay.toISOString().split('T')[0];

      this.formLabelAlign.timeRange = [startDate, endDate];
      this.handleLegendChange();
    },
    // 处理图例状态变化
    handleLegendChange() {
      // 如果需要重新加载数据，可以调用
      this.formLabelAlign.planStatusList = [];
      if (this.legendStatus.completed) {
        this.formLabelAlign.planStatusList.push('5');
      }
      if (this.legendStatus.processing) {
        this.formLabelAlign.planStatusList.push('2', '3');
      }
      if (this.legendStatus.pending) {
        this.formLabelAlign.planStatusList.push('1');
      }

      this.getData();
    },
    // 获取星期名称
    getDayName(dayIndex) {
      const days = ['', '一', '二', '三', '四', '五', '六'];
      return `星期${days[dayIndex]}`;
    },
    processChange(val) {
      if (val) {
        this.formLabelAlign.processName = val.name;
      } else {
        this.formLabelAlign.processName = '';
      }
    },
    equipChange(val) {
      if (val) {
        this.formLabelAlign.equipName = val.deviceName;
      } else {
        this.formLabelAlign.equipName = '';
      }
    },
    teamChange(val) {
      if (val) {
        this.formLabelAlign.teamName = val.tsName;
      } else {
        this.formLabelAlign.teamName = '';
      }
    },

    // 导出
    exportXls() {
      exportBlob(`/blade-scheduling/workOrder/exportBoard`, this.formLabelAlign).then(res => {
        //
        if (this.$route.path == '/productionSchedulingPlan/schedulingDashboard/index') {
          downloadXls(res.data, `排产看板数据.xlsx`);
        } else {
          const blob = res.data;
          const reader = new FileReader();
          reader.onload = function (e) {
            const base64 = e.target.result; // 格式：data:application/octet-stream;base64,...
            const fileName = '排产看板数据.xlsx'; // 可从接口响应头获取（如 Content-Disposition）

            // 4. 通过 postMessage 通知父页面
            window.parent.postMessage(
              {
                type: 'DOWNLOAD_FILE',
                base64: base64,
                fileName: fileName,
              },
              '*' // 生产环境建议指定父页面域名（如 "https://parent-domain.com"），避免安全风险
            );
          };
          reader.readAsDataURL(blob);
        }
      });
    },

    // 滚动到当前时间位置
    scrollToCurrentTime() {
      const container = this.$refs.timelineContainer;
      if (container && this.currentTimePosition >= 0 && this.currentTimePosition <= 100) {
        // 计算当前时间位置的像素值
        const scrollWidth = container.scrollWidth;
        const containerWidth = container.clientWidth;

        // 计算当前时间位置的像素坐标
        const timePositionPx = (this.currentTimePosition / 100) * scrollWidth;

        // 计算需要滚动到的位置，使当前时间线在左侧可见
        // 使用容器宽度的1/4位置作为目标，使当前时间在左侧区域显示
        const targetPosition = timePositionPx - containerWidth / 100;

        // 平滑滚动到指定位置
        container.scrollTo({
          left: Math.max(0, Math.min(scrollWidth - containerWidth, targetPosition)),
          behavior: 'smooth', // 平滑滚动
        });
      }
    },

    // 分页相关方法
    handleSizeChange(val) {
      this.pageSize = val;
      this.currentPage = 1;
      this.updateCurrentPageOrders();
    },
    handleCurrentChange(val) {
      this.currentPage = val;
      this.updateCurrentPageOrders();
    },
    updateCurrentPageOrders() {
      const start = (this.currentPage - 1) * this.pageSize;
      const end = start + this.pageSize;
      this.currentPageOrders = this.allOrders.slice(start, end);
    },

    // 数据获取
    async getData(params) {
      if (this.formLabelAlign.timeRange.length > 0) {
        this.formLabelAlign.startTime = this.formLabelAlign.timeRange[0];
        this.formLabelAlign.endTime = this.formLabelAlign.timeRange[1];
      }
      if (this.formLabelAlign.planStatusList.length <= 0) {
        this.formLabelAlign.planStatusList = null;
      }
      this.loading = true;
      await getData(this.formLabelAlign).then(res => {
        this.processData(res.data.data);
      });
    },
    getSelectEquip() {
      getEquipment().then(res => {
        this.selectEquipOptions = res.data.data;
      });
    },
    getSelectTeam() {
      getTeamSet().then(res => {
        this.selectTeamOptions = res.data.data;
      });
    },
    getProcessSet() {
      getProcessSet().then(res => {
        this.selectProcessOptions = res.data.data;
      });
    },

    // 数据处理
    processData(rawData) {
      const tasks = [];
  const orders = [];

  // 遍历数组对象
  rawData.forEach(item => {
    const woCode = item.woCode; // 提取车间订单号
    const woTasks = item.workOrderList || []; // 提取任务列表

    // 提取订单信息（取第一个任务的基础信息）
    if (woTasks.length > 0) {
      const firstTask = woTasks[0];
      orders.push({
        woCode,
        partCode: firstTask.partCode,
        batchNo: firstTask.batchNo,
        makeQty: firstTask.makeQty,
        productIdent: firstTask.productIdent,
        priorityAps: firstTask.priorityAps,
      });
    }

    // 按工序名称分组并合并任务
    const groupedTasks = {};
    woTasks.forEach(task => {
      if (!groupedTasks[task.processName]) {
        groupedTasks[task.processName] = [];
      }
      groupedTasks[task.processName].push(task);
    });

    // 合并相同工序的任务
    Object.values(groupedTasks).forEach(group => {
      // 按开始时间排序
      const sortedTasks = [...group].sort((a, b) => {
        const aStart = this.parseTimeToHours(a.planStartTime);
        const bStart = this.parseTimeToHours(b.planStartTime);
        return aStart - bStart;
      });

      // 合并符合条件的任务
      const mergedTasks = [];
      let currentMergedTask = null;

      sortedTasks.forEach(task => {
        if (!currentMergedTask) {
          // 初始化第一个任务
          currentMergedTask = { ...task };
        } else {
          // 检查当前任务的开始时间是否等于前一个任务的结束时间
          const prevEnd = this.parseTimeToHours(currentMergedTask.planEndTime);
          const currStart = this.parseTimeToHours(task.planStartTime);

          if (prevEnd === currStart) {
            // 合并任务：更新结束时间
            currentMergedTask.planEndTime = task.planEndTime;
          } else {
            // 当前任务无法合并，保存之前的合并任务，并重新初始化
            mergedTasks.push(currentMergedTask);
            currentMergedTask = { ...task };
          }
        }
      });

      // 保存最后一个合并任务
      if (currentMergedTask) {
        mergedTasks.push(currentMergedTask);
      }

      // 将合并后的任务添加到总任务列表
      tasks.push(...mergedTasks);
    });
  });

  this.allOrders = orders;
  this.totalOrders = orders.length;
  this.taskData = tasks;

  this.updateCurrentPageOrders();
  this.loading = false;
    },
    formatHoursToTime(hours) {
      const baseDate = new Date(this.baseDate);
      const date = new Date(baseDate.getTime() + hours * 60 * 60 * 1000);

      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      const hour = String(date.getHours()).padStart(2, '0');
      const minute = String(date.getMinutes()).padStart(2, '0');

      return `${year}-${month}-${day} ${hour}:${minute}`;
    },

    // 任务状态计算
    calcTaskStatus(startTime, endTime) {
      const now = new Date();
      const current = now.getHours() * 60 + now.getMinutes();

      // 解析开始时间
      let startMinutes;
      if (startTime.includes(' ')) {
        const timePart = startTime.split(' ')[1];
        const [startHour, startMinute] = timePart.split(':').map(Number);
        startMinutes = startHour * 60 + startMinute;
      } else {
        const [startHour, startMinute] = startTime.split(':').map(Number);
        startMinutes = startHour * 60 + startMinute;
      }

      // 解析结束时间
      let endMinutes;
      if (endTime.includes(' ')) {
        const timePart = endTime.split(' ')[1];
        const [endHour, endMinute] = timePart.split(':').map(Number);
        endMinutes = endHour * 60 + endMinute;
      } else {
        const [endHour, endMinute] = endTime.split(':').map(Number);
        endMinutes = endHour * 60 + endMinute;
      }

      if (endMinutes < startMinutes) endMinutes += 24 * 60;

      if (current >= endMinutes) return '已完成';
      else if (current >= startMinutes) return '进行中';
      else return '未开始';
    },

    // 事件处理
    handleSubmit() {
      if (!this.formLabelAlign.timeRange || this.formLabelAlign.timeRange.length !== 2) {
        this.$message.warning('请选择时间范围');
        return;
      }
      // 将时间范围设置到请求参数中
      this.formLabelAlign.startTime = this.formLabelAlign.timeRange[0];
      this.formLabelAlign.endTime = this.formLabelAlign.timeRange[1];

      this.getData();
    },
    handleReset() {
      this.formLabelAlign = {
        timeRange: [], // 重置为默认值
        startTime: null,
        endTime: null,
        teamName: '',
        teamId: '',
        equipName: '',
        equipId: '',
        processName: '',
        processId: '',
        woCode: '',
        receiveTime: '', //接收时间
        partCode: '', //订单号
        batchNo: '', //批次号
      };
      this.legendStatus.completed = false;
      this.legendStatus.processing = true;
      this.legendStatus.pending = true;
      this.updateTime();
      this.getData();
    },

    // 任务数据过滤
    getDeviceTasks(device) {
      return this.taskData.filter(task => task.woCode === device);
    },

    // 时间转换工具
    timeToMinutes(timeStr) {
      const [hours, minutes] = timeStr.split(':').map(Number);
      return hours * 60 + minutes;
    },
    // 任务 样式计算
    getStatusColor(row) {
      switch (row.planStatus) {
        case '5':
          return '#007bff';
        case '2':
        case '3':
          return '#28a745';
        case '1':
          return '#6c757d';
        case '6':
          return '#dc3545';
        default:
          return '#ccc';
      }
    },
    getStatusTagType(row) {
      switch (row.planStatus) {
        case '5':
          return 'primary';
        case '2':
        case '3':
          return 'success';
        case '1':
          return 'info';
        case '6':
          return 'danger';
        default:
          return 'default';
      }
    },

    // 缩放控制
    handleWheel(e) {
      if (e.deltaY < 0 && this.zoomLevel < this.maxZoom) {
        this.zoomLevel += 0.5;
      } else if (e.deltaY > 0 && this.zoomLevel > this.minZoom) {
        this.zoomLevel -= 0.5;
      }
    },

    // 提示框控制
    showTooltip(e, task, device) {
      this.tooltipData = { ...task, device };
      this.tooltipVisible = true;

      this.$nextTick(() => {
        const tooltipEl = document.querySelector('.tooltip');
        if (!tooltipEl) return;

        const tooltipWidth = tooltipEl.offsetWidth;
        const tooltipHeight = tooltipEl.offsetHeight;
        const padding = 5;
        let x = e.pageX + 8;
        let y = e.pageY + 8;

        if (x + tooltipWidth > document.documentElement.clientWidth) {
          x = e.pageX - tooltipWidth - 8;
        }
        if (y + tooltipHeight > document.documentElement.clientHeight) {
          y = e.pageY - tooltipHeight - 8;
        }

        this.tooltipX = Math.max(padding, x);
        this.tooltipY = Math.max(padding, y);
      });
    },
    hideTooltip() {
      this.tooltipVisible = false;
    },

    // 左侧行高计算
    getRowHeight(device) {
      return this.baseRowHeight - 1;
    },
    // 右侧行高计算
    getRowChartHeight(device) {
      // 固定行高，不随层数变化
      return this.baseRowChartHeight;
    },
    getLayerOffset(layerIndex, height, device) {
      const rowHeight = this.getRowChartHeight(device);
      return Math.max(0, (rowHeight - height) / 2);
    },
    getTastTopOffset(layerIndex, totalLayers, device) {
      const taskHeight = this.getLayerTaskHeight(totalLayers, device);
      // 计算任务条内部文字的垂直居中位置
      return Math.max(0, (taskHeight - 31) / 2); // 文字高度约10px
    },
    getLayerTaskHeight(totalLayers, device) {
      const rowHeight = this.getRowChartHeight(device);
      return rowHeight - 31;
    },

    // 任务分层
    getLayeredTasks(device) {
      const tasks = this.getDeviceTasks(device);
      if (!tasks.length) return [];

      // 按开始时间排序
      const sortedTasks = [...tasks].sort((a, b) => {
        const aStart = this.timeToMinutes(a.startTime);
        const bStart = this.timeToMinutes(b.startTime);
        return aStart - bStart;
      });

      const layers = [];
      sortedTasks.forEach(task => {
        const taskStart = this.timeToMinutes(task.startTime);
        const taskEnd = this.timeToMinutes(task.endTime);

        // 处理跨天情况
        const adjustedTaskEnd = taskEnd < taskStart ? taskEnd + 24 * 60 : taskEnd;

        // 寻找可以放置任务的层
        let placed = false;
        for (let i = 0; i < layers.length; i++) {
          const layer = layers[i];
          const lastTask = layer[layer.length - 1];
          const lastEnd = this.timeToMinutes(lastTask.endTime);
          const adjustedLastEnd =
            lastEnd < this.timeToMinutes(lastTask.startTime) ? lastEnd + 24 * 60 : lastEnd;

          // 检查是否有时间重叠
          if (taskStart >= adjustedLastEnd) {
            // 没有时间重叠，可以放在这一层
            layer.push(task);
            placed = true;
            break;
          }
        }
        // 如果没有找到合适的层，创建新层
        if (!placed) {
          layers.push([task]);
        }
      });
      return layers;
    },
    // 格式化小时标签，只显示小时部分
    formatHourLabel(timeStr) {
      return timeStr.split(' ')[1]; // 只返回时间部分
    },

    // 格式化分钟标签
    formatMinuteLabel(timeStr) {
      return timeStr.split(' ')[1]; // 只返回时间部分
    },

    // 更新时间轴数据
    updateTimeAxis() {
      // 更新当前视图时间范围
      this.currentViewStartTime = new Date(this.baseDate);
      this.currentViewEndTime = new Date(this.endDate);
    },

    // 计算任务位置百分比（基于3天时间轴）
    getPositionPercent(startTime) {
      const startHour = this.parseTimeToHours(startTime);
      const totalDuration = this.totalHours; // 使用实际总小时数

      // 确保百分比在有效范围内
      const percent = (startHour / totalDuration) * 100;
      return Math.max(0, Math.min(100, percent));
    },

    // 计算任务宽度百分比
    getWidthPercent(startTime, endTime) {
      const startHour = this.parseTimeToHours(startTime);
      const endHour = this.parseTimeToHours(endTime);

      const totalDuration = this.totalHours; // 使用实际总小时数

      let duration = endHour - startHour;
      if (duration < 0) {
        // 处理跨天情况 - 这里需要根据实际业务逻辑调整
        duration = this.totalHours - startHour + endHour;
      }

      // 确保宽度在有效范围内
      const width = (duration / totalDuration) * 100;

      return Math.max(0, Math.min(100, width));
    },

    // // 将时间字符串转换为小时数（从基准日期开始计算）
    parseTimeToHours(timeStr) {
      if (!timeStr) {
        console.error('timeStr is undefined or null');
        return 0;
      }

      // timeStr 格式是 "YYYY-MM-DD HH:mm" 如 "2025-12-25 18:35"
      const [datePart, timePart] = timeStr.split(' ');
      const [year, month, day] = datePart.split('-').map(Number);
      const [hours, minutes] = timePart.split(':').map(Number);

      // 创建完整日期时间对象
      const fullDate = new Date(year, month - 1, day, hours, minutes);

      // 计算与基准开始时间的差值（小时）
      const diffMs = fullDate - this.baseDate;
      const diffHours = diffMs / (1000 * 60 * 60);

      // 确保结果在合理范围内
      return Math.max(0, Math.min(this.totalHours, diffHours));
    },

    // 更新当前时间位置
    calcCurrentTimePosition() {
      const now = new Date();
      const viewStart = this.baseDate;
      const viewEnd = this.endDate;

      // 如果当前时间不在显示范围内，不显示当前时间线
      if (now < viewStart || now > viewEnd) {
        this.currentTimePosition = -1; // 特殊值表示不显示
        return;
      }

      // 计算当前时间相对于视图开始时间的毫秒差
      const diffMs = now - viewStart;

      // 计算整个视图范围的总毫秒数
      const totalDurationMs = viewEnd - viewStart;

      // 计算百分比位置
      const positionPercent = (diffMs / totalDurationMs) * 100;

      // 确保百分比在有效范围内 [0, 100]
      this.currentTimePosition = Math.max(0, Math.min(100, positionPercent));

      // 自动滚动到当前时间位置
      this.$nextTick(() => {
        this.scrollToCurrentTime();
      });
    },
  },
};
</script>

<style scoped lang="scss">
.gantt-container {
  width: 100%;
  padding: 20px;
  box-sizing: border-box;
  font-family: Arial, sans-serif;
  height: calc(100% - 72px - 100px);
}

.gantt-header {
  height: 35px;
  margin-bottom: 10px;
}

.status-legend {
  display: flex;
  gap: 20px;
  float: right;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 14px;
}
.legend-text {
  margin-left: 5px;
}
:deep(.el-checkbox__input.is-checked .el-checkbox__inner:after) {
  border-color: #fff;
  left: 5px;
  top: 2px;
}
:deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  background-color: var(--checkbox-color);
}

:deep(.el-checkbox__inner) {
  border-color: var(--checkbox-color);
  background-color: var(--checkbox-color);
  width: 16px;
  height: 16px;
}
:deep(.el-checkbox__inner:hover) {
  border-color: var(--checkbox-color);
}
:deep(.el-checkbox__label) {
  color: #606266;
  font-size: 14px;
}

.legend-color {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 2px;
}

.legend-color.completed {
  background-color: #28a745;
}
.legend-color.processing {
  background-color: #007bff;
}
.legend-color.pending {
  background-color: #6c757d;
}

.gantt-wrapper {
  display: flex;
  overflow: hidden;
}

/* 左侧信息列表样式 */
.info-list {
  width: 360px;
  background-color: #f8f9fa;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
}
.info-container {
  flex: 1;
  overflow-y: auto; /* 允许垂直滚动 */
  overflow-x: hidden; /* 隐藏水平滚动条 */
}
/* 隐藏滚动条的样式（Webkit浏览器） */
.info-container::-webkit-scrollbar {
  display: none; /* 隐藏滚动条 */
}

.info-item-title {
  display: flex;
  background: #284c89;
  color: #fff;
  font-weight: bold;
  height: 50px;
  line-height: 50px;
}
.info-item-txt {
  line-height: 25px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  text-align: left;
  padding-left: 15px;
}
.info-item-txt i {
  font-style: normal;
}
.info-item-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-right: 15px;
}

.info-title-cell {
  flex: 1;
  text-align: center;
  line-height: 50px;
  border-right: 1px solid #eee;
  font-size: 14px;
}
.info-title-num {
  width: 30px;
  flex: none !important;
}
.info-title-no {
  width: 125px;
  flex: none !important;
}

.info-item {
  display: flex;
  height: 100%;
}

.info-cell {
  flex: 1;
  text-align: center;
  box-sizing: border-box;
  border-right: 1px solid #eee;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 10px;
}

.timeline-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow-y: auto; /* 允许垂直滚动 */
  overflow-x: auto; /* 允许水平滚动 */
}

/* 图表X轴区域样式 */
.chart-axis {
  height: 50px;
  position: relative;
}

.time-labels {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 50px;
  display: flex;
  background-color: #284c89;
}

.major-label {
  position: absolute;
  top: 0;
  left: 0;
  font-size: 14px;
  color: #fff;
  font-weight: 500;
  white-space: nowrap;
  line-height: 50px;
}

.minor-labels {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.minor-label {
  position: absolute;
  top: 0;
  left: 0;
  font-size: 12px;
  color: #fff;
  white-space: nowrap;
  line-height: 50px;
  padding: 0 2px;
}

.tick-lines {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 6px;
  background-color: #284c89;
}

.major-tick-line {
  position: absolute;
  bottom: 0;
  width: 1px;
  height: 4px;
  background-color: #fff;
  transform: translateX(-50%);
}

.minor-tick-lines {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
/* 15分钟刻度样式 */
.quarter-labels {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.quarter-label {
  position: absolute;
  top: 0;
  left: 0;
  font-size: 11px;
  color: #e0e0e0;
  white-space: nowrap;
  line-height: 30px;
  padding: 0 2px;
}

.quarter-tick-lines {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.quarter-tick-line {
  position: absolute;
  bottom: 0;
  width: 1px;
  height: 2px;
  background-color: #e0e0e0;
  transform: translateX(-50%);
}
.minor-tick-line {
  position: absolute;
  bottom: 0;
  width: 1px;
  height: 3px;
  background-color: #fff;
  transform: translateX(-50%);
}

.axis-base-line {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background-color: #dee2e6;
}

/* 当前时间线样式 */
.current-time-line {
  position: absolute;
  top: 0px;
  bottom: 0;
  width: 2px;
  transform: translateX(-50%);
  z-index: 10;
  height: calc(100vh - 130px);
  border-left: 1px dashed #ccc;
}

/* 图表内容区域 */
.chart-content {
  flex: 1;
  position: relative;
  overflow-y: auto;
  overflow-x: auto;
}

.grid-lines {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.grid-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0px;
  background-color: #e9ecef;
}

.tasks-container {
  position: relative;
  width: 100%;
  min-height: 100%;

  overflow-x: hidden;
}

.device-task-row {
  position: relative;
  border-bottom: 1px solid #e9ecef;
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

.task-bar {
  position: absolute;
  border-radius: 5px;
  display: flex;
  align-items: center;
  padding: 2px 0px;
  box-sizing: border-box;
  cursor: pointer;
  /* overflow: hidden; */
  transition: all 0.2s;
  white-space: nowrap;
  border: 1px solid rgba(255, 255, 255, 0.3);
  min-width: 5px;
  z-index: 1;
}
.task-bar.task-bar-narrow {
  overflow: visible; /* 允许覆盖元素超出边界 */
}

.task-bar:hover {
  transform: translateY(-2px);
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
}

.task-label {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  display: inline-block;
  transform: scale(0.7);
}
.task-label-txt {
  position: absolute;
  font-size: 9px;
  color: white;
  /* white-space: nowrap; */
  /* overflow: hidden; */
  /* text-overflow: ellipsis; */
  max-width: 120%;
  text-align: center;
  /* 正确的居中方式 */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.task-label-txt-inside {
}
.task-overlay-text {
  position: absolute;
  top: -20px;
  left: -7px;
  color: rgba(0, 0, 0);
  padding: 2px 4px 2px 0;
  border-radius: 3px;
  font-size: 10px;
  white-space: nowrap;
  z-index: 10;
  transform: none;
  min-width: max-content;
  pointer-events: none;
  display: inline-block;
  transform: scale(0.7);
}

/* 提示框样式 */
.tooltip {
  position: fixed;
  background-color: white;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 20px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  font-size: 12px;
  pointer-events: none;
}

.tooltip-content div {
  margin: 3px 0;
}
.wo-code-title {
  font-size: 18px;
  font-weight: bold;
  color: #1f2d3d;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #e6e6e6;
}

.detail-list {
  list-style: none;
  padding: 0;
  margin: 0;

  .detail-item {
    display: flex;
    align-items: center;
    margin-bottom: 5px;
    line-height: 20px;

    .label {
      width: 60px;
      color: #666;
      font-weight: 500;
      text-align: right;
    }

    .value {
      flex: 1;
      color: #333;
    }
  }
}

/* 分页样式 */
.pagination-container {
  height: 35px;
  margin-top: 15px;
  background-color: #fff; /* 增加背景色避免与内容重叠时看不清 */
  padding: 10px; /* 增加内边距 */
  z-index: 10;
  float: right;
  width: calc(100% - 20px);
}
:deep(.el-pagination) {
  float: right;
}
:deep(.el-button--primary) {
  background-color: #284c89 !important;
  color: #fff;
}
:deep(.el-col) {
  margin-bottom: 0px;
}

/* 日期标签行 */
.date-labels {
  position: absolute;
  top: 0;
  left: 0;
  height: 20px;
  display: flex;
}

.date-label {
  position: absolute;
  top: 0;
  height: 20px;
  background-color: #1a3a6c;
  color: #fff;
  font-size: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid #fff;
  box-sizing: border-box;
}

.time-labels {
  position: absolute;
  top: 20px; /* 为日期行留出空间 */
  left: 0;
  width: 100%;
  height: 30px;
  display: flex;
  background-color: #284c89;
}

.major-label {
  position: absolute;
  top: 0;
  left: 0;
  font-size: 12px;
  color: #fff;
  white-space: nowrap;
  line-height: 30px;
  transform: translateX(-50%);
}

.current-time-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  transform: translateX(-50%);
  z-index: 10;
  height: 100%;
}

.current-time-indicator {
  position: absolute;
  top: -20px;
  left: -15px;
  background-color: #ff4d4f;
  color: white;
  padding: 2px 5px;
  border-radius: 3px;
  font-size: 10px;
  white-space: nowrap;
}
.info-item-content {
  display: flex;
  width: 100%;
}
/* 左侧信息颜色区分 */
.order-code {
  color: #1a73e8; /* 谷歌蓝 - 专业稳重 */
  font-weight: bold;
}

.part-code {
  color: #34a853; /* 谷歌绿 - 清新自然 */
  font-weight: bold;
}

.batch-no {
  color: #fbbc05; /* 谷歌黄 - 温暖明亮 */
  font-weight: bold;
  flex: 0 0 100px; /* 固定宽度80px，不伸缩 */
}

.make-qty {
  color: #ea4335; /* 谷歌红 - 醒目突出 */
  font-weight: bold;
  flex: 1; /* 均匀分配剩余空间 */
}

.product-ident {
  color: #9c27b0; /* 紫色 - 优雅独特 */
  font-weight: bold;
  flex: 1; /* 均匀分配剩余空间 */
}

.priority-aps {
  color: #ff6d01; /* 橙色 - 温暖活力 */
  font-weight: bold;
  flex: 0 0 90px; /* 固定宽度80px，不伸缩 */
  text-align: right;
  padding-right: 15px;
}
</style>
