<!-- eslint-disable vue/max-attributes-per-line -->
<template>
  <div id="screen" class="allShow" :style="{
    width: `${style.width}px`,
    height: `${style.height}px`,
    transform: `${style.transform}`,
  }">
    <button class="route-switch-btn" @click="switchToTV1">切换TV1</button>

    <div class="title-png">
      <span class="title-text">大陆架零部件智能生产线数字孪生系统</span>
      <div class="df-header__right">
        <div class="df-header__timebar">
          <span class="df-header__year">{{ headerDateCn }}</span>
          <span class="df-header__time">{{ headerTime }}</span>
        </div>
      </div>
      <!-- <img style="
        width: 200px;
        height: 30px;
        position: absolute;
        left: 55px;
        top: 20px;
      " src="/png/logo.png" alt="东方理工大学logo" /> -->
    </div>
    <div class="leftLine"></div>
    <div class="rightLine"></div>
    <!-- <button class="button1" @click="togglePanelLayout" :style="buttonStyle"></button> -->
    <div class="main-content">
      <iframe
            id="dmtIframe"
            :src="iframeAddress"
            style="
              width: 100%;
              height: 100%;
              border: none;
              filter: blur(10);
              z-index: 100;
            " />
      <div v-show="!isPanelCollapsed" class="left-box">
        <div class="realtimeTask-box">
          <div class="left-title-header">
            <span class="left-title-text">生产任务</span>
          </div>
          <div class="realtime-task-grid">
            <div class="realtime-task-item">
              <span class="realtime-task-label">订单号</span>
              <span class="realtime-task-value">{{ realtimeTaskInfo.orderNo }}</span>
            </div>
            <div class="realtime-task-item">
              <span class="realtime-task-label">物料号</span>
              <span class="realtime-task-value">{{ realtimeTaskInfo.materialNo }}</span>
            </div>
            <div class="realtime-task-item">
              <span class="realtime-task-label">数量</span>
              <span class="realtime-task-value">{{ realtimeTaskInfo.quantity }}</span>
            </div>
          </div>
        </div>
        <!-- 工单加工时长统计模块 -->
        <div class="component-maintenance-box">
          <div class="left-title-header">
            <span class="left-title-text">工单加工时长统计</span>
          </div>
          <div class="component-maintenance-body">
            <div id="workOrderChart" class="component-maintenance-chart" />
          </div>
        </div>

        <!-- 设备状态模块 -->
        <div class="device-status-box">
          <div class="left-title-header">
            <span class="left-title-text">设备状态</span>
          </div>
          <div class="device-status-body">
            <div class="device-status-table">
              <div class="device-status-row device-status-row--header">
                <div class="device-status-cell">工位</div>
                <div class="device-status-cell">工位名称</div>
                <div class="device-status-cell">手自动</div>
                <div class="device-status-cell">状态</div>
              </div>
              <div v-for="(row, index) in deviceStatusList" :key="index" class="device-status-row">
                <div class="device-status-cell">{{ row.station }}</div>
                <div class="device-status-cell">{{ row.stationName }}</div>
                <div class="device-status-cell">{{ row.mode }}</div>
                <div class="device-status-cell">
                  <span class="device-status-pill" :class="`device-status-pill--${row.statusType}`">
                    {{ row.statusText }}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div v-show="!isPanelCollapsed" class="right-box">
        <!-- 加工中心7日工作时长统计模块 -->
        <div class="daily-output-box">
          <div class="right-title-header">
            <span class="right-title-text">加工中心7日工作时长统计</span>
          </div>
          <div class="daily-output-body">
            <div id="machiningCenterChart" class="daily-output-chart" />
          </div>
        </div>

        <!-- 实时状态模块 -->
        <div class="storage-status-box">
          <div class="right-title-header">
            <span class="right-title-text">实时状态</span>
          </div>
          <div class="storage-status-body now-status-body">
            <div class="now-status-fixed-row">
              <div class="now-status-fixed-label">设备状态</div>
              <div class="now-status-indicators">
                <div v-for="item in nowStatusIndicators" :key="item.label" class="now-status-indicator-item">
                  <span class="now-status-circle" :class="{ 'now-status-circle--active': item.active }" :style="{
                    backgroundColor: item.active ? getNowStatusCircleColor(item.label) : '#909399'
                  }"></span>
                  <span class="now-status-indicator-label">{{ item.label }}</span>
                </div>
              </div>
            </div>

            <div class="now-status-scroll-container">
              <scroll
                class="now-status-scroll-wrapper"
                :data="nowStatusList"
                :class-option="nowStatusScrollOption"
              >
                <div class="now-status-scroll-content">
                  <div v-for="item in nowStatusList" :key="item.key" class="now-status-row">
                    <div class="now-status-row-label">{{ item.label }}</div>
                    <div class="now-status-row-value">{{ item.value }}</div>
                  </div>
                </div>
              </scroll>
            </div>
          </div>
        </div>
      </div>

      <!-- 设备运行履历模块 -->
      <div v-show="!isPanelCollapsed" class="status-timeline-box">
        <div class="status-timeline-header"></div>
        <div class="bb-chart-container bb-chart-container--timeline">
          <div id="dashboardDeviceStatus" class="bb-chart bb-chart--status" />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import 'echarts-gl'
