<script lang="ts" setup>
import * as echarts from 'echarts'
import '@vuepic/vue-datepicker/dist/main.css'
import {
  AlarmClock,
  Checked,
  Clock,
  CollectionTag,
  DataAnalysis,
  DocumentChecked,
  Files,
  Flag,
  Histogram,
  Odometer,
  Postcard,
  Warning,
  Search,
  Refresh
} from '@element-plus/icons-vue'
import {
  kanbanApi,
  IotDangerApi,
  IotHiddenApi,
  IotInstrumentApi,
  IotMeasureCertApi,
  IotCertificateApi
} from '@/api/pms/qhse/index'
import { useUserStore } from '@/store/modules/user'
import {
  ANIMATION,
  CHART_RENDERER,
  DESIGN_HEIGHT,
  DESIGN_WIDTH,
  FONT_FAMILY,
  THEME,
  createTooltip
} from '@/utils/kb'
import { DICT_TYPE, getBoolDictOptions, getStrDictOptions } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'

defineOptions({
  name: 'PmsQhseKanban'
})

type PermitStat = {
  label: string
  value: number
  color: string
}

type SafeDayMap = Record<string, number>
type SafeDayBarItem = {
  name: string
  value: number
}

type SummaryTabValue = 'home' | 'certificate'
type QhseMetricValue = 'ltir' | 'trir' | 'pmva'
const userStore = useUserStore()

const type = ref('day')

const handelChange = (value: any) => {
  console.log('Selected time:', value)
  // 在这里处理时间选择变化的逻辑，例如更新看板数据
}

function padDateValue(value: number) {
  return `${value}`.padStart(2, '0')
}

function formatDateValue(date = new Date()) {
  return `${date.getFullYear()}-${padDateValue(date.getMonth() + 1)}-${padDateValue(date.getDate())}`
}

function getCurrentPickerValue(pickerType: string) {
  const now = new Date()

  if (pickerType === 'year') {
    return `${now.getFullYear()}`
  }

  if (pickerType === 'month') {
    return `${now.getFullYear()}-${padDateValue(now.getMonth() + 1)}`
  }

  return formatDateValue(now)
}

const timeVal = ref(getCurrentPickerValue(type.value))

const wrapperRef = ref<HTMLDivElement>()
const hazardChartRef = ref<HTMLDivElement>()
const safeDayChartRef = ref<HTMLDivElement>()
const qhseTrendChartRef = ref<HTMLDivElement>()
const socChartRef = ref<HTMLDivElement>()
const scale = ref(1)
const supportsZoom = ref(false)

let resizeObserver: ResizeObserver | null = null
let resizeRaf = 0
let hazardChart: echarts.ECharts | null = null
let safeDayChart: echarts.ECharts | null = null
let qhseTrendChart: echarts.ECharts | null = null
let socChart: echarts.ECharts | null = null

const summaryTabs: Array<{ label: string; value: SummaryTabValue }> = [
  { label: '首页看板', value: 'home' },
  { label: '证书信息', value: 'certificate' }
]

const activeSummaryTab = ref<SummaryTabValue>('home')

watch(
  () => activeSummaryTab.value,
  async (value) => {
    if (value === 'certificate') {
      await getCertificateBoardList()
    } else {
      nextTick(() => {
        initHazardChart()
        initSafeDayChart()
        initQhseTrendChart()
        initSocChart()
        resizeHazardChart()
        resizeSafeDayChart()
        resizeQhseTrendChart()
        resizeSocChart()
      })
    }
  }
)

const pageTitle = computed(() =>
  activeSummaryTab.value === 'certificate' ? '证书信息看板' : 'QHSE管理看板'
)

const summaryCards = ref([
  {
    title: '人工时(小时)',
    value: 671987,
    note: '',
    accent: '#4f8dff',
    glow: 'rgba(79, 141, 255, 0.22)',
    icon: Clock
  },
  {
    title: '车辆里程(公里)',
    value: 631128,
    note: '',
    accent: '#4f8dff',
    glow: 'rgba(79, 141, 255, 0.22)',
    icon: Odometer
  },
  {
    title: '重大风险数量',
    value: 0,
    note: '',
    accent: '#ff5a62',
    glow: 'rgba(255, 90, 98, 0.26)',
    icon: Warning
  },
  {
    title: '特种人员持证率',
    value: 0,
    note: 'Warn: 0',
    accent: '#f2b800',
    glow: 'rgba(242, 184, 0, 0.22)',
    icon: Postcard
  },
  {
    title: '设备检测合规率',
    value: '98%',
    note: '',
    accent: '#f2b800',
    glow: 'rgba(242, 184, 0, 0.22)',
    icon: DataAnalysis
  },
  {
    title: '作业许可证数量',
    value: 0,
    note: '',
    accent: '#4f8dff',
    glow: 'rgba(79, 141, 255, 0.22)',
    icon: DocumentChecked
  }
])

const hazardBars = ref([
  { label: '总数', value: 0, color: '#4f8dff' },
  { label: '已整改', value: 0, color: '#43c7ca' },
  { label: '未整改', value: 0, color: '#ff981f' }
])

const riskZones = ref([
  { title: '', desc: '办公区 / 展厅 / 主通道', color: '#25b36a', value: 0 },
  { title: '', desc: '物料库 / 维修 / 装卸区', color: '#3d7cff', value: 0 },
  { title: '', desc: '焊接 / 机加 / 吊装区', color: '#ff9827', value: 0 },
  { title: '', desc: '危化库 / 试压区 / 配电房', color: '#ff5b61', value: 0 }
])

const permitStats = ref<PermitStat[]>([
  { label: '个人防护', value: 18, color: '#4f8dff' },
  { label: '规范操作', value: 26, color: '#43c7ca' },
  { label: '规范指挥', value: 12, color: '#ffb14a' },
  { label: '人员位置', value: 9, color: '#ff7a7a' },
  { label: '作业场所', value: 15, color: '#8d8cff' }
])

const qualificationWarnings = ref([
  { label: '证件过期', value: 0, accent: '#ff7a7a', key: 'expired' },
  { label: '即将到期', value: 0, accent: '#e6ab00', key: 'warn' }
])

const qhseMetricTabs = [
  { label: 'LTIR(百万工时)', value: 'ltir', accent: '#3d7cff', label2: '百万工时损失工时事故率' },
  { label: 'TRIR(百万工时)', value: 'trir', accent: '#17b6c5', label2: '百万工时总可记录事件率' },
  {
    label: 'PMVA(百万公里)',
    value: 'pmva',
    accent: '#f2a93b',
    label2: '百万公里可预防性交通事故率'
  }
] as const

const activeQhseMetric = ref<QhseMetricValue>('ltir')
const dangerGradeOptions = computed(() => getStrDictOptions(DICT_TYPE.DANGER_GRADE))

const qhseTrendSeries = ref<Record<QhseMetricValue, Array<{ year: string; value: number }>>>({
  ltir: [
    { year: '2026年1月', value: 0.42 },
    { year: '2026年2月', value: 0.39 },
    { year: '2026年3月', value: 0.36 },
    { year: '2026年4月', value: 0.34 },
    { year: '2026年5月', value: 0.31 },
    { year: '2026年6月', value: 0.29 },
    { year: '2026年7月', value: 0.27 },
    { year: '2026年8月', value: 0.25 },
    { year: '2026年9月', value: 0.24 },
    { year: '2026年10月', value: 0.22 },
    { year: '2026年11月', value: 0.21 },
    { year: '2026年12月', value: 0.2 }
  ],
  trir: [
    { year: '1月', value: 0.78 },
    { year: '2月', value: 0.75 },
    { year: '3月', value: 0.73 },
    { year: '4月', value: 0.7 },
    { year: '5月', value: 0.68 },
    { year: '6月', value: 0.66 },
    { year: '7月', value: 0.63 },
    { year: '8月', value: 0.61 },
    { year: '9月', value: 0.59 },
    { year: '10月', value: 0.57 },
    { year: '11月', value: 0.55 },
    { year: '12月', value: 0.54 }
  ],
  pmva: [
    { year: '1月', value: 0.22 },
    { year: '2月', value: 0.21 },
    { year: '3月', value: 0.2 },
    { year: '4月', value: 0.18 },
    { year: '5月', value: 0.17 },
    { year: '6月', value: 0.16 },
    { year: '7月', value: 0.15 },
    { year: '8月', value: 0.14 },
    { year: '9月', value: 0.14 },
    { year: '10月', value: 0.13 },
    { year: '11月', value: 0.12 },
    { year: '12月', value: 0.12 }
  ]
})

