From b12b55a5ee1b34b5a3f9d21533fa9fc909207285 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期四, 05 二月 2026 09:40:13 +0800
Subject: [PATCH] Merge branch 'dev_New' of http://114.132.189.42:9002/r/product-inventory-management into dev_New
---
src/views/reportAnalysis/qualityAnalysis/components/center-center.vue | 355 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 355 insertions(+), 0 deletions(-)
diff --git a/src/views/reportAnalysis/qualityAnalysis/components/center-center.vue b/src/views/reportAnalysis/qualityAnalysis/components/center-center.vue
new file mode 100644
index 0000000..8d28f7a
--- /dev/null
+++ b/src/views/reportAnalysis/qualityAnalysis/components/center-center.vue
@@ -0,0 +1,355 @@
+<template>
+ <div>
+ <div class="warn-panel">
+ <div class="warn-header">
+ <div class="warn-header-left">
+ <div class="warn-badge"></div>
+ <span class="warn-title">涓嶅悎鏍奸璀�</span>
+ </div>
+ <div class="warn-range" @click="handleRangeClick">杩�7澶�</div>
+ </div>
+
+ <div class="warn-body">
+ <div class="warn-list" role="list">
+ <div v-for="item in warnings" :key="item.id" class="warn-item" role="listitem" @click="openWarning(item)">
+ <div class="warn-tag" :class="tagClass(item.type)">{{ item.parentProductTitle }}-{{ item.productTitle }}
+ </div>
+ <div class="warn-text" :title="item.title">{{ item.title }}</div>
+ <div class="warn-action" @click.stop="openWarning(item)">鏌ョ湅</div>
+ <div class="warn-date">{{ item.date }}</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script setup>
+import { computed, getCurrentInstance, ref, onMounted } from 'vue'
+import Echarts from '@/components/Echarts/echarts.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'
+ if (type === 'final') return 'tag-final'
+ return 'tag-semi'
+}
+
+// 鏍规嵁productTitle鏄犲皠绫诲瀷
+const mapProductTitleToType = (productTitle) => {
+ if (productTitle === '鍘熸潗鏂�') return 'raw'
+ if (productTitle === '鍗婃垚鍝�') return 'semi'
+ if (productTitle === '鎴愬搧') return 'final'
+ 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 || []
+ warnings.value = children.map((item, idx) => {
+ const type = mapProductTitleToType(item.parentProductTitle)
+ const date = item.date ? item.date.replace(/-/g, '.') : ''
+ return {
+ id: item.id ?? `warning-${idx}`,
+ type,
+ parentProductTitle: item.parentProductTitle || '鍘熸潗鏂�',
+ productTitle: item.productTitle || '鍘熸潗鏂�',
+ title: item.description || '涓嶅悎鏍奸璀�',
+ date,
+ }
+ })
+ }
+ } catch (e) {
+ // 鎺ュ彛澶辫触鍒欎繚鎸佺┖鏁版嵁
+ console.error('鑾峰彇涓嶅悎鏍奸璀﹀け璐�:', e)
+ }
+}
+
+const openWarning = (item) => {
+ const title = `銆�${item.parentProductTitle}-${item.productTitle}銆�${item.title}`
+ if (proxy?.$modal?.alert) {
+ proxy.$modal.alert(title)
+ return
+ }
+ // 鍏滃簳锛氭病鏈夊叏灞� modal 鏃剁敤 console
+ console.log('warning:', { ...item })
+}
+
+const handleRangeClick = () => {
+ // 鍏堟寜鎴浘鍋氶潤鎬佲�滆繎7澶┾�濓紝鍚庣画鏈夌湡瀹炵瓫閫夐渶姹傚啀鎺ュ叆
+}
+
+onMounted(() => {
+ fetchWarnings()
+})
+</script>
+
+<style scoped>
+.warn-panel {
+ border: 1px solid #1a58b0;
+ padding: 0 18px 18px;
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ height: 100%;
+ box-sizing: border-box;
+}
+
+.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;
+ padding: 10px 0 6px;
+}
+
+.warn-header-left {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.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);
+}
+
+.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;
+ line-height: 24px;
+}
+
+.warn-range {
+ height: 32px;
+ padding: 0 14px;
+ 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);
+ cursor: pointer;
+}
+
+.warn-body {
+ display: grid;
+ gap: 18px;
+ align-items: stretch;
+ min-height: 260px;
+}
+
+.warn-list {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ padding-top: 6px;
+}
+
+.warn-item {
+ display: grid;
+ grid-template-columns: 130px 1fr auto 110px;
+ align-items: center;
+ gap: 12px;
+ color: #b8c8e0;
+ font-size: 14px;
+ line-height: 1.2;
+ padding: 8px 0;
+ border-radius: 4px;
+ transition: background-color 0.2s, color 0.2s;
+}
+
+.warn-item:hover {
+ color: #ff4d4f;
+ background-color: rgba(255, 77, 79, 0.06);
+}
+
+.warn-item:hover .warn-text {
+ color: #ff4d4f;
+}
+
+.warn-tag {
+ height: 28px;
+ padding: 0 10px;
+ border-radius: 4px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 700;
+ color: #ffffff;
+}
+
+.tag-raw {
+ background: #7c4dff;
+}
+
+.tag-final {
+ background: #f5a000;
+}
+
+.tag-semi {
+ background: #ff66cc;
+}
+
+.warn-text {
+ color: #e8f1ff;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.warn-action {
+ color: #ff4d4f;
+ font-weight: 700;
+ white-space: nowrap;
+ cursor: pointer;
+}
+
+.warn-date {
+ color: rgba(184, 200, 224, 0.75);
+ 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;
+}
+</style>
--
Gitblit v1.9.3