import scroll from 'vue-seamless-scroll'
export default {
  name: 'DaLuJiaTV2',
  components: { scroll },
  data() {
    return {
      style: {
        width: '1920',
        height: '1080',
        transform: 'scaleY(1) scaleX(1) translate(-50%, -50%)'
      },
      isPanelCollapsed: false,
      workstationStatusLoading: false,
      workstationStatusTimer: null,
      equipmentRuntimeHistoryLoading: false,
      equipmentRuntimeHistoryRefreshTimer: null,
      nowStatusLoading: false,
      nowStatusRefreshTimer: null,
      nowStatusIndicators: [
        { label: '关机', active: false },
        { label: '待机', active: false },
        { label: '运行', active: false },
        { label: '报警', active: false }
      ],
      nowStatusList: [
        { key: 'status', label: 'status', value: '待机' }
      ],
      deviceStatusList: [
        {
          station: 'OP1010',
          stationName: '3D打印机',
          mode: '自动',
          statusText: '运行',
          statusType: 'running'
        },
        {
          station: 'OP1010',
          stationName: '加工单元',
          mode: '自动',
          statusText: '报警',
          statusType: 'alarm'
        },
        {
          station: 'OP1010',
          stationName: '检测',
          mode: '自动',
          statusText: '待机',
          statusType: 'standby'
        },
        {
          station: 'OP1010',
          stationName: '装配',
          mode: '自动',
          statusText: '运行',
          statusType: 'running'
        },
        {
          station: 'OP1010',
          stationName: '打标',
          mode: '自动',
          statusText: '离线',
          statusType: 'offline'
        }
      ],
      deviceStatusChart: null, // 设备运行状态图表
      workOrderChart: null, // 工单加工时长统计图表
      machiningCenterChart: null, // 加工中心7日工作时长统计图表
      workOrderLoading: false,
      workOrderRefreshTimer: null,
      realtimeTaskLoading: false,
      realtimeTaskRefreshTimer: null,
      realtimeTaskInfo: {
        orderNo: '--',
        materialNo: '--',
        quantity: '--'
      },
      // 加工中心7日工作时长数据
      machiningCenterDates: [],
      machiningCenterValues: [],
      machiningCenterLoading: false,
      machiningCenterRefreshTimer: null,
      // 工单加工时长数据
      workOrderNames: [],
      workOrderHours: [],
      date: new Date(),
      iframe: '',
      iframeAddress: '',
      handleWindowResize: null,
      lastWorkstationStatusSignature: ''
    }
  },
  created() {
    this.iframe = document.getElementById('dmtIframe')
    this.iframeAddress = window.dt_Config?.iframeAddress
    this.loadEquipmentRuntimeHistory() // 历史_工位设备状态每分钟记录_查询
    this.loadNowStatusData() // 当前_设备数据_查询
    this.loadWorkstationStatus() // 基础_工位_查询
    this.setScale()
  },
  mounted() {
    this.timer = setInterval(() => {
      this.date = new Date()
    }, 1000)
    this.initEcharts()
    this.startEquipmentRuntimeHistoryRefresh() // 每分钟刷新一次设备运行履历
    this.startWorkOrderRefresh() // 每分钟刷新一次工单加工时长统计
    this.startMachiningCenterRefresh() // 每分钟刷新一次加工中心7日工作时长统计
    this.startWorkstationStatusRefresh() // 每2秒刷新一次设备状态（调用存储过程：基础_工位_查询）
    this.startNowStatusRefresh() // 每2秒刷新一次实时状态（调用存储过程：当前_设备数据_查询）
    this.startRealtimeTaskRefresh() // 每2秒刷新一次生产任务实时信息
    this.setScale()
    this.handleWindowResize = () => {
      this.setScale()
      if (this.machiningCenterChart) this.machiningCenterChart.resize()
      if (this.workOrderChart) this.workOrderChart.resize()
      if (this.deviceStatusChart) this.deviceStatusChart.resize()
    }
    window.addEventListener('resize', this.handleWindowResize)
  },
  beforeDestroy() {
    if (this.timer) {
      clearInterval(this.timer)
      this.timer = null
    }
    if (this.machiningCenterRefreshTimer) {
      clearInterval(this.machiningCenterRefreshTimer)
      this.machiningCenterRefreshTimer = null
    }
    if (this.workstationStatusTimer) {
      clearInterval(this.workstationStatusTimer)
      this.workstationStatusTimer = null
    }
    if (this.nowStatusRefreshTimer) {
      clearInterval(this.nowStatusRefreshTimer)
      this.nowStatusRefreshTimer = null
    }
    if (this.equipmentRuntimeHistoryRefreshTimer) {
      clearInterval(this.equipmentRuntimeHistoryRefreshTimer)
      this.equipmentRuntimeHistoryRefreshTimer = null
    }
    if (this.workOrderRefreshTimer) {
      clearInterval(this.workOrderRefreshTimer)
      this.workOrderRefreshTimer = null
    }
    if (this.realtimeTaskRefreshTimer) {
      clearInterval(this.realtimeTaskRefreshTimer)
      this.realtimeTaskRefreshTimer = null
    }
    if (this.handleWindowResize) {
      window.removeEventListener('resize', this.handleWindowResize)
      this.handleWindowResize = null
    }
    if (this.deviceStatusChart) {
      this.deviceStatusChart.dispose()
      this.deviceStatusChart = null
    }
    if (this.workOrderChart) {
      this.workOrderChart.dispose()
      this.workOrderChart = null
    }
    if (this.machiningCenterChart) {
      this.machiningCenterChart.dispose()
      this.machiningCenterChart = null
    }
  },
  computed: {
    nowStatusScrollOption() {
      return {
        step: 0.5,
        limitMoveNum: 6,
        hoverStop: true,
        direction: 1,
        openTouch: false,
        singleHeight: 40,
        waitTime: 1000,
        autoPlay: this.nowStatusList.length > 6
      }
    },
    headerTime() {
      const d = this.date instanceof Date ? this.date : new Date()
      const hh = String(d.getHours()).padStart(2, '0')
      const mm = String(d.getMinutes()).padStart(2, '0')
      const ss = String(d.getSeconds()).padStart(2, '0')
      return `${hh}:${mm}:${ss}`
    },
    headerDate() {
      const d = this.date instanceof Date ? this.date : new Date()
      const y = d.getFullYear()
      const m = String(d.getMonth() + 1).padStart(2, '0')
      const day = String(d.getDate()).padStart(2, '0')
      return `${y}/${m}/${day}`
    },
    headerDateCn() {
      const d = this.date instanceof Date ? this.date : new Date()
      const y = d.getFullYear()
      const m = d.getMonth() + 1
      const day = d.getDate()
      return `${y}-${m}-${day}`
    }
  },
  methods: {
    switchToTV1() {
      if (this.$route.path !== '/') {
        this.$router.push('/')
      }
    },
    getScale() {
      const w = window.innerWidth / this.style.width
      const h = window.innerHeight / this.style.height
      return { x: w, y: h }
    },
    // 实时状态模块：数据库定时刷新
    startNowStatusRefresh() {
      if (this.nowStatusRefreshTimer) {
        clearInterval(this.nowStatusRefreshTimer)
        this.nowStatusRefreshTimer = null
      }
      this.nowStatusRefreshTimer = setInterval(() => {
        this.loadNowStatusData()
      }, 2000)
      this.loadNowStatusData()
    },
    getNowStatusCircleColor(label) {
      const colorMap = {
        关机: 'grey',
        待机: 'orange',
        运行: 'green',
        报警: 'red'
      }
      return colorMap[label] || 'grey'
    },
    updateNowStatusIndicator(statusCode) {
      this.nowStatusIndicators.forEach((item) => {
        item.active = false
      })
      const statusMap = {
        '-1': 0,
        0: 1,
        1: 2,
        2: 3
      }
      const statusIndex = statusMap[String(statusCode).trim()]
      if (statusIndex !== undefined && this.nowStatusIndicators[statusIndex]) {
        this.nowStatusIndicators[statusIndex].active = true
      }
    },
    mapNowStatusText(statusCode) {
      const textMap = {
        '-1': '关机',
        0: '待机',
        1: '运行',
        2: '报警'
      }
      return textMap[String(statusCode).trim()] || String(statusCode || '--').trim()
    },
    applyNowStatusData(tagList) {
      const list = Array.isArray(tagList) ? tagList : []
      const statusRow = list.find((item) => {
        const tagName = item && (item.TagName != null ? item.TagName : item['TagName'])
        return String(tagName || '').trim() === '设备状态'
      })
      const statusValue = statusRow && (statusRow.TagValue != null ? statusRow.TagValue : statusRow['TagValue'])
      this.updateNowStatusIndicator(statusValue)
      this.nowStatusList = list
        .filter((item) => {
          const tagName = item && (item.TagName != null ? item.TagName : item['TagName'])
          return String(tagName || '').trim() !== '设备状态'
        })
        .map((item, index) => {
          const tagName = item && (item.TagName != null ? item.TagName : item['TagName'])
          const rawValue = item && (item.TagValue != null ? item.TagValue : item['TagValue'])
          return {
            key: `${String(tagName || 'tag')}-${index}`,
            label: String(tagName || '--'),
            value: String(rawValue != null ? rawValue : '--')
          }
        })
    },
    loadNowStatusData() {
      if (this.nowStatusLoading) return
      this.nowStatusLoading = true
      const param = []
      const data = this.CreateData('11', '当前_设备数据_查询', param)
      this.ExecDatabase(data)
        .then((response) => {
          const list = response && response.data ? response.data : null
          if (Array.isArray(list)) {
            this.applyNowStatusData(list)
          } else {
            this.nowStatusList = []
          }
        })
        .catch((err) => {
          console.error('实时状态数据获取失败', err)
          this.nowStatusList = []
        })
        .finally(() => {
          this.nowStatusLoading = false
        })
    },
    setScale() {
      const scale = this.getScale()
      this.style.transform =
        'scaleY(' + scale.y + ') scaleX(' + scale.x + ') translate(-50%, -50%)'
    },
    startToolUseTimeRefresh() {
      if (this.toolUseTimeRefreshTimer) {
        clearInterval(this.toolUseTimeRefreshTimer)
        this.toolUseTimeRefreshTimer = null
      }
      this.toolUseTimeRefreshTimer = setInterval(() => {
        this.loadToolUseTimeData()
      }, 60 * 1000)
    },
    startRealtimeTaskRefresh() {
      if (this.realtimeTaskRefreshTimer) {
        clearInterval(this.realtimeTaskRefreshTimer)
        this.realtimeTaskRefreshTimer = null
      }
      this.realtimeTaskRefreshTimer = setInterval(() => {
        this.loadRealtimeTaskData()
      }, 2000)
      this.loadRealtimeTaskData()
    },
    loadRealtimeTaskData() {
      if (this.realtimeTaskLoading) return
      this.realtimeTaskLoading = true
      const param = []
      const data = this.CreateData('11', '接口_生产任务_实时_查询', param)
      this.ExecDatabase(data)
        .then((response) => {
          const list = response && response.data ? response.data : null
          const row = Array.isArray(list) && list.length > 0 ? list[0] : null
          this.realtimeTaskInfo = {
            orderNo: row && row['计划号'] != null ? String(row['计划号']) : '--',
            materialNo: row && row['物料号'] != null ? String(row['物料号']) : '--',
            quantity: row && row['数量'] != null ? String(row['数量']) : '--'
          }
        })
        .catch((err) => {
          console.error('接口_生产任务_实时_查询失败', err)
          this.realtimeTaskInfo = {
            orderNo: '--',
            materialNo: '--',
            quantity: '--'
          }
        })
        .finally(() => {
          this.realtimeTaskLoading = false
        })
    },
    togglePanelLayout() {
      this.isPanelCollapsed = !this.isPanelCollapsed
    },
    initEcharts() {
      // 设备运行履历甘特图
      this.deviceStatusChart = echarts.init(
        document.getElementById('dashboardDeviceStatus'),
      )
      // 工单加工时长统计柱状图
      const workOrderEl = document.getElementById('workOrderChart')
      if (workOrderEl) {
        this.workOrderChart = echarts.init(workOrderEl)
        this.loadWorkOrderData()
      }
      // 加工中心7日工作时长统计柱状图
      const machiningCenterEl = document.getElementById('machiningCenterChart')
      if (machiningCenterEl) {
        this.machiningCenterChart = echarts.init(machiningCenterEl)
        this.initMachiningCenterData()
        this.drawMachiningCenterChart()
        this.loadMachiningCenterHistory()
      }
    },
    openModelInfoPopup({ left, top, ModelId, ModelName }) {
      this.modelInfoPopup.visible = true
      this.modelInfoPopup.loading = true
      this.modelInfoPopup.error = ''
      this.modelInfoPopup.base.ModelId = ModelId || ''
      this.modelInfoPopup.base.ModelName = ModelName || ''
      this.modelInfoPopup.detail = null
      this.modelInfoPopup.left = Number(left) || 0
      this.modelInfoPopup.top = Number(top) || 0
      this.$nextTick(() => {
        this.fixModelInfoPopupPosition()
      })
      this.fetchModelInfoPopupDetail(ModelId)
    },
    closeModelInfoPopup() {
      this.modelInfoPopup.visible = false
      this.modelInfoPopup.loading = false
      this.modelInfoPopup.error = ''
      this.modelInfoPopup.detail = null
    },
    fixModelInfoPopupPosition() {
      const el = this.$refs.modelInfoPopupRef
      if (!el) return
      const rect = el.getBoundingClientRect()
      const margin = 10
      let left = this.modelInfoPopup.left
      let top = this.modelInfoPopup.top
      const maxLeft = window.innerWidth - rect.width - margin
      const maxTop = window.innerHeight - rect.height - margin
      left = Math.max(margin, Math.min(left, maxLeft))
      top = Math.max(margin, Math.min(top, maxTop))
      this.modelInfoPopup.left = left
      this.modelInfoPopup.top = top
    },
    // 设备状态模块：每秒刷新一次（调用存储过程：基础_工位_查询）
    startWorkstationStatusRefresh() {
      if (this.workstationStatusTimer) {
        clearInterval(this.workstationStatusTimer)
        this.workstationStatusTimer = null
      }
      this.workstationStatusTimer = setInterval(() => {
        this.loadWorkstationStatus()
      }, 2000)
    },
    loadWorkstationStatus() {
      if (this.workstationStatusLoading) return
      this.workstationStatusLoading = true

      const param = [] // 无入参
      const data = this.CreateData('11', '基础_工位_查询', param)
      this.ExecDatabase(data)
        .then((response) => {
          const list = response && response.data ? response.data : null
          if (!Array.isArray(list)) return

          const mapStatus = (code) => {
            const c = Number(code)
            if (c === -1) return { statusText: '离线', statusType: 'offline' }
            if (c === 0) return { statusText: '待机', statusType: 'standby' }
            if (c === 1) return { statusText: '运行', statusType: 'running' }
            if (c === 2) return { statusText: '报警', statusType: 'alarm' }
            return { statusText: '未知', statusType: 'offline' }
          }

          const nextDeviceStatusList = list.map((item) => {
            const station =
              item && (item['工位号'] != null ? String(item['工位号']) : '')
            const stationName =
              item &&
              (item['工位名称'] != null ? String(item['工位名称']) : '')
            const statusCode =
              item && (item['状态代码'] != null ? item['状态代码'] : null)
            const st = mapStatus(statusCode)
            return {
              station,
              stationName,
              mode: '自动',
              statusText: st.statusText,
              statusType: st.statusType
            }
          })
          const signature = JSON.stringify(nextDeviceStatusList)
          if (signature !== this.lastWorkstationStatusSignature) {
            this.lastWorkstationStatusSignature = signature
            this.deviceStatusList = nextDeviceStatusList
          }
        })
        .catch((err) => {
          console.error('基础_工位_查询失败', err)
        })
        .then(() => {
          this.workstationStatusLoading = false
        })
    },
    // 每分钟刷新一次日产量历史数据
    startDailyOutputHistoryRefresh() {
      if (this.dailyOutputRefreshTimer) {
        clearInterval(this.dailyOutputRefreshTimer)
        this.dailyOutputRefreshTimer = null
      }
      this.dailyOutputRefreshTimer = setInterval(() => {
        this.loadDailyOutputHistory()
      }, 60 * 1000)
    },
    // 初始化日产量数据（首次为空，由存储过程填充）
    initDailyOutputData() {
      this.dailyOutputDates = []
      this.dailyOutputValues = []
    },
    // 拉取日产量历史数据（调用存储过程：历史_过站记录_日产量查询）
    loadDailyOutputHistory() {
      if (this.dailyOutputLoading) return
      if (!this.dailyOutputChart) return
      this.dailyOutputLoading = true

      const param4 = [] // 无入参
      const Data4 = this.CreateData('11', '历史_过站记录_日产量查询', param4)
      this.ExecDatabase(Data4)
        .then((response) => {
          const list = response && response.data ? response.data : null
          if (!Array.isArray(list) || list.length === 0) {
            // 查询不到数据：清空数据，在图表中显示“暂无最近七日产量数据”
            this.dailyOutputDates = []
            this.dailyOutputValues = []
            this.drawDailyOutputChart()
            return
          }

          // 存储过程按“日期 + 工位号”分组，这里忽略工位号，按日期汇总近七日产量
          const parseDate = (rawDate) => {
            if (rawDate == null) return null
            // 优先从字符串中直接截取 YYYY-MM-DD，避免时区造成的日期偏移
            if (typeof rawDate === 'string') {
              const m = rawDate.match(/^(\d{4})[-\/.](\d{1,2})[-\/.](\d{1,2})/)
              if (m) {
                const y = String(m[1]).padStart(4, '0')
                const mo = String(m[2]).padStart(2, '0')
                const da = String(m[3]).padStart(2, '0')
                const key = `${y}-${mo}-${da}`
                return {
                  key,
                  md: `${mo}-${da}`,
                  time: new Date(`${key}T00:00:00`).getTime()
                }
              }
            }
            const dt = rawDate instanceof Date ? rawDate : new Date(rawDate)
            if (!dt || Number.isNaN(dt.getTime())) return null
            const y = String(dt.getFullYear()).padStart(4, '0')
            const mo = String(dt.getMonth() + 1).padStart(2, '0')
            const da = String(dt.getDate()).padStart(2, '0')
            const key = `${y}-${mo}-${da}`
            return {
              key,
              md: `${mo}-${da}`,
              time: new Date(`${key}T00:00:00`).getTime()
            }
          }

          const sumByDate = new Map() // key: YYYY-MM-DD -> { md, time, sum }
          list.forEach((item) => {
            const rawDate =
              item && (item['日期'] != null ? item['日期'] : item.日期)
            const rawValue =
              item && (item['产量'] != null ? item['产量'] : item.产量)
            const d = parseDate(rawDate)
            if (!d) return
            const num = Number(rawValue)
            if (!Number.isFinite(num)) return
            const prev = sumByDate.get(d.key)
            if (prev) {
              prev.sum += num
            } else {
              sumByDate.set(d.key, { md: d.md, time: d.time, sum: num })
            }
          })

          const sorted = Array.from(sumByDate.values())
            .sort((a, b) => a.time - b.time)
            .slice(-7)
          const dates = sorted.map((d) => d.md)
          const values = sorted.map((d) => Math.round(Number(d.sum) || 0))

          this.dailyOutputDates = dates
          this.dailyOutputValues = values
          this.drawDailyOutputChart()
        })
        .catch((err) => {
          console.error('日产量历史查询失败', err)
          this.dailyOutputDates = []
          this.dailyOutputValues = []
          this.drawDailyOutputChart()
        })
        .then(() => {
          this.dailyOutputLoading = false
        })
    },
    // 绘制日产量折线图
    drawDailyOutputChart() {
      if (!this.dailyOutputChart) return
      const data = this.dailyOutputValues || []
      const dates = this.dailyOutputDates || []

      // 先清空，避免上一次的图形或文字残留
      this.dailyOutputChart.clear()

      // 如果没有任何数据，就只显示“暂无最近七日产量数据”提示
      if (!data.length || !dates.length) {
        const optionEmpty = {
          backgroundColor: 'transparent',
          animation: false,
          xAxis: { show: false, type: 'category', data: [] },
          yAxis: { show: false, type: 'value' },
          series: [],
          graphic: {
            type: 'text',
            left: 'center',
            top: 'middle',
            style: {
              text: '暂无最近七日产量数据',
              fill: '#fff',
              fontSize: 16,
              fontFamily: 'Microsoft YaHei'
            }
          }
        }
        this.dailyOutputChart.setOption(optionEmpty)
        return
      }

      const maxValue = Math.max.apply(null, data)
      const maxIndex = data.indexOf(maxValue)
      const lineColor = '#4fc3e8'
      const pointColor = '#dff8ff'
      const topAreaColor = 'rgba(79, 195, 232, 0.30)'
      const option = {
        backgroundColor: 'transparent',
        animation: false,
        grid: {
          top: '18%',
          bottom: '11%',
          left: '8%',
          right: '8%'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'line',
            lineStyle: {
              color: 'rgba(79, 195, 232, 0.45)'
            }
          },
          formatter: (params) => {
            const p = params && params[0]
            if (!p) return ''
            return `${p.axisValue}<br/>日产量：${p.value}`
          }
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: dates,
          axisLabel: {
            color: '#fff',
            fontSize: 10
          },
          axisLine: {
            show: true,
            lineStyle: { color: '#1B3F66' }
          },
          axisTick: { show: false }
        },
        yAxis: {
          type: 'value',
          axisLabel: {
            color: '#fff',
            fontSize: 10
          },
          axisLine: {
            show: true,
            lineStyle: { color: '#1B3F66' }
          },
          splitLine: {
            lineStyle: { color: 'rgba(27, 63, 102, 0.6)' }
          }
        },
        graphic: [],
        series: [
          {
            type: 'line',
            name: '日产量',
            smooth: false,
            showSymbol: true,
            symbol: 'circle',
            symbolSize: 5,
            data: data,
            lineStyle: {
              color: lineColor,
              width: 1
            },
            itemStyle: {
              color: pointColor,
              borderColor: lineColor,
              borderWidth: 2
            },
            areaStyle: {
              color: {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [
                  { offset: 0, color: topAreaColor },
                  { offset: 1, color: 'rgba(79, 195, 232, 0)' }
                ]
              }
            },
            markPoint: {
              symbol: 'circle',
              symbolSize: 5,
              itemStyle: {
                color: pointColor,
                borderColor: lineColor,
                borderWidth: 2
              },
              label: {
                show: true,
                position: 'top',
                distance: 10,
                color: '#dff8ff',
                fontSize: 12,
                fontWeight: 'bold',
                formatter: 'Max:{c}'
              },
              data: [
                {
                  coord: [dates[maxIndex], maxValue],
                  value: maxValue
                }
              ]
            },
            emphasis: {
              focus: 'series'
            }
          }
        ]
      }
      this.dailyOutputChart.setOption(option)
    },

    getMaintenanceAxisMax(values) {
      const maxVal = Math.max(...values, 1)
      const roughStep = maxVal / 5
      const pow10 = Math.pow(10, Math.floor(Math.log10(roughStep)))
      const normalized = roughStep / pow10
      let step
      if (normalized <= 1) step = 1 * pow10
      else if (normalized <= 2) step = 2 * pow10
      else if (normalized <= 5) step = 5 * pow10
      else step = 10 * pow10
      return Math.ceil(maxVal / step) * step
    },
    // 每分钟刷新一次设备运行履历（调用存储过程：历史_工位设备状态每分钟记录_查询）
    startEquipmentRuntimeHistoryRefresh() {
      if (this.equipmentRuntimeHistoryRefreshTimer) {
        clearInterval(this.equipmentRuntimeHistoryRefreshTimer)
        this.equipmentRuntimeHistoryRefreshTimer = null
      }
      this.equipmentRuntimeHistoryRefreshTimer = setInterval(() => {
        this.loadEquipmentRuntimeHistory()
      }, 60 * 1000)
    },
    // 查询设备运行履历（调用存储过程：历史_工位设备状态每分钟记录_查询，过去24小时）
    loadEquipmentRuntimeHistory() {
      if (this.equipmentRuntimeHistoryLoading) return
      this.equipmentRuntimeHistoryLoading = true
      const endTime = new Date()
      const startTime = new Date(endTime.getTime() - 24 * 60 * 60 * 1000) // 近24小时
      const fmt = (d) => this.formatDateTime(d)
      const param4 = [
        ['开始时间', fmt(startTime)],
        ['结束时间', fmt(endTime)],
        ['记录条数', '2000']
      ]
      const Data4 = this.CreateData(
        '11',
        '历史_工位设备状态每分钟记录_查询',
        param4,
      )
      this.ExecDatabase(Data4)
        .then((response) => {
          const list = response.data
          if (Array.isArray(list) && list.length > 0) {
            this.processEquipmentRuntimeData(list)
          } else {
            this.deviceStatusTable = []
          }
          this.drawDeviceStatusChart()
        })
        .catch((err) => {
          console.error('设备运行履历数据获取失败', err)
          this.deviceStatusTable = []
          this.drawDeviceStatusChart()
        })
        .finally(() => {
          this.equipmentRuntimeHistoryLoading = false
        })
    },
    // 处理设备运行履历数据
    processEquipmentRuntimeData(records) {
      this.deviceStatusTable = records.map((record) => ({
        工位号: record.工位号 || '设备1',
        设备状态: record.设备状态,
        创建时间: record.创建时间
      }))
    },
    // 格式化日期时间
    formatDateTime(date) {
      const year = date.getFullYear()
      const month = (date.getMonth() + 1).toString().padStart(2, '0')
      const day = date.getDate().toString().padStart(2, '0')
      const hours = date.getHours().toString().padStart(2, '0')
      const minutes = date.getMinutes().toString().padStart(2, '0')
      const seconds = date.getSeconds().toString().padStart(2, '0')
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
    },
    drawDeviceStatusChart() {
      if (!this.deviceStatusChart) {
        return
      }
      const hasData =
        Array.isArray(this.deviceStatusTable) &&
        this.deviceStatusTable.length > 0
      if (!hasData) {
        this.deviceStatusChart.clear()
        this.deviceStatusChart.setOption(
          {
            backgroundColor: 'transparent',
            xAxis: { show: false, type: 'time' },
            yAxis: { show: false, type: 'category', data: [] },
            series: [],
            graphic: {
              type: 'text',
              left: 'center',
              top: 'middle',
              style: {
                text: '未查询到设备运行履历',
                fill: '#fff',
                fontSize: 16,
                fontFamily: 'Microsoft YaHei'
              }
            }
          },
          true,
        )
        return
      }
      // 设备状态映射
      const statusMap = {
        '-1': {
          name: '离线',
          color: '#878787'
        },
        0: {
          name: '待机',
          color: '#d49436'
        },
        1: {
          name: '运行',
          color: '#2d8f47'
        },
        2: {
          name: '报警',
          color: '#c23b48'
        }
      }
      // 处理数据，按工位号分组并按时间排序
      const groupedData = {}
      this.deviceStatusTable.forEach((item) => {
        const workstation = item.工位号 || 'OP10'
        if (!groupedData[workstation]) {
          groupedData[workstation] = []
        }
        groupedData[workstation].push(item)
      })
      // 对每组数据按时间排序
      Object.keys(groupedData).forEach((workstation) => {
        groupedData[workstation].sort(
          (a, b) =>
            new Date(a.创建时间).getTime() - new Date(b.创建时间).getTime(),
        )
      })
      // 构建图表数据 - 为每个状态创建一个系列
      const seriesData = []
      const yAxisData = Object.keys(groupedData)
      // 为每个工位和状态创建数据
      yAxisData.forEach((workstation, yIndex) => {
        const records = groupedData[workstation]
        records.forEach((record, index) => {
          const statusInfo = statusMap[String(record.设备状态)] || {
            name: '未知',
            color: '#909399'
          }
          // 计算结束时间
          let endTime
          if (index === records.length - 1) {
            const startTime = new Date(record.创建时间)
            endTime = new Date(startTime.getTime() + 60000) // 默认1分钟
          } else {
            endTime = new Date(records[index + 1].创建时间)
          }
          const startTime = new Date(record.创建时间)
          // 确保开始时间小于结束时间
          if (startTime.getTime() < endTime.getTime()) {
            seriesData.push({
              name: statusInfo.name,
              value: [
                workstation, // y轴类别
                startTime.getTime(), // 开始时间
                endTime.getTime(), // 结束时间
                statusInfo.name // 状态名称
              ],
              itemStyle: {
                color: statusInfo.color,
                shadowBlur: 8,
                shadowColor: statusInfo.shadowColor || 'rgba(0, 0, 0, 0.25)',
                shadowOffsetX: 0,
                shadowOffsetY: 0
              }
            })
          }
        })
      })
      // 创建配置选项
      const option = {
        backgroundColor: 'transparent',
        animation: false,
        tooltip: {
          trigger: 'item',
          formatter: function(params) {
            const data = params.value
            const startTime = new Date(data[1])
            const endTime = new Date(data[2])
            const startStr = `${startTime
              .getHours()
              .toString()
              .padStart(2, '0')}:${startTime
              .getMinutes()
              .toString()
              .padStart(2, '0')}`
            const endStr = `${endTime
              .getHours()
              .toString()
              .padStart(2, '0')}:${endTime
              .getMinutes()
              .toString()
              .padStart(2, '0')}`
            return `${data[3]}<br/>${data[0]}<br/>${startStr} ~ ${endStr}`
          },
          backgroundColor: 'rgba(0, 0, 0, 0.8)',
          textStyle: { color: '#fff' },
          borderColor: 'rgba(255, 255, 255, 0.3)',
          borderWidth: 1,
          confine: true,
          position: function(point, params, dom, rect, size) {
            const mouseX = point[0]
            const mouseY = point[1]
            const tooltipWidth = size.contentSize[0]
            const tooltipHeight = size.contentSize[1]
            const chartWidth = size.viewSize[0]
            const chartHeight = size.viewSize[1]
            // 默认显示在鼠标上方
            let x = mouseX - tooltipWidth / 2
            let y = mouseY - tooltipHeight - 10
            // 水平边界检查
            x = Math.max(5, Math.min(x, chartWidth - tooltipWidth - 5))
            // 垂直边界检查 - 确保不超出顶部
            if (y < 0) {
              // 上方放不下，放到鼠标下方
              y = mouseY + 20 // 增加下方偏移量，避免紧贴鼠标
            }
            // 检查是否超出底部
            if (y + tooltipHeight > chartHeight) {
              // 超出底部，尝试放回上方
              y = mouseY - tooltipHeight - 20
              // 如果上方也放不下，就放在图表顶部，留出边距
              if (y < 0) {
                y = 10 // 固定在顶部，留10px边距
              }
            }
            // 最终检查：确保整个tooltip都在可视区域内
            y = Math.max(5, Math.min(y, chartHeight - tooltipHeight - 5))
            return [x, y]
          }
        },
        grid: {
          left: '2%',
          right: '5%',
          bottom: '8%',
          top: '7%',
          containLabel: true
        },
        xAxis: {
          type: 'time',
          axisLine: { show: false, lineStyle: { color: '#fff' }},
          axisLabel: {
            show: true,
            color: '#fff',
            fontSize: 15,
            formatter: function(value) {
              const date = new Date(value)
              return `${date.getHours().toString().padStart(2, '0')}:${date
                .getMinutes()
                .toString()
                .padStart(2, '0')}`
            }
          },
          splitLine: { lineStyle: { color: 'rgba(255, 255, 255, 0.1)' }}
        },
        yAxis: {
          type: 'category',
          data: yAxisData,
          axisLine: { show: false, lineStyle: { color: '#fff' }},
          axisLabel: { color: '#fff', fontSize: 15, show: true },
          splitLine: { show: false }
        },
        series: [
          {
            type: 'custom',
            name: '设备状态',
            renderItem: function(params, api) {
              try {
                const categoryIndex = api.value(0)
                const start = api.coord([api.value(1), categoryIndex])
                const end = api.coord([api.value(2), categoryIndex])
                if (!start || !end || start[0] === end[0]) {
                  return null
                }
                const height = api.size([0, 1])[1] * 0.6
                return {
                  type: 'rect',
                  shape: {
                    x: start[0],
                    y: start[1] - height / 2,
                    width: Math.max(end[0] - start[0], 1),
                    height: height
                  },
                  style: api.style()
                }
              } catch (error) {
                return null
              }
            },
            encode: {
              x: [1, 2],
              y: 0
            },
            data: seriesData
          }
        ]
      }

      this.deviceStatusChart.setOption(option, true)
    },
    // 每分钟刷新一次工单加工时长统计
    startWorkOrderRefresh() {
      if (this.workOrderRefreshTimer) {
        clearInterval(this.workOrderRefreshTimer)
        this.workOrderRefreshTimer = null
      }
      this.workOrderRefreshTimer = setInterval(() => {
        this.loadWorkOrderData()
      }, 60000)
    },
    loadWorkOrderData() {
      if (this.workOrderLoading) return
      if (!this.workOrderChart) return

      const param = []
      const data = this.CreateData('11', '历史_工位设备状态每分钟记录_工单查询', param)
      this.workOrderLoading = true
      this.ExecDatabase(data)
        .then((response) => {
          const list = response && response.data ? response.data : null
          if (!Array.isArray(list) || list.length === 0) {
            this.workOrderNames = []
            this.workOrderHours = []
            this.drawWorkOrderChart()
            return
          }

          const names = []
          const hours = []
          list.forEach((item) => {
            const orderNo = item && (item['订单号'] != null ? String(item['订单号']) : '')
            const workTime = item && (item['工作时长'] != null ? Number(item['工作时长']) : 0)
            if (orderNo) {
              names.push(orderNo)
              hours.push(Number.isFinite(workTime) ? workTime : 0)
            }
          })

          this.workOrderNames = names
          this.workOrderHours = hours
          this.drawWorkOrderChart()
        })
        .catch((error) => {
          console.error('工单加工时长统计数据获取失败', error)
          this.workOrderNames = []
          this.workOrderHours = []
          this.drawWorkOrderChart()
        })
        .finally(() => {
          this.workOrderLoading = false
        })
    },
    drawWorkOrderChart() {
      if (!this.workOrderChart) return

      const names = this.workOrderNames || []
      const hours = this.workOrderHours || []

      this.workOrderChart.clear()

      if (!names.length || !hours.length) {
        this.workOrderChart.setOption({
          backgroundColor: 'transparent',
          xAxis: { show: false, type: 'category', data: [] },
          yAxis: { show: false, type: 'value' },
          series: [],
          graphic: {
            type: 'text',
            left: 'center',
            top: 'middle',
            style: {
              text: '未查询到工单数据',
              fill: '#fff',
              fontSize: 16,
              fontFamily: 'Microsoft YaHei'
            }
          }
        }, true)
        return
      }

      const maxAxis = this.getMaintenanceAxisMax(hours)
      const buildBarGradient = (startColor, middleColor, endColor) => ({
        type: 'linear',
        x: 0,
        y: 0,
        x2: 1,
        y2: 0,
        colorStops: [
          { offset: 0, color: startColor },
          { offset: 0.55, color: middleColor },
          { offset: 1, color: endColor }
        ]
      })

      const option = {
        backgroundColor: 'transparent',
        animation: false,
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          },
          backgroundColor: 'rgba(0, 0, 0, 0.8)',
          textStyle: { color: '#fff' },
          borderColor: 'rgba(255, 255, 255, 0.3)',
          borderWidth: 1,
          formatter: function(params) {
            const p = params && params[0]
            if (!p) return ''
            return `${p.name}<br/>工作时长: ${p.value}分钟`
          }
        },
        grid: {
          left: '2%',
          right: '8%',
          bottom: '12%',
          top: '8%',
          containLabel: true
        },
        xAxis: {
          type: 'value',
          max: maxAxis,
          interval: maxAxis / 5,
          axisLabel: {
            color: '#ffffff',
            formatter: '{value}m'
          },
          axisLine: {
            show: false
          },
          splitLine: {
            lineStyle: {
              color: 'rgba(255, 255, 255, 0.1)'
            }
          }
        },
        yAxis: {
          type: 'category',
          data: names,
          inverse: true,
          axisLabel: {
            color: '#fff',
            fontSize: 12,
            interval: 0,
            lineHeight: 16,
            align: 'right',
            formatter: function(value) {
              if (!value) return ''
              if (value.length > 8) {
                const firstLine = value.slice(0, 8)
                const secondLine = value.slice(8)
                return `${firstLine}\n${secondLine}`
              }
              return value
            }
          },
          axisLine: {
            show: false
          },
          axisTick: {
            alignWithLabel: true
          }
        },
        series: [
          {
            type: 'bar',
            name: '工作时长',
            data: hours,
            barWidth: 12,
            itemStyle: {
              borderRadius: [0, 2, 2, 0],
              color: buildBarGradient(
                'rgba(143, 201, 255, 0.10)',
                '#4fc3e8',
                '#dff8ff',
              )
            },
            label: {
              show: true,
              position: 'right',
              color: '#dff8ff',
              fontSize: 11,
              formatter: '{c}min'
            }
          }
        ]
      }

      this.workOrderChart.setOption(option, true)
    },
    // 每分钟刷新一次加工中心7日工作时长统计
    startMachiningCenterRefresh() {
      if (this.machiningCenterRefreshTimer) {
        clearInterval(this.machiningCenterRefreshTimer)
        this.machiningCenterRefreshTimer = null
      }
      this.machiningCenterRefreshTimer = setInterval(() => {
        this.loadMachiningCenterHistory()
      }, 60 * 1000)
    },
    initMachiningCenterData() {
      this.machiningCenterDates = []
      this.machiningCenterValues = []
    },
    loadMachiningCenterHistory() {
      if (this.machiningCenterLoading) return
      if (!this.machiningCenterChart) return
      this.machiningCenterLoading = true

      const param = []
      const data = this.CreateData('11', '历史_工位设备状态每分钟记录_加工中心查询', param)
      this.ExecDatabase(data)
        .then((response) => {
          const list = response && response.data ? response.data : null
          if (!Array.isArray(list) || list.length === 0) {
            this.machiningCenterDates = []
            this.machiningCenterValues = []
            this.drawMachiningCenterChart()
            return
          }

          const parseDate = (rawDate) => {
            if (rawDate == null) return null
            if (typeof rawDate === 'string') {
              const m = rawDate.match(/^(\d{4})[-\/.](\d{1,2})[-\/.](\d{1,2})/)
              if (m) {
                const mo = String(m[2]).padStart(2, '0')
                const da = String(m[3]).padStart(2, '0')
                return `${mo}-${da}`
              }
            }
            const dt = rawDate instanceof Date ? rawDate : new Date(rawDate)
            if (!dt || Number.isNaN(dt.getTime())) return null
            const mo = String(dt.getMonth() + 1).padStart(2, '0')
            const da = String(dt.getDate()).padStart(2, '0')
            return `${mo}-${da}`
          }

          const dates = []
          const values = []
          list.forEach((item) => {
            const rawDate = item && (item['日期'] != null ? item['日期'] : item.日期)
            const rawValue = item && (item['工作时长'] != null ? item['工作时长'] : item.工作时长)
            const dateStr = parseDate(rawDate)
            if (!dateStr) return
            const num = Number(rawValue)
            if (!Number.isFinite(num)) return
            dates.push(dateStr)
            values.push(Math.round(num))
          })

          this.machiningCenterDates = dates
          this.machiningCenterValues = values
          this.drawMachiningCenterChart()
        })
        .catch((err) => {
          console.error('加工中心7日工作时长查询失败', err)
          this.machiningCenterDates = []
          this.machiningCenterValues = []
          this.drawMachiningCenterChart()
        })
        .finally(() => {
          this.machiningCenterLoading = false
        })
    },
    drawMachiningCenterChart() {
      if (!this.machiningCenterChart) return
      const data = this.machiningCenterValues || []
      const dates = this.machiningCenterDates || []

      this.machiningCenterChart.clear()

      if (!data.length || !dates.length) {
        const optionEmpty = {
          backgroundColor: 'transparent',
          animation: false,
          xAxis: { show: false, type: 'category', data: [] },
          yAxis: { show: false, type: 'value' },
          series: [],
          graphic: {
            type: 'text',
            left: 'center',
            top: 'middle',
            style: {
              text: '暂无最近七日工作时长',
              fill: '#fff',
              fontSize: 16,
              fontFamily: 'Microsoft YaHei'
            }
          }
        }
        this.machiningCenterChart.setOption(optionEmpty)
        return
      }

      const option = {
        backgroundColor: 'transparent',
        animation: false,
        grid: {
          top: '18%',
          bottom: '11%',
          left: '18%',
          right: '8%'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          },
          formatter: (params) => {
            const p = params && params[0]
            if (!p) return ''
            return `${p.axisValue}<br/>工作时长：${p.value}分钟`
          }
        },
        xAxis: {
          type: 'category',
          data: dates,
          axisLabel: {
            color: '#fff',
            fontSize: 10
          },
          axisLine: {
            show: true,
            lineStyle: { color: '#1B3F66' }
          },
          axisTick: { show: false }
        },
        yAxis: {
          type: 'value',
          axisLabel: {
            color: '#fff',
            fontSize: 10,
            formatter: '{value}分钟'
          },
          axisLine: {
            show: true,
            lineStyle: { color: '#1B3F66' }
          },
          splitLine: {
            lineStyle: { color: 'rgba(27, 63, 102, 0.6)' }
          }
        },
        series: [
          {
            type: 'bar',
            name: '工作时长',
            data: data,
            barWidth: 20,
            itemStyle: {
              borderRadius: [2, 2, 0, 0],
              color: {
                type: 'linear',
                x: 0,
                y: 1,
                x2: 0,
                y2: 0,
                colorStops: [
                  { offset: 0, color: 'rgba(79, 195, 232, 0.10)' },
                  { offset: 0.55, color: '#4fc3e8' },
                  { offset: 1, color: '#dff8ff' }
                ]
              }
            },
            label: {
              show: true,
              position: 'top',
              color: '#dff8ff',
              fontSize: 11,
              fontWeight: 'bold',
              formatter: '{c}'
            }
          }
        ]
      }
      this.machiningCenterChart.setOption(option)
    }
  }
}
</script>
<style>
HTML {
  overflow: auto;
}