const bottomCards = ref([
  {
    title: '体系合规',
    icon: Files,
    accent: '#39c6cc',
    glow: 'rgba(57, 198, 204, 0.22)',
    lines: ['内审已完成', '外审待安排']
  },
  {
    title: '安全检测',
    icon: Histogram,
    accent: '#4f8dff',
    glow: 'rgba(79, 141, 255, 0.2)',
    lines: ['在用: 0台', '待检: 0项（重点关注）']
  },
  {
    title: '应急演练',
    icon: AlarmClock,
    accent: '#ff5b61',
    glow: 'rgba(255, 91, 97, 0.22)',
    lines: ['年度应急演练：80次']
  },
  {
    title: '职业健康',
    icon: Checked,
    accent: '#f2c11a',
    glow: 'rgba(242, 193, 26, 0.2)',
    lines: ['职业健康体检率', '98.7%（达标）']
  },
  {
    title: '危废管控',
    icon: Flag,
    accent: '#28c98b',
    glow: 'rgba(40, 201, 139, 0.2)',
    lines: ['危废暂存合规', '三废处置100%达标']
  }
])

const targetWrapperStyle = computed(() => ({
  width: `${DESIGN_WIDTH * scale.value}px`,
  height: `${DESIGN_HEIGHT * scale.value}px`
}))

const targetAreaStyle = computed(() => {
  const style = {
    width: `${DESIGN_WIDTH}px`,
    height: `${DESIGN_HEIGHT}px`,
    transformOrigin: '0 0'
  } as Record<string, string | number>

  if (supportsZoom.value) {
    style.zoom = scale.value
  } else {
    style.transform = `scale(${scale.value})`
  }

  return style
})

function updateScale() {
  cancelAnimationFrame(resizeRaf)

  resizeRaf = requestAnimationFrame(() => {
    const wrapper = wrapperRef.value
    if (!wrapper) return

    const { clientWidth, clientHeight } = wrapper
    if (!clientWidth || !clientHeight) return

    scale.value = Math.min(clientWidth / DESIGN_WIDTH, clientHeight / DESIGN_HEIGHT)

    nextTick(() => {
      resizeHazardChart()
      resizeSafeDayChart()
      resizeQhseTrendChart()
      resizeSocChart()
    })
  })
}

const staticData = ref<any>({})
const safeDay = ref<SafeDayMap>({})
const safeDayBarData = ref<SafeDayBarItem[]>([])
const summaryPanel = ref<any>(null)
const total = ref(0)
const instrumentExpired = ref(0)
const safeDayDisplayOrder = ['瑞气能源', '瑞霖技术', '5#项目', '酸化压裂', '气体增产', '钻修井']

function buildSafeDayBarData(baseData: SafeDayMap) {
  const mappedData = Object.entries(baseData || {}).map(([name, value]) => ({
    name,
    value: Number(value) || 0
  }))
  const orderedData = safeDayDisplayOrder
    .map((name) => mappedData.find((item) => item.name === name))
    .filter(Boolean) as SafeDayBarItem[]
  const remainingData = mappedData.filter((item) => !safeDayDisplayOrder.includes(item.name))

  safeDayBarData.value = [...orderedData, ...remainingData]
}

async function getStatic() {
  const res = await IotDangerApi.getDangerStatistics(userStore.user.deptId)
  staticData.value = res.classify || []

  riskZones.value.forEach((zone, index) => {
    const item = staticData.value[index]
    if (!item) return
    zone.value = item.count || 0
    zone.title = `${item.classify}区`
  })
}

async function getCertStatic() {
  const res = await IotMeasureCertApi.getIotMeasureCertStatistics(userStore.user.deptId)
  qualificationWarnings.value[0].value = res.expired || 0
  qualificationWarnings.value[1].value = res.warn || 0
}

async function getInstrumentOverview() {
  const listData = await IotInstrumentApi.getInstrumentList({
    pageNo: 1,
    pageSize: 10,
    deptId: userStore.user.deptId
  })
  total.value = listData.total || 0

  const statData = await IotInstrumentApi.getInstrumentStatistics(userStore.user.deptId)
  instrumentExpired.value = statData.expired || 0

  bottomCards.value[1].lines = [
    `在用: ${total.value}台`,
    `待检: ${instrumentExpired.value}项（重点关注）`
  ]
}

function getHazardChartOption(): echarts.EChartsOption {
  return {
    ...ANIMATION,
    grid: {
      left: 20,
      right: 10,
      top: 24,
      bottom: 24,
      containLabel: true
    },
    tooltip: createTooltip({
      trigger: 'axis',
      confine: true,
      appendToBody: false,
      axisPointer: {
        type: 'shadow',
        shadowStyle: {
          color: 'rgba(31, 91, 184, 0.08)'
        }
      },
      formatter(params: any) {
        if (!params || (Array.isArray(params) && params.length === 0)) return ''
        const item = Array.isArray(params) ? params[0] : params
        return `${item.name}<br/>数量：${item.value}`
      }
    }),
    xAxis: {
      type: 'category',
      data: hazardBars.value.map((item) => item.label),
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: '#5b6f8f',
        fontSize: 16,
        fontWeight: 700,
        fontFamily: FONT_FAMILY,
        interval: 0
      }
    },
    yAxis: {
      type: 'value',
      name: '隐患数量',
      nameLocation: 'end',
      nameGap: 13,
      nameTextStyle: {
        color: '#657897',
        fontSize: 12,
        // fontWeight: 600,
        fontFamily: FONT_FAMILY
      },
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: '#8a9bb5',
        fontSize: 13,
        fontFamily: FONT_FAMILY
      },
      splitLine: {
        lineStyle: {
          color: THEME.split,
          type: 'dashed'
        }
      }
    },
    series: [
      {
        type: 'bar',
        data: hazardBars.value.map((item) => ({
          value: item.value,
          itemStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: item.color },
              { offset: 1, color: `${item.color}99` }
            ]),
            shadowBlur: 14,
            shadowColor: item.color,
            borderRadius: [5, 5, 0, 0]
          }
        })),
        barWidth: 70,
        label: {
          show: true,
          position: 'top',
          color: '#3c5f96',
          fontSize: 16,
          fontWeight: 700,
          fontFamily: FONT_FAMILY
        },
        emphasis: {
          itemStyle: {
            shadowBlur: 18
          }
        }
      }
    ]
  }
}

function initHazardChart() {
  if (!hazardChartRef.value) return
  hazardChart?.dispose()
  hazardChart = echarts.init(hazardChartRef.value, undefined, {
    renderer: CHART_RENDERER
  })
  hazardChart.setOption(getHazardChartOption(), true)
  hazardChart.off('click')
  hazardChart.on('click', handleHazardBarClick)
}

function updateHazardChart() {
  if (!hazardChart) return
  hazardChart.clear()
  hazardChart.setOption(getHazardChartOption(), { notMerge: true, lazyUpdate: false })
}

function resizeHazardChart() {
  if (!hazardChart) return
  hazardChart.resize({ animation: { duration: 300 } })
}

function destroyHazardChart() {
  hazardChart?.dispose()
  hazardChart = null
}

function getSafeDayChartOption(): echarts.EChartsOption {
  const maxValue = Math.max(...safeDayBarData.value.map((item) => item.value), 0)
  const axisMax = maxValue > 0 ? Math.ceil(maxValue / 300) * 300 : 300

  return {
    ...ANIMATION,
    grid: {
      left: 30,
      right: 28,
      top: 18,
      bottom: 34,
      containLabel: true
    },
    tooltip: createTooltip({
      trigger: 'axis',
      confine: true,
      appendToBody: false,
      axisPointer: {
        type: 'shadow',
        shadowStyle: {
          color: 'rgba(79, 141, 255, 0.08)'
        }
      },
      formatter(params: any) {
        if (!params || (Array.isArray(params) && params.length === 0)) return ''
        const item = Array.isArray(params) ? params[0] : params
        return `${item.name}<br/>安全生产天数：<span style="font-weight:700">${item.value}</span>`
      }
    }),
    xAxis: {
      type: 'value',
      max: axisMax,
      axisLine: {
        lineStyle: {
          color: 'rgba(106, 144, 221, 0.45)'
        }
      },
      axisTick: { show: false },
      axisLabel: {
        color: '#5b6f8f',
        fontSize: 12,
        fontWeight: 600,
        fontFamily: FONT_FAMILY
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(104, 139, 205, 0.32)',
          type: 'dashed'
        }
      }
    },
    yAxis: {
      type: 'category',
      inverse: true,
      data: safeDayBarData.value.map((item) => item.name),
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: '#2e4262',
        fontSize: 14,
        fontWeight: 700,
        fontFamily: FONT_FAMILY
      },
      splitLine: { show: false }
    },
    series: [
      {
        name: '安全生产天数',
        type: 'bar',
        data: safeDayBarData.value.map((item) => item.value),
        barWidth: 22,
        showBackground: true,
        backgroundStyle: {
          color: 'rgba(116, 152, 216, 0.08)',
          borderRadius: 11
        },
        itemStyle: {
          color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
            { offset: 0, color: '#6f9af0' },
            { offset: 1, color: '#5f88de' }
          ]),
          borderRadius: [0, 11, 11, 0],
          shadowBlur: 10,
          shadowColor: 'rgba(95, 136, 222, 0.25)'
        },
        label: {
          show: false
        },
        emphasis: {
          itemStyle: {
            shadowBlur: 14,
            shadowColor: 'rgba(95, 136, 222, 0.38)'
          }
        }
      }
    ],
    graphic: [
      {
        type: 'text',
        left: 'center',
        bottom: 0,
        style: {
          text: '安全生产天数',
          fill: '#5b6f8f',
          font: `700 12px ${FONT_FAMILY}`
        }
      }
    ]
  }
}

