云
2026-09-15 1c829f9177eab675b22be4d20ef2761ed1bbb423
src/views/reportAnalysis/qualityAnalysis/components/center-center.vue
@@ -1,5 +1,5 @@
<template>
  <div>
  <div class="panel-root">
    <div class="warn-panel">
      <div class="warn-header">
        <div class="warn-header-left">
@@ -25,26 +25,12 @@
</template>
<script setup>
import { computed, getCurrentInstance, ref, onMounted } from 'vue'
import Echarts from '@/components/Echarts/echarts.vue'
import { getCurrentInstance, ref, onMounted } from 'vue'
import { nonComplianceWarning } from '@/api/viewIndex.js'
const { proxy } = getCurrentInstance() || {}
const warnings = ref([])
// 占比数据
const ratios = ref({
  rawMaterialRatio: 0,
  semiFinishedProductRatio: 0,
  finishedProductRatio: 0,
})
const TAG_COLORS = {
  raw: '#7C4DFF',
  final: '#F5A000',
  semi: '#FF66CC',
}
const tagClass = (type) => {
  if (type === 'raw') return 'tag-raw'
@@ -60,71 +46,11 @@
  return 'raw' // 默认值
}
const pieChartStyle = { width: '100%', height: '100%' }
const pieOptions = {
  backgroundColor: 'transparent',
  textStyle: { color: '#B8C8E0' },
}
const pieTooltip = {
  trigger: 'item',
  formatter: (p) => `${p.name}:${p.value}%`,
}
const pieData = computed(() => {
  return [
    { name: '原材料', value: ratios.value.rawMaterialRatio, itemStyle: { color: TAG_COLORS.raw } },
    { name: '半成品', value: ratios.value.semiFinishedProductRatio, itemStyle: { color: TAG_COLORS.semi } },
    { name: '成品', value: ratios.value.finishedProductRatio, itemStyle: { color: TAG_COLORS.final } },
  ]
})
const pieSeries = computed(() => {
  return [
    {
      type: 'pie',
      radius: ['0%', '68%'],
      center: ['50%', '50%'],
      startAngle: 90,
      clockwise: true,
      avoidLabelOverlap: true,
      label: { show: false },
      labelLine: { show: false },
      itemStyle: {
        borderColor: '#071a3a',
        borderWidth: 4,
        shadowBlur: 14,
        shadowColor: 'rgba(0, 0, 0, 0.35)',
      },
      data: pieData.value,
    },
    {
      // 内圈暗环,增强层次
      type: 'pie',
      radius: ['70%', '74%'],
      center: ['50%', '50%'],
      silent: true,
      label: { show: false },
      labelLine: { show: false },
      itemStyle: { color: 'rgba(78, 228, 255, 0.12)' },
      data: [1],
    },
  ]
})
const fetchWarnings = async () => {
  try {
    const res = await nonComplianceWarning()
    if (res?.code === 200 && res?.data) {
      const data = res.data
      // 更新占比数据
      ratios.value = {
        rawMaterialRatio: data.rawMaterialRatio ?? 0,
        semiFinishedProductRatio: data.semiFinishedProductRatio ?? 0,
        finishedProductRatio: data.finishedProductRatio ?? 0,
      }
      // 更新警告列表
      const children = data.children || []
@@ -167,26 +93,32 @@
</script>
<style scoped>
.panel-root {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.warn-panel {
  border: 1px solid #1a58b0;
  border: 1px solid var(--bi-panel-border);
  background: var(--bi-panel-bg);
  border-radius: 8px;
  padding: 0 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
  flex: 1;
  min-height: 0;
  box-sizing: border-box;
  overflow: hidden;
}
.warn-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  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;
  border-bottom: 1px solid rgba(143, 163, 200, 0.15);
  padding: 10px 0 6px;
}
@@ -196,43 +128,50 @@
  gap: 10px;
}
/* 品牌蓝细竖条,与 PanelHeader 呼应 */
.warn-badge {
  width: 18px;
  height: 18px;
  background: linear-gradient(180deg, #2aa8ff 0%, #4ee4ff 100%);
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  box-shadow: 0 0 12px rgba(78, 228, 255, 0.25);
  width: 3px;
  height: 14px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--bi-accent-bright) 0%, var(--bi-accent) 100%);
  flex-shrink: 0;
}
.warn-title {
  font-weight: 600;
  font-size: 18px;
  background: linear-gradient(360deg, #056dff 0%, #43e8fc 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  font-weight: 500;
  font-size: 16px;
  color: var(--bi-text-strong);
  letter-spacing: 1px;
  line-height: 24px;
}
.warn-range {
  height: 32px;
  padding: 0 14px;
  height: 28px;
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  color: #ffffff;
  font-weight: 600;
  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);
  border-radius: 6px;
  color: var(--bi-text-strong);
  font-weight: 500;
  font-size: 13px;
  background: rgba(74, 108, 240, 0.15);
  border: 1px solid rgba(74, 108, 240, 0.35);
  cursor: pointer;
  transition: border-color 0.2s ease;
}
.warn-range:hover {
  border-color: var(--bi-accent-bright);
}
.warn-body {
  display: grid;
  gap: 18px;
  align-items: stretch;
  min-height: 260px;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
.warn-list {
@@ -247,7 +186,7 @@
  grid-template-columns: 130px 1fr auto 110px;
  align-items: center;
  gap: 12px;
  color: #b8c8e0;
  color: var(--bi-text);
  font-size: 14px;
  line-height: 1.2;
  padding: 8px 0;
@@ -256,100 +195,58 @@
}
.warn-item:hover {
  color: #ff4d4f;
  background-color: rgba(255, 77, 79, 0.06);
  color: var(--bi-down);
  background-color: rgba(255, 107, 107, 0.06);
}
.warn-item:hover .warn-text {
  color: #ff4d4f;
  color: var(--bi-down);
}
.warn-tag {
  height: 28px;
  height: 24px;
  padding: 0 10px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-weight: 500;
  font-size: 12px;
  color: #ffffff;
  white-space: nowrap;
  overflow: hidden;
}
/* 序列色区分检测环节,与大屏图表配色一致 */
.tag-raw {
  background: #7c4dff;
  background: var(--bi-accent-bright);
}
.tag-final {
  background: #f5a000;
  background: #8E7CE6;
}
.tag-semi {
  background: #ff66cc;
  background: #35C6D6;
}
.warn-text {
  color: #e8f1ff;
  color: var(--bi-text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.warn-action {
  color: #ff4d4f;
  font-weight: 700;
  color: var(--bi-down);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.warn-date {
  color: rgba(184, 200, 224, 0.75);
  color: var(--bi-text);
  white-space: nowrap;
}
.warn-chart {
  display: flex;
  align-items: center;
  justify-content: center;
}
.chart-frame {
  width: 100%;
  height: 260px;
  border: 2px dashed rgba(184, 200, 224, 0.35);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at 50% 50%, rgba(78, 228, 255, 0.08) 0%, rgba(0, 0, 0, 0) 65%);
}
/* 外圈刻度环 */
.chart-frame::before {
  content: '';
  position: absolute;
  width: 220px;
  height: 220px;
  border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, rgba(78, 228, 255, 0.75) 0 1deg, rgba(78, 228, 255, 0) 1deg 9deg);
  -webkit-mask: radial-gradient(circle, transparent 62%, #000 63%);
  mask: radial-gradient(circle, transparent 62%, #000 63%);
  opacity: 0.5;
  pointer-events: none;
}
/* 十字辅助线 */
.chart-frame::after {
  content: '';
  position: absolute;
  width: 240px;
  height: 240px;
  background:
    linear-gradient(to right, rgba(78, 228, 255, 0) 0%, rgba(78, 228, 255, 0.55) 50%, rgba(78, 228, 255, 0) 100%),
    linear-gradient(to bottom, rgba(78, 228, 255, 0) 0%, rgba(78, 228, 255, 0.55) 50%, rgba(78, 228, 255, 0) 100%);
  background-size: 100% 1px, 1px 100%;
  background-position: center, center;
  background-repeat: no-repeat;
  opacity: 0.35;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}
</style>