body {
  margin: 0;
  padding: 0;
  width: 1920px;
  height: 1080px;
  overflow: hidden;
  position: relative;
  font-family: MiSans Bold, serif;
}

.route-switch-btn {
  position: absolute;
  left: 0px;
  top: 0px;
  z-index: 9999;
  width: 78px;
  height: 30px;
  background: rgba(5, 24, 55, 0.72);
  color: #dff8ff;
  font-size: 13px;
  line-height: 28px;
  text-align: center;
  cursor: pointer;
  box-shadow: 0 0 12px rgba(64, 205, 255, 0.35);
}

.route-switch-btn:hover {
  background: rgba(18, 80, 130, 0.88);
  color: #ffffff;
}

/*css主要部分的样式*/
/*定义滚动条宽高及背景，宽高分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar {
  width: 0px;
  /*对垂直流动条有效*/
  height: 0px;
  /*对水平流动条有效*/
}

/*定义滚动条的轨道颜色、内阴影及圆角*/
::-webkit-scrollbar-track {
  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
  background-color: rgb(14, 50, 97);
  /*background-color: #ffffff;*/
  border-radius: 2px;
}

/*定义滑块颜色、内阴影及圆角*/
::-webkit-scrollbar-thumb {
  border-radius: 5px;
  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
  background-color: rgb(10, 35, 82);
}