function initSafeDayChart() {
  if (!safeDayChartRef.value) return
  safeDayChart?.dispose()
  safeDayChart = echarts.init(safeDayChartRef.value, undefined, {
    renderer: CHART_RENDERER
  })
  safeDayChart.setOption(getSafeDayChartOption(), true)
}

function updateSafeDayChart() {
  if (!safeDayChart) return
  safeDayChart.clear()
  safeDayChart.setOption(getSafeDayChartOption(), { notMerge: true, lazyUpdate: false })
}

function resizeSafeDayChart() {
  if (!safeDayChart) return
  safeDayChart.resize({ animation: { duration: 300 } })
}

function destroySafeDayChart() {
  safeDayChart?.dispose()
  safeDayChart = null
}

function getQhseTrendChartOption(): echarts.EChartsOption {
  const activeTab =
    qhseMetricTabs.find((item) => item.value === activeQhseMetric.value) || qhseMetricTabs[0]
  const seriesData = qhseTrendSeries.value[activeQhseMetric.value] || []

  return {
    ...ANIMATION,
    grid: {
      left: 32,
      right: 18,
      top: 28,
      bottom: 28,
      containLabel: true
    },
    tooltip: createTooltip({
      trigger: 'axis',
      confine: true,
      appendToBody: false,
      axisPointer: {
        type: 'line',
        lineStyle: {
          color: `${activeTab.accent}99`,
          width: 1.5
        }
      },
      formatter(params: any) {
        if (!params || (Array.isArray(params) && params.length === 0)) return ''
        const item = Array.isArray(params) ? params[0] : params
        return `${item.axisValue}<br/>${activeTab.label}：${item.data}`
      }
    }),
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: seriesData.map((item) => item.year),
      axisLine: {
        lineStyle: {
          color: 'rgba(106, 144, 221, 0.45)'
        }
      },
      axisTick: { show: false },
      axisLabel: {
        color: '#5b6f8f',
        rotate: 28,
        fontSize: 13,
        fontWeight: 600,
        fontFamily: FONT_FAMILY
      }
    },
    yAxis: {
      type: 'value',
      axisLine: { show: false },
      axisTick: { show: false },
      axisLabel: {
        color: '#8a9bb5',
        fontSize: 12,
        fontFamily: FONT_FAMILY
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(104, 139, 205, 0.22)',
          type: 'dashed'
        }
      }
    },
    series: [
      {
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 9,
        showSymbol: true,
        data: seriesData.map((item) => item.value),
        lineStyle: {
          width: 3,
          color: activeTab.accent
        },
        itemStyle: {
          color: activeTab.accent,
          borderColor: '#fff',
          borderWidth: 2
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: `${activeTab.accent}55` },
            { offset: 1, color: `${activeTab.accent}08` }
          ])
        }
      }
    ]
  }
}

function initQhseTrendChart() {
  if (!qhseTrendChartRef.value) return
  qhseTrendChart?.dispose()
  qhseTrendChart = echarts.init(qhseTrendChartRef.value, undefined, {
    renderer: CHART_RENDERER
  })
  qhseTrendChart.setOption(getQhseTrendChartOption(), { notMerge: true, lazyUpdate: false })
}

function updateQhseTrendChart() {
  if (!qhseTrendChart) return
  qhseTrendChart.clear()
  qhseTrendChart.setOption(getQhseTrendChartOption(), { notMerge: true, lazyUpdate: false })
}

function resizeQhseTrendChart() {
  if (!qhseTrendChart) return
  qhseTrendChart.resize({ animation: { duration: 300 } })
}

function destroyQhseTrendChart() {
  qhseTrendChart?.dispose()
  qhseTrendChart = null
}

function getSocChartOption(): echarts.EChartsOption {
  return {
    ...ANIMATION,
    title: {
      text: 'SOC',
      left: '34%',
      top: '54%',
      textAlign: 'center',
      textVerticalAlign: 'middle',
      textStyle: {
        color: '#3d5f94',
        fontSize: 24,
        fontWeight: 800,
        fontFamily: FONT_FAMILY
      }
    },
    tooltip: createTooltip({
      trigger: 'item',
      confine: true,
      appendToBody: false,
      formatter(params: any) {
        if (!params) return ''
        return `${params.name}<br/>数量：${params.value}<br/>占比：${params.percent}%`
      }
    }),
    legend: {
      orient: 'vertical',
      right: 100,
      top: 'center',
      itemWidth: 12,
      itemHeight: 12,
      icon: 'circle',
      textStyle: {
        color: '#5b6f8f',
        fontSize: 15,
        fontWeight: 600,
        fontFamily: FONT_FAMILY
      }
    },
    series: [
      {
        name: 'SOC卡类型',
        type: 'pie',
        radius: ['50%', '74%'],
        center: ['34%', '54%'],
        avoidLabelOverlap: true,
        itemStyle: {
          borderColor: 'rgba(255, 255, 255, 0.85)',
          borderWidth: 2,
          shadowBlur: 10,
          shadowColor: 'rgba(31, 91, 184, 0.12)'
        },
        label: {
          show: true,
          color: '#4e6483',
          fontSize: 13,
          fontWeight: 700,
          formatter: '{d}%'
        },
        labelLine: {
          lineStyle: {
            color: 'rgba(91, 111, 143, 0.5)'
          },
          length: 10,
          length2: 8
        },
        data: permitStats.value.map((item) => ({
          name: item.label,
          value: item.value,
          itemStyle: {
            color: item.color
          }
        }))
      }
    ]
  }
}

function initSocChart() {
  if (!socChartRef.value) return
  socChart?.dispose()
  socChart = echarts.init(socChartRef.value, undefined, {
    renderer: CHART_RENDERER
  })
  socChart.setOption(getSocChartOption(), { notMerge: true, lazyUpdate: false })
}

function updateSocChart() {
  if (!socChart) return
  socChart.clear()
  socChart.setOption(getSocChartOption(), { notMerge: true, lazyUpdate: false })
}

function resizeSocChart() {
  if (!socChart) return
  socChart.resize({ animation: { duration: 300 } })
}

function destroySocChart() {
  socChart?.dispose()
  socChart = null
}

const tableRowStyle = ({ row }) => {
  if (row.expired) {
    return { backgroundColor: '#ffe6e6' }
  }
  if (row.alertWarn) {
    return { backgroundColor: '#e19f1a' }
  }
  return {}
}

const tableRowClassName = ({ row }) => {
  if (row.expired) {
    return 'expired-row'
  }
  if (row.alertWarn) {
    return 'alert-warn-row'
  }
  return ''
}

function formatPercent(numerator: number, denominator: number) {
  if (!denominator || Number.isNaN(denominator)) {
    return '0%'
  }
  return `${((numerator / denominator) * 100).toFixed(1)}%`
}

async function loadHomeBoard() {
  summaryPanel.value = await kanbanApi.getKanban()

  summaryCards.value[3].value = formatPercent(
    summaryPanel.value.totdalCert - summaryPanel.value.expiredCert,
    summaryPanel.value.totdalCert
  )
  summaryCards.value[3].note = `Warn: ${summaryPanel.value.warnCert || 0}`

  hazardBars.value[0].value = summaryPanel.value.totalHazard || 0
  hazardBars.value[1].value =
    (summaryPanel.value.totalHazard || 0) - (summaryPanel.value.todoHazard || 0)
  hazardBars.value[2].value = summaryPanel.value.todoHazard || 0

  safeDay.value = (await kanbanApi.getSafeDay(userStore.getUser.deptId)) || {}
  buildSafeDayBarData(safeDay.value)

  await Promise.all([getStatic(), getCertStatic(), getInstrumentOverview()])

  nextTick(() => {
    updateHazardChart()
    updateSafeDayChart()
    updateQhseTrendChart()
    updateSocChart()
    resizeHazardChart()
    resizeSafeDayChart()
    resizeQhseTrendChart()
    resizeSocChart()
  })
}

const certLoading = ref(false)
const certTableData = ref<any[]>([])
const certTotal = ref(0)
const certQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,

  expired: undefined as string | undefined,
  alertWarn: undefined as string | undefined
})

const certWarningDialogVisible = ref(false)
const certWarningDialogTitle = ref('')
const certWarningLoading = ref(false)
const certWarningList = ref<any[]>([])
const certWarningTotal = ref(0)
const certWarningQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  deptId: userStore.getUser.deptId,
  type: undefined as string | undefined,
  classify: undefined as string | undefined,
  userName: undefined as string | undefined,
  expired: undefined as boolean | undefined,
  alertWarn: undefined as boolean | undefined
})

const hazardDialogVisible = ref(false)
const hazardDialogTitle = ref('')
const hazardDialogLoading = ref(false)
const hazardDialogList = ref<any[]>([])
const hazardDialogTotal = ref(0)
const hazardDialogQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  deptId: userStore.getUser.deptId,
  status: undefined as string | undefined,
  address: '',
  source: ''
})

