spring
2 天以前 b12b55a5ee1b34b5a3f9d21533fa9fc909207285
src/views/reportAnalysis/qualityAnalysis/components/center-bottom.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,254 @@
<template>
  <div>
    <div class="chart-header">
      <PanelHeader title="完成检验数" />
      <div class="warn-range" @click="handleRangeClick">近7天</div>
    </div>
    <div class="main-panel panel-item-customers">
      <Echarts
          ref="chart"
          :chartStyle="chartStyle"
          :grid="grid"
          :legend="barLegend"
          :series="chartSeries"
          :tooltip="tooltip"
          :xAxis="xAxis1"
          :yAxis="yAxis1"
          :options="{ backgroundColor: 'transparent', textStyle: { color: '#B8C8E0' } }"
          style="height: 260px"
      />
    </div>
  </div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { completedInspectionCount } from '@/api/viewIndex.js'
import PanelHeader from './PanelHeader.vue'
import Echarts from '@/components/Echarts/echarts.vue'
const chartStyle = {
  width: '100%',
  height: '135%',
}
const grid = { left: '8%', right: '8%', bottom: '8%', top: '15%', containLabel: true }
const barLegend = {
  show: true,
  top: '5%',
  left: 'center',
  textStyle: { color: '#B8C8E0', fontSize: 14 },
  itemGap: 30,
  data: ['合格', '不合格', '合格率'],
}
// æŸ±çŠ¶å›¾ï¼šåˆæ ¼ï¼ˆé»„è‰²ï¼‰ã€ä¸åˆæ ¼ï¼ˆç´«è‰²ï¼‰ï¼›æŠ˜çº¿å›¾ï¼šåˆæ ¼çŽ‡ï¼ˆè“è‰²ï¼‰
const chartSeries = ref([
  {
    name: '合格',
    type: 'bar',
    barWidth: 20,
    barGap: '20%',
    yAxisIndex: 0,
    emphasis: { focus: 'series' },
    itemStyle: {
      color: {
        type: 'linear',
        x: 0,
        y: 0,
        x2: 0,
        y2: 1,
        colorStops: [
          { offset: 0, color: 'rgba(255, 215, 0, 1)' }, // é‡‘黄色顶部
          { offset: 1, color: 'rgba(255, 215, 0, 0.5)' }, // åŠé€æ˜Žåº•部
        ],
      },
    },
    data: [],
  },
  {
    name: '不合格',
    type: 'bar',
    barGap: '20%',
    barWidth: 20,
    yAxisIndex: 0,
    emphasis: { focus: 'series' },
    itemStyle: {
      color: {
        type: 'linear',
        x: 0,
        y: 0,
        x2: 0,
        y2: 1,
        colorStops: [
          { offset: 0, color: 'rgba(144, 97, 248, 1)' }, // ç´«è‰²é¡¶éƒ¨
          { offset: 1, color: 'rgba(144, 97, 248, 0.6)' }, // åŠé€æ˜Žåº•部
        ],
      },
    },
    data: [],
  },
  {
    name: '合格率',
    type: 'line',
    yAxisIndex: 1,
    smooth: true,
    symbol: 'circle',
    symbolSize: 8,
    lineStyle: {
      color: 'rgba(78, 228, 255, 1)', // é’色
      width: 2,
    },
    itemStyle: {
      color: 'rgba(78, 228, 255, 1)',
      borderWidth: 2,
      borderColor: '#fff',
    },
    emphasis: {
      focus: 'series',
      itemStyle: {
        shadowBlur: 10,
        shadowColor: 'rgba(78, 228, 255, 0.8)',
      },
    },
    data: [],
  },
])
const tooltip = {
  trigger: 'axis',
  axisPointer: { type: 'cross' },
  backgroundColor: 'rgba(0, 0, 0, 0.8)',
  borderColor: 'rgba(78, 228, 255, 0.5)',
  borderWidth: 1,
  textStyle: { color: '#B8C8E0' },
  formatter(params) {
    let result = params[0].axisValueLabel + '<br/>'
    params.forEach((item) => {
      let unit = ''
      if (item.seriesName === '合格率') {
        unit = '%'
      } else {
        unit = 'ä»¶'
      }
      result += `<div style="margin: 4px 0;">${item.marker} ${item.seriesName}: ${item.value}${unit}</div>`
    })
    return result
  },
}
const xAxis1 = ref([
  {
    type: 'category',
    axisTick: { show: false },
    axisLabel: { color: '#B8C8E0', fontSize: 12 },
    axisLine: { lineStyle: { color: 'rgba(184, 200, 224, 0.3)' } },
    data: [],
  },
])
const yAxis1 = [
  {
    type: 'value',
    name: '单位: ä»¶',
    nameLocation: 'start',
    nameTextStyle: { color: '#B8C8E0', fontSize: 12, padding: [0, 0, 0, 10] },
    axisLabel: { color: '#B8C8E0', fontSize: 12 },
    axisLine: { show: false },
    splitLine: {
      show: true,
      lineStyle: { color: 'rgba(184, 200, 224, 0.2)', type: 'dashed' },
    },
  },
  {
    type: 'value',
    name: '单位: %',
    nameLocation: 'end',
    nameTextStyle: { color: '#B8C8E0', fontSize: 12, padding: [0, 0, 0, 10] },
    min: 0,
    max: 100,
    axisLabel: { color: '#B8C8E0', fontSize: 12, formatter: '{value}' },
    axisLine: { show: false },
    splitLine: {
      show: true,
      lineStyle: { color: 'rgba(184, 200, 224, 0.2)', type: 'dashed' },
    },
  },
]
const fetchData = () => {
  completedInspectionCount()
    .then((res) => {
      if (res?.code === 200 && Array.isArray(res?.data)) {
        const items = res.data
        // æ›´æ–°X轴日期数据
        xAxis1.value[0].data = items.map((d) => d.dateStr || '')
        // æ›´æ–°åˆæ ¼æ•°ï¼ˆé»„色柱状图)
        chartSeries.value[0].data = items.map((d) => Number(d.qualifiedCount) || 0)
        // æ›´æ–°ä¸åˆæ ¼æ•°ï¼ˆç´«è‰²æŸ±çŠ¶å›¾ï¼‰
        chartSeries.value[1].data = items.map((d) => Number(d.unqualifiedCount) || 0)
        // æ›´æ–°åˆæ ¼çŽ‡ï¼ˆè“è‰²æŠ˜çº¿å›¾ï¼‰
        chartSeries.value[2].data = items.map((d) => Number(d.passRate) || 0)
      }
    })
    .catch((err) => {
      console.error('获取完成检验数数据失败:', err)
    })
}
const handleRangeClick = () => {
  // å…ˆæŒ‰æˆªå›¾åšé™æ€"近7天",后续有真实筛选需求再接入
  fetchData()
}
onMounted(() => {
  fetchData()
})
</script>
<style scoped>
.chart-header {
  position: relative;
  display: flex;
  align-items: center;
}
.warn-range {
  position: absolute;
  right: 0;
  top: 0;
  height: 32px;
  padding: 0 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  color: #ffffff;
  font-weight: 600;
  font-size: 14px;
  background: linear-gradient(180deg, rgba(51, 120, 255, 1) 0%, rgba(0, 164, 237, 1) 100%);
  border: 1px solid rgba(78, 228, 255, 0.25);
  cursor: pointer;
  z-index: 10;
}
.warn-range:hover {
  background: linear-gradient(180deg, rgba(51, 140, 255, 1) 0%, rgba(0, 184, 237, 1) 100%);
}
.main-panel {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.panel-item-customers {
  border: 1px solid #1a58b0;
  padding: 18px;
  width: 100%;
  height: 449px;
  position: relative;
  background: radial-gradient(circle at 50% 50%, rgba(78, 228, 255, 0.05) 0%, rgba(0, 0, 0, 0) 70%);
}
</style>