/*定义两端按钮的样式*/
::-webkit-scrollbar-button {
  display: none;
}

/*定义右下角汇合处的样式*/
::-webkit-scrollbar-corner {
  background: #dedede;
}
</style>
<style scoped="scoped">
.allShow {
  overflow-y: hidden;
  z-index: 100;
  transform-origin: 0 0;
  position: fixed;
  left: 50%;
  top: 50%;
  transition: 0.3s;
  background: url("/png/背景底图.png") no-repeat center center;
  background-size: cover;
  color: white;
}

.daily-output-box {
  width: 100%;
  height: 300px;
  overflow: hidden;
}

.left-title-header {
  width: 100%;
  height: 35px;
  background: url("/png/left.png") no-repeat center center;
  background-size: 100% 100%;
  display: flex;
  align-items: center;
  padding-left: 25px;
  box-sizing: border-box;
}
.left-title-text{
  font-size: 20px;
  font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", sans-serif;
}
.box-title {
  font-size: 25px;
  font-weight: 700;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", sans-serif;
}

.daily-output-body {
  width: 100%;
  height: calc(100% - 35px);
  box-sizing: border-box;
}

.daily-output-chart {
  width: 100%;
  height: 100%;
}

.storage-status-box {
  height: 600px;
  overflow: hidden;
}