const dangerDialogVisible = ref(false)
const dangerDialogTitle = ref('')
const dangerDialogLoading = ref(false)
const dangerDialogList = ref<any[]>([])
const dangerDialogTotal = ref(0)
const dangerDialogQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  riskGrade: '',
  deptId: userStore.getUser.deptId
})

const instrumentDialogVisible = ref(false)
const instrumentDialogTitle = ref('')
const instrumentDialogLoading = ref(false)
const instrumentDialogList = ref<any[]>([])
const instrumentDialogTotal = ref(0)
const instrumentDialogQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  measureName: undefined as string | undefined,
  measureCertNo: undefined as string | undefined,
  deptId: userStore.getUser.deptId,
  expired: undefined as boolean | undefined,
  alertWarn: undefined as boolean | undefined
})

const getCertificateTypeText = (type: string) => {
  const map: Record<string, string> = {
    personal: '个人证书',
    organization: '组织证书',
    other: '其他'
  }
  return map[type] || type
}

function formatDateCorrectly(timestamp: any) {
  if (!timestamp) return ''
  let time = Number(timestamp)
  if (time < 10000000000) {
    time = time * 1000
  }
  return formatDate(time).substring(0, 10)
}

let dialogFileView = ref(false)
let fileList = ref([])
const viewFile = (file) => {
  fileList.value = file.split(',')
  dialogFileView.value = true
  // window.open(file)
}

const viewFileInfo = (file) => {
  window.open(
    'http://doc.deepoil.cc:8012/onlinePreview?url=' + encodeURIComponent(Base64.encode(file))
  )
}

const extractFileName = (url: string): string => {
  try {
    // 移除查询参数和哈希
    const cleanUrl = url.split('?')[0].split('#')[0]
    // 获取最后一个斜杠后的内容
    const parts = cleanUrl.split('/')
    const fileName = parts[parts.length - 1]
    // URL 解码
    return decodeURIComponent(fileName) || url
  } catch {
    // 如果解析失败，返回原始 URL
    return url
  }
}

const handleDownload = async (url) => {
  try {
    const response = await fetch(url)
    const blob = await response.blob()
    const downloadUrl = window.URL.createObjectURL(blob)

    const link = document.createElement('a')
    link.href = downloadUrl
    link.download = url.split('/').pop() // 自动获取文件名‌:ml-citation{ref="3" data="citationList"}
    link.click()

    URL.revokeObjectURL(downloadUrl)
  } catch (error) {
    console.error('下载失败:', error)
  }
}

async function getCertificateBoardList() {
  certLoading.value = true
  try {
    const data = await IotCertificateApi.getCertificateList({
      ...certQueryParams
      // deptId: userStore.user.deptId
      // type: 'organization'
    })
    certTableData.value = data.list || []
    certTotal.value = data.total || 0
  } finally {
    certLoading.value = false
  }
}

async function getCertificateWarningList() {
  certWarningLoading.value = true
  try {
    const data = await IotMeasureCertApi.getIotMeasureCertPage(certWarningQueryParams)
    certWarningList.value = data.list || []
    certWarningTotal.value = data.total || 0
  } finally {
    certWarningLoading.value = false
  }
}

async function getHazardDialogList() {
  hazardDialogLoading.value = true
  try {
    const data = await IotHiddenApi.getHiddenList(hazardDialogQueryParams)
    hazardDialogList.value = data.list || []
    hazardDialogTotal.value = data.total || 0
  } finally {
    hazardDialogLoading.value = false
  }
}

async function getDangerDialogList() {
  dangerDialogLoading.value = true
  try {
    const data = await IotDangerApi.getDangerList(dangerDialogQueryParams)
    dangerDialogList.value = data.list || []
    dangerDialogTotal.value = data.total || 0
  } finally {
    dangerDialogLoading.value = false
  }
}

async function getInstrumentDialogList() {
  instrumentDialogLoading.value = true
  try {
    const data = await IotInstrumentApi.getInstrumentList(instrumentDialogQueryParams)
    instrumentDialogList.value = data.list || []
    instrumentDialogTotal.value = data.total || 0
  } finally {
    instrumentDialogLoading.value = false
  }
}

function openHazardDialog(barLabel: string) {
  hazardDialogQueryParams.pageNo = 1
  hazardDialogQueryParams.pageSize = 10
  hazardDialogQueryParams.deptId = userStore.getUser.deptId
  hazardDialogQueryParams.address = ''
  hazardDialogQueryParams.source = ''

  if (barLabel === '未整改') {
    hazardDialogTitle.value = '未整改隐患列表'
    hazardDialogQueryParams.status = 'todo'
  } else if (barLabel === '已整改') {
    hazardDialogTitle.value = '已整改隐患列表'
    hazardDialogQueryParams.status = 'finished'
  } else {
    hazardDialogTitle.value = '隐患总数列表'
    hazardDialogQueryParams.status = undefined
  }

  hazardDialogVisible.value = true
  getHazardDialogList()
}

function openDangerDialog(zone: { title?: string }) {
  const riskGradeLabel = String(zone.title || '')
    .replace(/区$/, '')
    .trim()
  const matchedOption = dangerGradeOptions.value.find((item) => item.label === riskGradeLabel)
  const riskGrade = matchedOption?.value || ''
  dangerDialogQueryParams.pageNo = 1
  dangerDialogQueryParams.pageSize = 10
  dangerDialogQueryParams.deptId = userStore.getUser.deptId
  dangerDialogQueryParams.riskGrade = riskGrade
  dangerDialogTitle.value = riskGradeLabel ? `${riskGradeLabel}风险列表` : '风险列表'
  dangerDialogVisible.value = true
  getDangerDialogList()
}

function openInstrumentDialog(type: 'all' | 'expired') {
  instrumentDialogQueryParams.pageNo = 1
  instrumentDialogQueryParams.pageSize = 10
  instrumentDialogQueryParams.measureName = undefined
  instrumentDialogQueryParams.measureCertNo = undefined
  instrumentDialogQueryParams.deptId = userStore.getUser.deptId
  instrumentDialogQueryParams.alertWarn = undefined

  if (type === 'expired') {
    instrumentDialogTitle.value = '待检设备列表'
    instrumentDialogQueryParams.expired = true
  } else {
    instrumentDialogTitle.value = '在用设备列表'
    instrumentDialogQueryParams.expired = undefined
  }

  instrumentDialogVisible.value = true
  getInstrumentDialogList()
}

function handleHazardBarClick(params: { name?: string }) {
  if (!params?.name) return
  openHazardDialog(params.name)
}

function openCertificateWarningDialog(type: 'expired' | 'warn') {
  certWarningQueryParams.pageNo = 1
  certWarningQueryParams.pageSize = 10
  certWarningQueryParams.deptId = userStore.getUser.deptId
  certWarningQueryParams.type = undefined
  certWarningQueryParams.classify = undefined
  certWarningQueryParams.userName = undefined

  if (type === 'expired') {
    certWarningDialogTitle.value = '证件过期'
    certWarningQueryParams.expired = true
    certWarningQueryParams.alertWarn = undefined
  } else {
    certWarningDialogTitle.value = '证件即将到期'
    certWarningQueryParams.expired = undefined
    certWarningQueryParams.alertWarn = true
  }

  certWarningDialogVisible.value = true
  getCertificateWarningList()
}

function handleCertificateQuery() {
  certQueryParams.pageNo = 1
  getCertificateBoardList()
}

function resetCertificateQuery() {
  certQueryParams.pageNo = 1
  certQueryParams.pageSize = 10

  certQueryParams.expired = undefined
  certQueryParams.alertWarn = undefined
  getCertificateBoardList()
}

watch(
  () => activeSummaryTab.value,
  async (value) => {
    if (value === 'certificate') {
      await getCertificateBoardList()
    } else {
      nextTick(() => {
        resizeHazardChart()
        resizeSafeDayChart()
        resizeQhseTrendChart()
        resizeSocChart()
      })
    }
  }
)

watch(
  () => type.value,
  (value) => {
    timeVal.value = getCurrentPickerValue(value)
  }
)

onMounted(async () => {
  // supportsZoom.value = typeof CSS !== 'undefined' && CSS.supports?.('zoom', '1') === true
  nextTick(updateScale)
  resizeObserver = new ResizeObserver(updateScale)
  if (wrapperRef.value) {
    resizeObserver.observe(wrapperRef.value)
  }
  initHazardChart()
  initSafeDayChart()
  initQhseTrendChart()
  initSocChart()
  window.addEventListener('resize', updateScale)
  window.addEventListener('resize', resizeHazardChart)
  window.addEventListener('resize', resizeSafeDayChart)
  window.addEventListener('resize', resizeQhseTrendChart)
  window.addEventListener('resize', resizeSocChart)

  await loadHomeBoard()
})

onUnmounted(() => {
  resizeObserver?.disconnect()
  window.removeEventListener('resize', updateScale)
  window.removeEventListener('resize', resizeHazardChart)
  window.removeEventListener('resize', resizeSafeDayChart)
  window.removeEventListener('resize', resizeQhseTrendChart)
  window.removeEventListener('resize', resizeSocChart)
  cancelAnimationFrame(resizeRaf)
  destroyHazardChart()
  destroySafeDayChart()
  destroyQhseTrendChart()
  destroySocChart()
})
</script>

