src/views/reportAnalysis/PSIDataAnalysis/components/center-center.vue
@@ -1,159 +1,142 @@
<template>
  <div>
    <!-- 设备统计 -->
    <div class="equipment-stats">
      <div class="equipment-header">
        <img
          src="@/assets/BI/shujutongjiicon@2x.png"
          alt="图标"
          class="equipment-icon"
        />
        <span class="equipment-title">产品周转天数</span>
  <div class="kpi-stack">
    <div class="stats-cards">
      <div
        v-for="item in statItems"
        :key="item.name"
        class="stat-card"
      >
        <img src="@/assets/BI/icon@2x.png" alt="图标" class="card-icon" />
        <div class="card-content">
          <span class="card-label">{{ item.name }}</span>
          <span class="card-value">{{ item.value }}</span>
          <div class="card-compare" :class="compareClass(Number(item.rate))">
            <span>同比</span>
            <span class="compare-value">{{ formatPercent(item.rate) }}</span>
            <span class="compare-icon">{{ Number(item.rate) >= 0 ? '↑' : '↓' }}</span>
          </div>
        </div>
      </div>
      <Echarts
        ref="chart"
        :chartStyle="chartStyle"
        :grid="grid"
        :legend="barLegend"
        :series="barSeries1"
        :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 Echarts from '@/components/Echarts/echarts.vue'
import { customerRevenueAnalysis } from '@/api/viewIndex.js'
import { listCustomer } from '@/api/basicData/customerFile.js'
import { salesPurchaseStorageProductCount } from '@/api/viewIndex.js'
const dateType = ref(1)
const customerValue = ref(null)
const customerOptions = ref([])
const statItems = ref([])
const chartStyle = { width: '100%', height: '100%' }
const grid = { left: '3%', right: '4%', bottom: '3%', top: '4%', containLabel: true }
const barLegend = { show: false, textStyle: { color: '#B8C8E0' }, data: ['营收'] }
const barSeries1 = ref([
  {
    name: '营收',
    type: 'bar',
    barGap: 0,
    barWidth: 30,
    emphasis: { focus: 'series' },
    itemStyle: {
      color: {
        type: 'linear',
        x: 0, y: 1, x2: 0, y2: 0,
        colorStops: [
          { offset: 0, color: 'rgba(0,164,237,0)' },
          { offset: 1, color: '#4EE4FF' },
        ],
      },
    },
    data: [],
  },
])
const tooltip = {
  trigger: 'axis',
  axisPointer: { type: 'shadow' },
  formatter(params) {
    let result = params[0].axisValueLabel + '<br/>'
    params.forEach((item) => {
      result += `<div>${item.marker} ${item.seriesName}: ${item.value}</div>`
    })
    return result
  },
const formatPercent = (val) => {
  const num = Number(val) || 0
  return `${num.toFixed(2)}%`
}
const xAxis1 = ref([{ type: 'category', axisTick: { show: false }, axisLabel: { color: '#B8C8E0' }, data: [] }])
const yAxis1 = [{ type: 'value', axisLabel: { color: '#B8C8E0' } }]
const getCustomerRevenueAnalysis = () => {
  if (customerOptions.value.length > 0 && !customerValue.value) customerValue.value = customerOptions.value[0].value
  if (!customerValue.value) return
  customerRevenueAnalysis({ customerId: customerValue.value, type: dateType.value })
const compareClass = (val) => (val >= 0 ? 'compare-up' : 'compare-down')
const fetchData = () => {
  salesPurchaseStorageProductCount()
    .then((res) => {
      xAxis1.value[0].data = []
      barSeries1.value[0].data = []
      const items = res.data?.items || []
      items.forEach((item) => {
        xAxis1.value[0].data.push(item.name)
        barSeries1.value[0].data.push(item.value)
      })
      if (res.code === 200 && Array.isArray(res.data)) {
        statItems.value = res.data.map((item) => ({
          name: item.name,
          value: item.value,
          rate: item.rate,
        }))
      }
    })
    .catch((e) => console.error('获取客户营收分析失败:', e))
}
const fetchCustomerOptions = async () => {
  try {
    const res = await listCustomer({ pageNum: 1, pageSize: 200 })
    const records = res?.records || res?.data?.records || res?.rows || []
    customerOptions.value = records.map((r) => ({
      label: r.customerName || r.name || r.customer || '-',
      value: r.id ?? r.customerId ?? r.customerCode ?? r.customerName,
    }))
    if (customerOptions.value.length > 0 && !customerValue.value) {
      customerValue.value = customerOptions.value[0].value
      getCustomerRevenueAnalysis()
    }
  } catch (e) {
    customerOptions.value = [
      { label: '华东精密', value: '华东精密' },
      { label: '星辰电子', value: '星辰电子' },
      { label: '启航科技', value: '启航科技' },
      { label: '铭诚制造', value: '铭诚制造' },
      { label: '远景材料', value: '远景材料' },
    ]
  }
    .catch((err) => {
      console.error('获取销售/采购/储存产品数失败:', err)
    })
}
onMounted(() => {
  fetchCustomerOptions()
  fetchData()
})
</script>
<style scoped>
.equipment-stats {
  border: 1px solid #1a58b0;
  padding: 0 18px 18px;
.kpi-stack {
  flex-shrink: 0;
}
.stats-cards {
  display: flex;
  flex-direction: column;
  gap: 16px;
  gap: 30px;
}
.equipment-header {
  font-weight: 500;
  font-size: 21px;
.stat-card {
  display: flex;
  border-bottom: 1px solid;
  border-image: linear-gradient(
      270deg,
      rgba(0, 126, 255, 0) 0%,
      rgba(0, 126, 255, 0.4549) 35%,
      #007eff 78%,
      #007eff 100%
    )
    1;
  padding-bottom: 2px;
  align-items: center;
  background-image: url('@/assets/BI/border@2x.png');
  background-size: 100% 100%;
  background-position: center;
  background-repeat: no-repeat;
  height: 142px;
  width: 100%;
  box-sizing: border-box;
}
.equipment-title {
.card-icon {
  width: 100px;
  height: 100px;
  margin: 20px 20px 0 10px;
  flex-shrink: 0;
}
.card-content {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}
.card-value {
  font-weight: 500;
  font-size: 18px;
  background: linear-gradient(360deg, #056dff 0%, #43e8fc 100%);
  font-size: 40px;
  background: linear-gradient(360deg, #008bfd 0%, #ffffff 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  line-height: 50px;
}
.equipment-icon {
  width: 50px;
  height: 50px;
.card-label {
  font-weight: 400;
  font-size: 19px;
  color: rgba(208, 231, 255, 0.7);
}
.card-compare {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 15px;
  color: #d0e7ff;
}
.card-compare > span:first-child {
  font-size: 13px;
  opacity: 0.8;
}
.compare-value {
  font-weight: 600;
}
.compare-icon {
  font-size: 14px;
  position: relative;
  top: -1px;
}
.compare-up .compare-value,
.compare-up .compare-icon {
  color: #00c853;
}
.compare-down .compare-value,
.compare-down .compare-icon {
  color: #ff5252;
}
</style>