.right-title-header {
  width: 100%;
  height: 35px;
  background: url("/png/right.png") no-repeat center center;
  background-size: 100% 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 25px;
  box-sizing: border-box;
}
.right-title-text{
  font-size: 20px;
  font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", sans-serif;
}
.storage-status-body {
  width: 100%;
  height: calc(100% - 35px);
  box-sizing: border-box;
  padding: 10px;
}

.now-status-body {
  position: relative;
  overflow: hidden;
}

.now-status-scroll-wrapper {
  height: 100%;
  overflow: hidden;
}

.now-status-fixed-row {
  display: grid;
  grid-template-columns: 95px 1fr;
  align-items: center;
  min-height: 42px;
  margin-bottom: 8px;
  padding: 6px 10px;
  box-sizing: border-box;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 6px;
}

.now-status-fixed-label {
  color: #fff;
  font-size: 16px;
  font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", sans-serif;
}

.now-status-indicators {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
}

.now-status-indicator-item {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}

.now-status-circle {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  display: inline-block;
  background: grey;
  transition: background-color 0.3s ease;
}

.now-status-circle--active {
  box-shadow: 0 0 8px currentColor;
}

.now-status-indicator-label {
  margin-left: 5px;
  color: #fff;
  font-size: 12px;
  white-space: nowrap;
  font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", sans-serif;
}