<template>
  <div ref="wrapperRef" class="bg absolute top-0 left-0 size-full z-10">
    <div class="mx-a overflow-hidden" :style="targetWrapperStyle">
      <div id="qhse-kanban" class="bg qhse-board" :style="targetAreaStyle">
        <header class="header">{{ pageTitle }}</header>

        <div class="summary-toolbar">
          <div class="summary-toolbar__tabs">
            <button
              v-for="tab in summaryTabs"
              :key="tab.value"
              type="button"
              class="summary-toolbar__tab"
              :class="{ 'is-active': activeSummaryTab === tab.value }"
              @click="activeSummaryTab = tab.value">
              {{ tab.label }}
            </button>
          </div>

          <div v-if="activeSummaryTab === 'home'" class="summary-toolbar__date">
            <span class="summary-toolbar__date-label">日期:</span>

            <div class="flex items-center gap-2 datepicker">
              <el-date-picker
                v-model="timeVal"
                :teleport="true"
                :type="type === 'day' ? 'date' : type === 'month' ? 'month' : 'year'"
                class="summary-toolbar__picker el-date-picker"
                popper-class="summary-toolbar__picker-popper"
                value-format="YYYY-MM-DD"
                range-separator="~"
                start-placeholder="开始"
                end-placeholder="结束"
                @change="handelChange"
                style="
                  width: 150px;
                  height: 40px;
                  margin-left: 10px;
                  background-color: transparent;
                " />

              <span class="bg-[#f5f9ff] rounded-2xl px-2 py-0 cursor-pointer">月度</span>
              <span class="bg-[#f5f9ff] rounded-2xl px-2 py-0 cursor-pointer">季度</span>
              <span class="bg-[#f5f9ff] rounded-2xl px-2 py-0 cursor-pointer">年度</span>
              <span class="bg-[#f5f9ff] rounded-2xl px-2 py-0 cursor-pointer">初始化</span>
            </div>
          </div>
        </div>

        <div v-if="activeSummaryTab === 'home'" class="board-body">
          <section class="panel summary-panel kb-stage-card kb-stage-card--1">
            <div class="panel-title">
              <span class="icon-decorator"><span></span><span></span></span>
              QHSE关键数据
            </div>
            <div class="summary-grid">
              <article
                v-for="card in summaryCards"
                :key="card.title"
                class="summary-card summary-tile"
                :style="
                  {
                    '--card-accent': card.accent,
                    '--card-glow': card.glow
                  } as any
                ">
                <span class="summary-card__shine"></span>
                <span class="summary-card__corner"></span>
                <div class="summary-card__icon">
                  <el-icon class="summary-card__icon-glyph">
                    <component :is="card.icon" />
                  </el-icon>
                </div>
                <div class="summary-card__content">
                  <div class="summary-card__label">{{ card.title }}</div>
                  <div class="summary-tile__meta">
                    <span class="summary-tile__value">{{ card.value }}</span>
                    <span class="summary-tile__note" :style="{ color: card.accent }">
                      {{ card.note }}
                    </span>
                  </div>
                </div>
              </article>
            </div>
          </section>

          <div class="board-main">
            <div class="center-column">
              <section class="panel board-panel board-panel--center kb-stage-card kb-stage-card--4">
                <div class="panel-title panel-title--center">
                  <span class="icon-decorator"><span></span><span></span></span>
                  风险管控及隐患治理
                </div>
                <div class="risk-grid">
                  <article
                    v-for="zone in riskZones"
                    :key="zone.title"
                    class="risk-card risk-card--clickable"
                    @click="openDangerDialog(zone)">
                    <div class="risk-card__title">
                      <span class="risk-card__dot" :style="{ background: zone.color }"></span>
                      <span :style="{ color: zone.color }">{{ zone.title }}</span>
                      <CountTo
                        :duration="2600"
                        :end-val="zone.value"
                        :start-val="0"
                        :style="{ color: zone.color, fontSize: '22px' }" />
                    </div>
                    <div class="risk-card__desc">{{ zone.desc }}</div>
                  </article>
                </div>

                <div class="risk-hazard-block mt-2!">
                  <div
                    ref="hazardChartRef"
                    class="chart-panel chart-panel--echart risk-hazard-block__chart"></div>
                </div>
              </section>
            </div>

            <div class="left-column">
              <section class="panel board-panel kb-stage-card kb-stage-card--3">
                <div class="panel-title panel-title--center">
                  <span class="icon-decorator"><span></span><span></span></span>
                  QHSE指标
                </div>

                <section class="board-panel kb-stage-card kb-stage-card--5">
                  <div ref="safeDayChartRef" class="safe-day-chart-panel"></div>
                </section>

                <section class="board-panel kb-stage-card kb-stage-card--5">
                  <div class="qhse-metric-tabs">
                    <button
                      v-for="item in qhseMetricTabs"
                      :key="item.value"
                      :title="item.label2"
                      type="button"
                      class="qhse-metric-tab"
                      :class="{ 'is-active': activeQhseMetric === item.value }"
                      @click="
                        () => {
                          activeQhseMetric = item.value
                          nextTick(() => {
                            updateQhseTrendChart()
                            resizeQhseTrendChart()
                          })
                        }
                      ">
                      {{ item.label }}
                    </button>
                  </div>
                  <div ref="qhseTrendChartRef" class="qhse-trend-chart-panel"></div>
                </section>
              </section>
            </div>

            <div class="right-column">
              <section class="panel board-panel board-panel--center kb-stage-card kb-stage-card--4">
                <div class="panel-title panel-title--center">
                  <span class="icon-decorator"><span></span><span></span></span>
                  行为安全与系统预警
                </div>
                <section class="board-panel kb-stage-card kb-stage-card--5 pt-2">
                  <div ref="socChartRef" class="soc-chart-panel"></div>
                </section>

                <section class="board-panel kb-stage-card kb-stage-card--6 pl-4">
                  <div class="qualification-panel">
                    <div class="qualification-icon">
                      <el-icon>
                        <CollectionTag />
                      </el-icon>
                    </div>
                    <div class="qualification-list">
                      <div
                        v-for="item in qualificationWarnings"
                        :key="item.label"
                        class="qualification-item qualification-item--clickable"
                        @click="openCertificateWarningDialog(item.key)">
                        <span class="qualification-item__label">{{ item.label }}：</span>
                        <strong :style="{ color: item.accent }">
                          <CountTo
                            :duration="2600"
                            :end-val="item.value"
                            :start-val="0"
                            :style="{ color: item.accent }" />
                          <span class="pl-2">人</span>
                        </strong>
                      </div>
                    </div>
                  </div>
                </section>
              </section>
            </div>
          </div>

          <section class="bottom-grid">
            <article
              v-for="(card, index) in bottomCards"
              :key="card.title"
              class="panel bottom-card kb-stage-card"
              :class="`kb-stage-card--${index + 7}`"
              :style="
                {
                  '--card-accent': card.accent,
                  '--card-glow': card.glow
                } as any
              ">
              <span class="summary-card__shine"></span>
              <div class="bottom-card__header">
                <div class="summary-card__icon bottom-card__icon">
                  <el-icon class="summary-card__icon-glyph">
                    <component :is="card.icon" />
                  </el-icon>
                </div>
                <div class="bottom-card__title">{{ card.title }}</div>
              </div>
              <div class="bottom-card__content">
                <template v-if="card.title === '安全检测'">
                  <button
                    type="button"
                    class="bottom-card__action"
                    @click="openInstrumentDialog('all')">
                    {{ card.lines[0] }}
                  </button>
                  <button
                    type="button"
                    class="bottom-card__action"
                    @click="openInstrumentDialog('expired')">
                    {{ card.lines[1] }}
                  </button>
                </template>
                <template v-else>
                  <p v-for="line in card.lines" :key="line">{{ line }}</p>
                </template>
              </div>
            </article>
          </section>
        </div>

        <div v-else class="certificate-board">
          <section class="panel certificate-filter-panel">
            <div class="certificate-filters">
              <div class="certificate-filter-item">
                <span class="certificate-filter-item__label">是否过期</span>
                <el-select
                  v-model="certQueryParams.expired"
                  clearable
                  placeholder="请选择是否过期"
                  class="certificate-filter-item__control">
                  <el-option
                    v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value" />
                </el-select>
              </div>

              <div class="certificate-filter-item">
                <span class="certificate-filter-item__label">是否预警</span>
                <el-select
                  v-model="certQueryParams.alertWarn"
                  clearable
                  placeholder="请选择是否过期"
                  class="certificate-filter-item__control">
                  <el-option
                    v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value" />
                </el-select>
              </div>

              <div class="certificate-filter-actions">
                <el-button type="primary" :icon="Search" @click="handleCertificateQuery"
                  >查询</el-button
                >
                <el-button :icon="Refresh" @click="resetCertificateQuery">重置</el-button>
              </div>
            </div>
          </section>

          <section class="panel certificate-table-panel">
            <el-table
              :loading="certLoading"
              :data="certTableData"
              :row-style="tableRowStyle"
              :row-class-name="tableRowClassName"
              height="100vh"
              :header-cell-style="{
                height: '42px'
              }"
              class="device-list-table production-brief-table">
              <el-table-column label="序号" width="80" align="center">
                <template #default="scope">
                  {{ (certQueryParams.pageNo - 1) * certQueryParams.pageSize + scope.$index + 1 }}
                </template>
              </el-table-column>

              <el-table-column label="证书类别" align="center" width="150" prop="classify">
                <template #default="scope">
                  <dict-tag :type="DICT_TYPE.ORG_CERT" :value="scope.row.classify" />
                </template>
              </el-table-column>
              <el-table-column
                label="证书名称"
                align="center"
                prop="certName"
                show-overflow-tooltip />

              <el-table-column label="所在部门" align="center" prop="deptName" />

              <el-table-column label="颁发机构" align="center" prop="certOrg" />

              <el-table-column label="证书标准" align="center" prop="certStandard" />

              <el-table-column label="颁发时间" align="center" prop="certIssue">
                <template #default="scope">
                  {{ formatDateCorrectly(scope.row.certIssue) }}
                </template>
              </el-table-column>

              <el-table-column label="有效期" align="center">
                <template #default="scope">
                  {{ formatDateCorrectly(scope.row.certExpire) }}
                </template>
              </el-table-column>

              <el-table-column label="到期提醒" align="center">
                <template #default="scope"> {{ scope.row.noticeBefore }}天前提醒 </template>
              </el-table-column>

              <el-table-column label="备注" align="center" prop="remark" />
              <el-table-column label="操作" align="center" fixed="right" min-width="180px" action>
                <template #default="scope">
                  <el-button
                    link
                    type="success"
                    v-if="scope.row.certPic"
                    @click="viewFile(scope.row.certPic)">
                    查看证书
                  </el-button>
                </template>
              </el-table-column>
            </el-table>

            <div class="certificate-pagination">
              <Pagination
                :total="certTotal"
                v-model:page="certQueryParams.pageNo"
                v-model:limit="certQueryParams.pageSize"
                @pagination="getCertificateBoardList" />
            </div>

            <div class="shadow rounded-lg p-3 min-w-0 flex gap-4 justify-between">
              <div
                class="bg-[#fef0f0] text-[#f57979] px-3 flex-1 flex items-center justify-center text-center py-2 text-sm rounded-md"
                ><el-icon class="stats-card__icon" :size="28">
                  <Icon icon="ep:info-filled" /> </el-icon
                >证书已过期红色预警</div
              >
              <div
                class="bg-[#fdf6ec] flex-1 text-[#e6a23c] text-center flex items-center justify-center px-3 py-2 text-sm rounded-md"
                ><el-icon class="stats-card__icon" :size="28">
                  <Icon icon="ep:bell-filled" /> </el-icon
                >证书60天橙色预警</div
              >
            </div>
          </section>
        </div>
      </div>
    </div>
  </div>

  <Dialog v-model="dialogFileView" title="附件">
    <div
      v-for="(file, index) in fileList"
      :key="index"
      class="mt-5 flex min-w-0 items-center justify-between gap-5">
      <span class="file-name-text flex-1 min-w-0">{{ extractFileName(file) }}</span>
      <div class="flex shrink-0 items-center gap-5 flex-nowrap">
        <el-button link type="primary" @click="viewFileInfo(file)">
          <Icon icon="ep:view" class="mr-2px" />查看
        </el-button>
        <el-button link type="primary" @click="handleDownload(file)">
          <Icon icon="ep:download" class="mr-2px" />下载
        </el-button>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer mt-10">
        <el-button type="primary" @click="dialogFileView = false">确认</el-button>
      </div>
    </template>
  </Dialog>

  <Dialog v-model="certWarningDialogVisible" :title="certWarningDialogTitle" width="1100px">
    <div class="certificate-warning-dialog">
      <el-table
        :loading="certWarningLoading"
        :data="certWarningList"
        :row-style="tableRowStyle"
        :row-class-name="tableRowClassName"
        height="400"
        class="device-list-table production-brief-table">
        <el-table-column label="序号" width="80" align="center">
          <template #default="scope">
            {{
              (certWarningQueryParams.pageNo - 1) * certWarningQueryParams.pageSize +
              scope.$index +
              1
            }}
          </template>
        </el-table-column>
        <el-table-column label="证书类型" align="center" prop="type" width="120">
          <template #default="scope">
            {{ getCertificateTypeText(scope.row.type) }}
          </template>
        </el-table-column>
        <el-table-column label="证书类别" align="center" width="150" prop="classify">
          <template #default="scope">
            <dict-tag
              v-if="scope.row.type === 'organization'"
              :type="DICT_TYPE.ORG_CERT"
              :value="scope.row.classify" />
            <dict-tag v-else :type="DICT_TYPE.PERSON_CERT" :value="scope.row.classify" />
          </template>
        </el-table-column>
        <el-table-column
          label="证书名称"
          align="center"
          prop="certName"
          show-overflow-tooltip
          width="100" />
        <el-table-column label="所属人" align="center" prop="userName" width="100" />
        <el-table-column
          label="所在部门"
          align="center"
          prop="deptName"
          width="100"
          show-overflow-tooltip />
        <el-table-column
          label="颁发机构"
          align="center"
          prop="certOrg"
          width="180"
          show-overflow-tooltip />
        <el-table-column
          label="证书标准"
          align="center"
          prop="certStandard"
          width="100"
          show-overflow-tooltip />
        <el-table-column label="颁发时间" align="center" prop="certIssue" width="120">
          <template #default="scope">
            {{ formatDateCorrectly(scope.row.certIssue) }}
          </template>
        </el-table-column>
        <el-table-column label="有效期" align="center" prop="certExpire" width="120">
          <template #default="scope">
            {{ formatDateCorrectly(scope.row.certExpire) }}
          </template>
        </el-table-column>
        <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
        <el-table-column label="操作" align="center" fixed="right" min-width="100px">
          <template #default="scope">
            <el-button
              link
              type="success"
              v-if="scope.row.certPic"
              @click="viewFile(scope.row.certPic)">
              查看证书
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="certificate-pagination">
        <Pagination
          :total="certWarningTotal"
          v-model:page="certWarningQueryParams.pageNo"
          v-model:limit="certWarningQueryParams.pageSize"
          @pagination="getCertificateWarningList" />
      </div>
    </div>
  </Dialog>

  <Dialog v-model="hazardDialogVisible" :title="hazardDialogTitle" width="1400px">
    <div class="certificate-warning-dialog">
      <el-table
        :loading="hazardDialogLoading"
        :data="hazardDialogList"
        height="400"
        class="device-list-table production-brief-table">
        <el-table-column label="序号" width="80" align="center">
          <template #default="scope">
            {{
              (hazardDialogQueryParams.pageNo - 1) * hazardDialogQueryParams.pageSize +
              scope.$index +
              1
            }}
          </template>
        </el-table-column>
        <el-table-column label="单位" align="center" prop="deptName" min-width="140" />
        <el-table-column label="类型" align="center" prop="classifyName" min-width="120" />
        <el-table-column label="来源" align="center" min-width="110">
          <template #default="scope">
            <dict-tag :type="DICT_TYPE.QHSE_HAZARD_SOURCE" :value="scope.row.source" />
          </template>
        </el-table-column>
        <el-table-column label="地点" align="center" prop="address" min-width="140" />
        <el-table-column
          label="存在问题"
          align="center"
          prop="problem"
          min-width="180"
          show-overflow-tooltip />
        <el-table-column label="隐患附件" align="center" min-width="100">
          <template #default="{ row }">
            <el-button v-if="row.hazardFile" link type="primary" @click="viewFile(row.hazardFile)">
              查看
            </el-button>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column
          label="整改人"
          align="center"
          prop="correctPersonName"
          min-width="100"
          show-overflow-tooltip />
        <el-table-column
          label="整改要求"
          align="center"
          prop="correctStandard"
          min-width="160"
          show-overflow-tooltip />
        <el-table-column
          label="整改情况"
          align="center"
          prop="rectifyDesc"
          min-width="160"
          show-overflow-tooltip />
        <el-table-column label="整改附件" align="center" min-width="100">
          <template #default="{ row }">
            <el-button
              v-if="row.rectifyFile"
              link
              type="primary"
              @click="viewFile(row.rectifyFile)">
              查看
            </el-button>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column label="排查时间" align="center" min-width="120">
          <template #default="{ row }">
            {{ formatDateCorrectly(row.checkTime) }}
          </template>
        </el-table-column>
        <el-table-column label="状态" align="center" min-width="90">
          <template #default="scope">
            <dict-tag :type="DICT_TYPE.QHSE_HAZARD_STATUS" :value="scope.row.status" />
          </template>
        </el-table-column>
        <el-table-column
          label="备注"
          align="center"
          prop="remark"
          min-width="120"
          show-overflow-tooltip />
      </el-table>

      <div class="certificate-pagination">
        <Pagination
          :total="hazardDialogTotal"
          v-model:page="hazardDialogQueryParams.pageNo"
          v-model:limit="hazardDialogQueryParams.pageSize"
          @pagination="getHazardDialogList" />
      </div>
    </div>
  </Dialog>

  <Dialog v-model="dangerDialogVisible" :title="dangerDialogTitle" width="1400px">
    <div class="certificate-warning-dialog">
      <el-table
        :loading="dangerDialogLoading"
        :data="dangerDialogList"
        height="400"
        class="device-list-table production-brief-table">
        <el-table-column label="序号" width="80" align="center">
          <template #default="scope">
            {{
              (dangerDialogQueryParams.pageNo - 1) * dangerDialogQueryParams.pageSize +
              scope.$index +
              1
            }}
          </template>
        </el-table-column>
        <el-table-column
          label="区域/位置"
          align="center"
          prop="region"
          min-width="140"
          show-overflow-tooltip />
        <el-table-column
          label="危险因素描述"
          align="center"
          prop="elementDescription"
          min-width="180"
          show-overflow-tooltip />
        <el-table-column
          label="可导致的后果"
          align="center"
          prop="maybeResult"
          min-width="180"
          show-overflow-tooltip />
        <el-table-column label="风险评价" align="center">
          <el-table-column prop="evalKn" label="可能性 (L)" width="100" align="center">
            <template #default="{ row }">
              {{ row.evalKn }}
            </template>
          </el-table-column>
          <el-table-column prop="evalYz" label="严重性 (S)" width="100" align="center">
            <template #default="{ row }">
              {{ row.evalYz }}
            </template>
          </el-table-column>
          <el-table-column prop="evalFxz" label="风险值 (R)" width="100" align="center">
            <template #default="{ row }">
              {{ row.evalFxz }}
            </template>
          </el-table-column>
          <el-table-column prop="riskGrade" label="风险等级" width="100" align="center">
            <template #default="scope">
              <dict-tag :type="DICT_TYPE.DANGER_GRADE" :value="scope.row.riskGrade" />
            </template>
          </el-table-column>
        </el-table-column>
        <el-table-column
          label="控制措施"
          align="center"
          prop="controlMethod"
          show-overflow-tooltip />
        <el-table-column
          label="责任人"
          align="center"
          prop="charge"
          min-width="100"
          show-overflow-tooltip />
      </el-table>

      <div class="certificate-pagination">
        <Pagination
          :total="dangerDialogTotal"
          v-model:page="dangerDialogQueryParams.pageNo"
          v-model:limit="dangerDialogQueryParams.pageSize"
          @pagination="getDangerDialogList" />
      </div>
    </div>
  </Dialog>

  <Dialog v-model="instrumentDialogVisible" :title="instrumentDialogTitle" width="1400px">
    <div class="certificate-warning-dialog">
      <el-table
        :loading="instrumentDialogLoading"
        :data="instrumentDialogList"
        :row-style="tableRowStyle"
        :row-class-name="tableRowClassName"
        height="400"
        class="device-list-table production-brief-table">
        <el-table-column label="序号" width="80" align="center">
          <template #default="scope">
            {{
              (instrumentDialogQueryParams.pageNo - 1) * instrumentDialogQueryParams.pageSize +
              scope.$index +
              1
            }}
          </template>
        </el-table-column>
        <el-table-column label="名称" align="center" prop="measureName" min-width="140" />
        <el-table-column label="编码" align="center" prop="measureCode" min-width="120" />
        <el-table-column label="序列号" align="center" prop="serialNo" min-width="120" />
        <el-table-column label="部门名称" align="center" prop="deptName" min-width="140" />
        <el-table-column label="计量单位" align="center" prop="measureUnit" min-width="100" />
        <el-table-column label="责任人" align="center" prop="dutyPerson" min-width="100" />
        <el-table-column label="品牌" align="center" prop="brand" min-width="100" />
        <el-table-column label="规格型号" align="center" prop="modelName" min-width="120" />
        <el-table-column label="分类" align="center" min-width="120">
          <template #default="scope">
            <dict-tag :type="DICT_TYPE.MEASURE_TYPE" :value="scope.row.classify" />
          </template>
        </el-table-column>
        <el-table-column label="采购日期" align="center" min-width="120">
          <template #default="scope">
            {{ formatDateCorrectly(scope.row.buyDate) }}
          </template>
        </el-table-column>
        <el-table-column label="价格" align="center" prop="measurePrice" min-width="100" />
        <el-table-column
          label="备注"
          align="center"
          prop="remark"
          min-width="140"
          show-overflow-tooltip />
      </el-table>

      <div class="certificate-pagination">
        <Pagination
          :total="instrumentDialogTotal"
          v-model:page="instrumentDialogQueryParams.pageNo"
          v-model:limit="instrumentDialogQueryParams.pageSize"
          @pagination="getInstrumentDialogList" />
      </div>
    </div>
  </Dialog>