.now-status-scroll-container {
  position: relative;
  height: calc(100% - 50px);
  overflow: hidden;
}

.now-status-scroll-wrapper {
  height: 100%;
  overflow: hidden;
}

.now-status-scroll-content {
  width: 100%;
}

.now-status-row {
  display: grid;
  grid-template-columns: 110px 1fr;
  align-items: center;
  height: 40px;
  padding: 5px 10px;
  box-sizing: border-box;
  color: #fff;
  font-size: 15px;
  border-radius: 4px;
  transition: background-color 0.3s;
}

.now-status-row:hover {
  background: rgba(0, 112, 192, 0.2);
}

.now-status-row-label,
.now-status-row-value {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", sans-serif;
}

.realtimeTask-box {
  width: 100%;
  height: 250px;
  overflow: hidden;
}

.realtime-task-grid {
  width: 100%;
  height: calc(100% - 35px);
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  row-gap: 8px;
  padding: 10px;
  box-sizing: border-box;
}

.realtime-task-item {
  min-width: 0;
  display: grid;
  grid-template-columns: 78px 1fr;
  align-items: center;
  padding: 0 14px;
  box-sizing: border-box;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 4px;
}

.realtime-task-label {
  color: #cfe8ff;
  font-size: 16px;
  font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", sans-serif;
}