</template>

<style lang="scss" scoped>
@import url('@/styles/qhse_kb.scss');

:deep(.el-select__wrapper) {
  // height: 38px !important;
  font-size: 14px !important;
}
.qhse-board {
  color: #24364f;
}

.board-body {
  padding: 5px 18px 24px;
}

.summary-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px 6px;
}

.summary-toolbar__tabs {
  display: flex;
  align-items: center;
  gap: 12px;
}

.summary-toolbar__tab {
  min-width: 120px;
  height: 40px;
  padding: 0 22px;
  font-family: YouSheBiaoTiHei, sans-serif;
  font-size: 17px;
  color: #2b76e9;
  background: linear-gradient(180deg, rgb(255 255 255 / 92%) 0%, rgb(228 239 255 / 90%) 100%);
  border: 1px solid rgb(126 174 244 / 44%);
  border-radius: 10px;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 96%),
    0 8px 14px rgb(63 103 171 / 8%);
  cursor: pointer;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease,
    background 0.2s ease,
    color 0.2s ease;
}

.summary-toolbar__tab.is-active {
  color: #fff;
  background: linear-gradient(180deg, #59a6ff 0%, #2d78ea 100%);
  border-color: rgb(62 122 223 / 88%);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 22%),
    0 10px 18px rgb(45 120 234 / 20%);
}