.realtime-task-value {
  color: #ffffff;
  font-size: 18px;
  font-weight: 700;
  text-align: right;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", sans-serif;
}

.component-maintenance-box {
  width: 100%;
  height: 350px;
  overflow: hidden;
}

.component-maintenance-body {
  width: 100%;
  height: calc(100% - 35px);
  box-sizing: border-box;
}

.component-maintenance-chart {
  width: 100%;
  height: 100%;
}

.device-status-box {
  width: 100%;
  height: 300px;
  overflow: hidden;
}

.device-status-body {
  width: 100%;
  height: calc(100% - 35px);
  box-sizing: border-box;
  padding: 8px;
}

.device-status-table {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.device-status-row {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  align-items: center;
  background: rgba(255, 255, 255, 0.12);
  border-radius: 4px;
  box-sizing: border-box;
  font-size: 13px;
  color: #ffffff;
}

.device-status-row--header {
  background: rgba(79, 131, 180, 0.5);
}

.device-status-cell {
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 15px;
  color: #fff;
  font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", sans-serif;
}

.device-status-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 2px 13px;
  border-radius: 10px;
  font-size: 15px;
  color: #ffffff;
  box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.35);
}

.device-status-pill--running {
  background: radial-gradient(circle at center, rgba(56, 136, 17, 0.3) 0%, rgba(56, 136, 17, 1) 100%);
}

.device-status-pill--alarm {
  background: radial-gradient(circle at center, rgba(210, 73, 86, 0.3) 0%, rgba(210, 73, 86, 1) 100%);
}

.device-status-pill--standby {
  background: radial-gradient(circle at center, rgba(204, 121, 0, 0.3) 0%, rgba(204, 121, 0, 1) 100%);
}

.device-status-pill--offline {
  background: radial-gradient(circle at center, rgba(135, 135, 135, 0.3) 0%, rgba(135, 135, 135, 1) 100%);
}

.df-header__right {
  position: absolute;
  top: 30px;
  right: 30px;
  width: 200px;
}

.df-header__timebar {
  display: flex;
  align-items: center;
  gap: 20px;
  color: #ffffff;
}

.df-header__time {
  order: 1;
  /* 确保时间在最左侧 */
}

.df-header__sep {
  opacity: 0.85;
  order: 2;
  /* 分隔符在中间 */
}

.df-header__date-wrapper {
  display: flex;
  flex-direction: column;
  /* 垂直排列 */
  align-items: flex-start;
  /* 右对齐 */
  gap: 2px;
  order: 3;
}

.df-header__year {
  font-size: 16px;
  /* 可以稍小一些 */
  line-height: 1.2;
}

.df-header__week {
  font-size: 14px;
  opacity: 0.85;
}

.other-params-label {
  padding: 10px 0;
}

.other-params-value {
  color: #ffcb6f;
  font-size: 20px;
  text-align: center;
}

.background {
  width: 1920px;
  height: 1080px;
  background-color: rgb(8, 31, 72);
  color: white;
  background-size: 100%;
}

/*表格透明写法*/
::v-deep .el-table,
.el-table__expanded-cell {
  background-color: transparent;
}

::v-deep .el-table th {
  background-color: transparent !important;
  color: #fefefe;
}

::v-deep .el-table tr {
  background-color: transparent !important;
}

::v-deep .el-table--enable-row-transition .el-table__body td,
::v-deep.el-table .cell {
  background-color: transparent;
  color: white;
  border: none;
  padding-left: 0 !important;
  padding-right: 0 !important;
}

::v-deep.el-table th>.cell {
  color: rgba(254, 254, 254, 1);
  font-weight: 700;
}

::v-deep .el-table td,
.el-table th {
  padding: 8px 0;
}

.el-table__body-wrapper::-webkit-scrollbar {
  /*width: 0;宽度为0隐藏*/
  width: 0;
}

.el-table::before {
  /*left: 0;*/
  /*bottom: 0;*/
  width: 100%;
  height: 0;
}

table {
  border-right: 1px solid #d7d7d7;
  border-bottom: 1px solid #d7d7d7;
  text-align: center;
}

table th {
  border-left: 1px solid #d7d7d7;
  border-top: 1px solid #d7d7d7;
}

table td {
  border-left: 1px solid #d7d7d7;
  border-top: 1px solid #d7d7d7;
}

/* 设备运行履历样式 */
.bb-chart-container {
  width: 100%;
  height: 110px;
  box-sizing: border-box;
  position: relative;
  min-height: 110px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.3);
}

.bb-chart-container--timeline {
  height: calc(100% - 35px);
  min-height: 0;
}

.bb-chart {
  width: 100% !important;
  height: 100% !important;
  min-height: 110px;
}

.main-content {
  height: 100%;
  width: 100%;
  position: absolute;
  top: 100px;
}
.status-timeline-box {
  position: absolute;
  left: 526px;
  top: 732px;
  width: 907px;
  height: 202px;
  overflow: hidden;
  background-image: url("/png/2.png");
  background-size: cover;
  background-repeat: no-repeat;
}

.status-timeline-header {
  width: 36%;
  height: 35px;
  background: url(/png/小标题-6.png) no-repeat center center;
  background-size: 100% 100%;
  display: flex;
  align-items: center;
  box-sizing: border-box;
  margin-top: 5px;
  margin-left: 16px;
}

.bb-chart--status {
  height: 100%;
  width: 100%;
  min-height: 0;
}

.title-png {
  position: absolute;
  top: 0;
  left: 0;
  height: 100px;
  width: 100%;
  background-image: url("/png/top1.png");
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
  pointer-events: none;
  display: flex;
  justify-content: center;
}

.title-text {
  color: #fff;
  font-size: 37px;
  font-weight: bold;
  text-align: center;
  margin-top: 15px;
  margin-right: 37px;
  font-family: "Microsoft YaHei", "\5FAE\8F6F\96C5\9ED1", "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.leftLine {
  z-index: 30;
  position: absolute;
  width: 54px;
  height: 1020px;
  top: 30px;
  left: 10px;
  margin-top: 20px;
  background-image: url(/png/左边条.png);
  background-size: 100% 100%;
  background-position: center;
}
.rightLine {
  z-index: 30;
  position: absolute;
  width: 54px;
  height: 1020px;
  top: 30px;
  right: 10px;
  margin-top: 20px;
  background-image: url(/png/右边条.png);
  background-size: 100% 100%;
  background-position: center;
}
.left-box {
  position: absolute;
  top: 0px;
  left: 30px;
  width: 336px;
  background-image: url(/png/1.png);
  background-size: cover;
  background-repeat: no-repeat;
  min-height: 724px;
}

.right-box {
  position: absolute;
  top: 0px;
  right: 30px;
  width: 336px;
  min-height: 724px;
  background-image: url(/png/1.png);
  background-size: cover;
  background-repeat: no-repeat;
}

.button1 {
  position: absolute;
  top: 100px;
  left: 0;
  width: 88px;
  height: 35px;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
  border: none;
  padding: 0;
  cursor: pointer;
  z-index: 20;
}

.cirle {
  pointer-events: none;
  background-image: url(/png/圆环.png);
  position: absolute;
  inset: 0;
  top: 20px;
  background-size: 95% 95%;
  background-repeat: no-repeat;
  background-position: center;
  border: none;
  padding: 0;
  z-index: 1;
}
</style>