.summary-toolbar__tab:hover {
  transform: translateY(-1px);
}

.summary-toolbar__date {
  display: flex;
  align-items: center;
  gap: 10px;
}

.summary-toolbar__date-label {
  font-size: 18px;
  font-weight: 700;
  color: #5c7393;
}

.bottom-card__action {
  display: block;
  width: 100%;
  padding: 0;
  text-align: left;
  color: #617491;
  background: transparent;
  border: none;
  cursor: pointer;
  transition: color 0.2s ease;
  font-size: 18px;
  font-weight: 700;
  color: #5c7393;
}

.bottom-card__action:hover {
  color: #2d78ea;
}

.risk-card--clickable {
  cursor: pointer;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease;
}

.risk-card--clickable:hover {
  transform: translateY(-2px);
}

.summary-toolbar__picker {
  width: 190px;
}

.summary-toolbar__picker :deep(.el-input__wrapper) {
  min-height: 38px;
  background: rgb(255 255 255 / 80%);
  border: 1px solid rgb(137 176 235 / 38%);
  border-radius: 10px;
  font-size: 14px !important;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 92%),
    0 8px 14px rgb(63 103 171 / 6%);
}

.summary-toolbar__picker :deep(.el-input__inner),
.summary-toolbar__picker :deep(.el-range-input),
.summary-toolbar__picker :deep(.el-input__prefix),
.summary-toolbar__picker :deep(.el-input__suffix) {
  font-size: 14px !important;
}

.summary-toolbar__picker :deep(.el-input__inner::placeholder),
.summary-toolbar__picker :deep(.el-range-input::placeholder) {
  font-size: 14px !important;
}

:deep(.summary-toolbar__picker-popper) {
  font-size: 14px;
}

:deep(.summary-toolbar__picker-popper .el-date-table),
:deep(.summary-toolbar__picker-popper .el-date-table th),
:deep(.summary-toolbar__picker-popper .el-date-table td),
:deep(.summary-toolbar__picker-popper .el-month-table),
:deep(.summary-toolbar__picker-popper .el-year-table),
:deep(.summary-toolbar__picker-popper .el-picker-panel__icon-btn),
:deep(.summary-toolbar__picker-popper .el-date-picker__header-label) {
  font-size: 14px !important;
}

.summary-panel {
  padding: 0 10px 10px;
  height: 200px;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 24px;
  margin-top: 10px;
}

.summary-tile {
  display: flex;
  height: 136px;
  padding: 28px 18px 24px;
  border-radius: 22px;
  align-items: center;
  gap: 22px;
}

.summary-card__content {
  position: relative;
  z-index: 2;
  min-width: 0;
  flex: 1;
}

.summary-tile__meta {
  display: flex;
  margin-top: 14px;
  align-items: baseline;
  gap: 8px;
}

.summary-tile__value {
  font-family: YouSheBiaoTiHei, sans-serif;
  font-size: 30px;
  line-height: 1;
  color: #114a9b;
  letter-spacing: 1px;
}

.summary-tile__note {
  font-size: 16px;
  font-weight: 700;
}

.board-main {
  display: grid;
  grid-template-columns: 1.02fr 1fr 0.98fr;
  gap: 28px;
  margin-top: 10px;
}

.left-column,
.right-column {
  display: grid;
  gap: 24px;
  align-content: start;
}
.left-column {
  height: 540px;
}
.board-panel {
  min-height: 258px;
}

.board-panel.kb-stage-card:hover {
  transform: none;
}

.board-panel--center {
  min-height: 540px;
  height: 540px;
}

.chart-panel {
  margin-top: 18px;
}

.chart-panel--echart {
  height: 188px;
}

.safe-day-chart-panel {
  height: 230px;
}

.qhse-metric-tabs {
  display: flex;
  justify-content: left;
  gap: 5px;
  padding-left: 30px;
}

.qhse-metric-tab {
  min-height: 24px;
  padding: 5px 12px;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.35;
  color: #4d6487;
  text-align: center;
  background: linear-gradient(180deg, rgb(255 255 255 / 86%) 0%, rgb(228 239 255 / 82%) 100%);
  border: 1px solid rgb(118 167 238 / 28%);
  border-radius: 14px;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 92%),
    0 10px 16px rgb(52 94 164 / 8%);
  cursor: pointer;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease,
    color 0.2s ease,
    background 0.2s ease,
    border-color 0.2s ease;
}

.qhse-metric-tab:hover {
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 94%),
    0 12px 18px rgb(52 94 164 / 10%);
}

.qhse-metric-tab.is-active {
  color: #fff;
  background: linear-gradient(180deg, #63adff 0%, #347eea 100%);
  border-color: rgb(62 122 223 / 76%);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 18%),
    0 12px 20px rgb(45 120 234 / 22%);
}

.qhse-trend-chart-panel {
  height: 220px;
  // margin-top: 14px;
}

.soc-chart-panel {
  height: 280px;
}

.panel-title--center {
  justify-content: center;
  padding-left: 0;
  font-size: 32px;
}

.panel-title--center .icon-decorator {
  left: 28px;
}

.risk-grid {
  display: grid;
  padding: 10px 24px 12px;
  // margin-top: 18px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 18px;
}

.risk-hazard-block {
  padding: 0 24px 5px;
  margin-top: 18px;
}

.risk-hazard-block__title {
  margin-top: 0;
}

.risk-hazard-block__chart {
  margin-top: 12px;
}

.risk-card {
  min-height: 124px;
  padding: 20px 18px;
  background: linear-gradient(180deg, rgb(255 255 255 / 42%) 0%, rgb(220 232 250 / 28%) 100%);
  border: 1px solid rgb(255 255 255 / 58%);
  border-radius: 18px;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 74%),
    0 8px 18px rgb(63 103 171 / 7%);
}

.risk-card__title {
  display: flex;
  font-size: 16px;
  font-weight: 800;
  align-items: center;
  gap: 8px;
}

.risk-card__dot {
  width: 14px;
  height: 14px;
  border-radius: 999px;
  box-shadow: 0 0 0 4px rgb(255 255 255 / 35%);
}

.risk-card__desc {
  margin-top: 18px;
  font-size: 13px;
  font-weight: 600;
  color: #6f819a;
  line-height: 1.35;
}

.qualification-panel {
  display: grid;
  margin-top: 26px;
  padding: 28px;
  grid-template-columns: 140px 1fr;
  padding-left: 120px;
  align-items: center;
  gap: 26px;
}

.qualification-icon {
  display: flex;
  width: 132px;
  height: 132px;
  font-size: 74px;
  color: #f09717;
  background: radial-gradient(
    circle at 50% 40%,
    rgb(255 255 255 / 74%) 0%,
    rgb(231 240 255 / 42%) 100%
  );
  border: 1px solid rgb(255 255 255 / 72%);
  border-radius: 32px;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 85%),
    0 10px 22px rgb(55 94 160 / 10%);
  align-items: center;
  justify-content: center;
}

.qualification-list {
  display: grid;
  gap: 22px;
}

.qualification-item {
  font-size: 24px;
  font-weight: 700;
  color: #516785;
}

.qualification-item--clickable {
  cursor: pointer;
  transition:
    transform 0.18s ease,
    opacity 0.18s ease;
}

.qualification-item--clickable:hover {
  transform: translateX(4px);
  opacity: 0.9;
}

.qualification-item strong {
  font-size: 28px;
}

.certificate-warning-dialog {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.bottom-grid {
  display: grid;
  margin-top: 10px;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 24px;
}

.bottom-card {
  min-height: 180px;
  padding: 15px 22px 0;
  overflow: hidden;
}

.bottom-card__header {
  display: flex;
  align-items: center;
  gap: 16px;
}

.bottom-card__icon {
  width: 54px;
  height: 54px;
}

.bottom-card__title {
  font-family: YouSheBiaoTiHei, sans-serif;
  font-size: 24px;
  color: #114a9b;
  letter-spacing: 1px;
}

.bottom-card__content {
  position: relative;
  z-index: 2;
  margin-top: 18px;
}

.bottom-card__content p {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  color: #5d718e;
  line-height: 1.7;
}

.certificate-board {
  padding: 16px 18px 24px;
}

.certificate-filter-panel {
  padding: 18px 20px 12px;
}

.certificate-filters {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)) auto;
  gap: 18px 20px;
  align-items: end;
}

.certificate-filter-item {
  display: flex;
  align-items: center;
  gap: 14px;
}

.certificate-filter-item__label {
  flex-shrink: 0;
  font-size: 16px;
  font-weight: 700;
  color: #4f6583;
}

.certificate-filter-item__control {
  flex: 1;
  height: 42px;
}

.certificate-filter-item__control :deep(.el-select__wrapper),
.certificate-filter-item__control :deep(.el-input__wrapper) {
  height: 42px !important;
  min-height: 42px !important;
  border-radius: 12px;
}

.certificate-filter-actions :deep(.el-button) {
  height: 42px;
  line-height: 42px;
  padding: 0 22px;
  border-radius: 12px;
}

.certificate-filter-item__control :deep(.el-input__inner) {
  height: 42px;
  line-height: 42px;
}

.certificate-filter-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: flex-end;
}

.certificate-table-panel {
  margin-top: 18px;
  padding: 18px 18px 12px;
  height: 860px;
  display: flex;
  flex-direction: column;
}

.certificate-table {
  flex: 1;
}

.file-name-text {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

// :deep(.el-input__inner) {
//   font-size: 14px !important;
//   border: none !important;
//   font-size: 14px !important;
// }

:deep(.datepicker .el-input__wrapper) {
  background: transparent !important;
  border: none !important;
  font-size: 14px !important;
}

:deep(.el-input) {
  border: none !important;
  outline: none !important;
  font-size: 14px !important;
}

:deep(.el-date-editor.el-input, .el-date-editor.el-input__inner) {
  border: none !important;
  font-size: 14px !important;
}

:deep(.el-date-editor.is-active) {
  border-color: #ff6a00 !important;
}

.certificate-pagination {
  padding-top: 0px;
}

.production-brief-table {
  width: 100%;

  :deep(.el-table__header-wrapper th.el-table__cell) {
    font-size: calc(16px * var(--kb-scale, 1));
    line-height: 1.2;
  }

  :deep(.el-table__body td.el-table__cell) {
    padding: calc(7px * var(--kb-scale, 1)) 0;
    font-size: calc(14px * var(--kb-scale, 1));
  }
}

.summary-toolbar__picker {
  :deep(*) {
    font-size: 14px !important;
  }

  :deep(input) {
    font-size: 14px !important;
    line-height: 14px !important;
  }
}

/* 过期行的红色背景 - 基础状态 */
:deep(.el-table__body tr.expired-row > td.el-table__cell) {
  background-color: #ffe6e6 !important;
}

/* 过期行 - 鼠标悬浮状态 */
:deep(.el-table__body tr.expired-row:hover > td.el-table__cell) {
  background-color: #ffcccc !important;
}

/* 确保斑马纹不影响过期行 */
:deep(.el-table__body tr.expired-row.el-table__row--striped > td.el-table__cell) {
  background-color: #ffe6e6 !important;
}

:deep(.el-table__body tr.expired-row.el-table__row--striped:hover > td.el-table__cell) {
  background-color: #ffcccc !important;
}

/* 预警行的橙色背景 - 基础状态 */
:deep(.el-table__body tr.alert-warn-row > td.el-table__cell) {
  background-color: #fff1df !important;
}

/* 预警行 - 鼠标悬浮状态 */
:deep(.el-table__body tr.alert-warn-row:hover > td.el-table__cell) {
  background-color: #ffe2bf !important;
}

/* 确保斑马纹不影响预警行 */
:deep(.el-table__body tr.alert-warn-row.el-table__row--striped > td.el-table__cell) {
  background-color: #fff1df !important;
}

:deep(.el-table__body tr.alert-warn-row.el-table__row--striped:hover > td.el-table__cell) {
  background-color: #ffe2bf !important;
}
</style>
