From e14d8f605015007082cd992830869dc0d62155c3 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 15 十月 2025 10:01:47 +0800
Subject: [PATCH] 生产管控-智能排产、物料看板页面联调

---
 src/api/productionScheduling/index.js                |   29 ++
 src/views/productionControl/reportAnalysis/index.vue |  773 ++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 544 insertions(+), 258 deletions(-)

diff --git a/src/api/productionScheduling/index.js b/src/api/productionScheduling/index.js
index 8d6a941..4940576 100644
--- a/src/api/productionScheduling/index.js
+++ b/src/api/productionScheduling/index.js
@@ -106,4 +106,33 @@
         method: 'get',
         params: query
     })
+}
+
+// 鑾峰彇鎶ヨ〃缁熻鏁版嵁
+export function getReportStatistics(query) {
+    return request({
+        url: '/productHome/reportStatistics',
+        method: 'get',
+        params: query
+    })
+}
+
+// 鑾峰彇杈炬爣鐜囪秼鍔挎暟鎹�
+export function getReportTrend(query) {
+    return request({
+        url: '/productHome/reportTrend',
+        method: 'get',
+        params: {
+            dto: query
+        }
+    })
+}
+
+// 鑾峰彇鍔犲伐寰楃巼鍒嗘瀽鏁版嵁
+export function processingRateAnalysis(query) {
+    return request({
+        url: '/productHome/processingRateAnalysis',
+        method: 'get',
+        params: query
+    })
 }
\ No newline at end of file
diff --git a/src/views/productionControl/reportAnalysis/index.vue b/src/views/productionControl/reportAnalysis/index.vue
index e6533c6..4d5dd16 100644
--- a/src/views/productionControl/reportAnalysis/index.vue
+++ b/src/views/productionControl/reportAnalysis/index.vue
@@ -29,8 +29,7 @@
 				</div>
 				<div class="card-content">
 					<div class="card-title">鍗曚綅鐑�艰�楃叅閲�</div>
-					<div class="card-value">{{ unitHeatCoalConsumption.toFixed(2) }} kg/GJ</div>
-					<div class="card-desc">瓒婁綆瓒婂ソ</div>
+					<div class="card-value">{{ unitHeatValue.toFixed(2) }} kg/GJ</div>
 				</div>
 			</div>
 			
@@ -40,8 +39,7 @@
 				</div>
 				<div class="card-content">
 					<div class="card-title">鏁翠綋杈炬爣鐜�</div>
-					<div class="card-value">{{ overallComplianceRate.toFixed(2) }}%</div>
-					<div class="card-desc">鍙戠儹閲忊墺5000澶у崱</div>
+					<div class="card-value">{{ wholeStandardRate.toFixed(2) }}%</div>
 				</div>
 			</div>
 			
@@ -51,8 +49,7 @@
 				</div>
 				<div class="card-content">
 					<div class="card-title">骞冲潎鍙戠儹閲�</div>
-					<div class="card-value">{{ averageCalorificValue.toFixed(0) }} 澶у崱</div>
-					<div class="card-desc">瓒婇珮瓒婂ソ</div>
+					<div class="card-value">{{ averageFuel.toFixed(0) }} 澶у崱</div>
 				</div>
 			</div>
 			
@@ -62,8 +59,7 @@
 				</div>
 				<div class="card-content">
 					<div class="card-title">閰嶆柟浣跨敤棰戞</div>
-					<div class="card-value">{{ totalBatches }} 娆�</div>
-					<div class="card-desc">鏃堕棿鑼冨洿鍐�</div>
+					<div class="card-value">{{ frequency }} 娆�</div>
 				</div>
 			</div>
 			
@@ -73,8 +69,7 @@
 				</div>
 				<div class="card-content">
 					<div class="card-title">鎬绘壒娆�</div>
-					<div class="card-value">{{ totalBatches }}</div>
-					<div class="card-desc">鏃堕棿鑼冨洿鍐�</div>
+					<div class="card-value">{{ totalBatch }}</div>
 				</div>
 			</div>
 		</div>
@@ -89,11 +84,7 @@
 					</div>
 				</template>
 				<div class="chart-wrapper">
-					<Echarts
-						ref="complianceChartRef"
-						:options="complianceTrendOptions"
-						:chartStyle="{ height: '300px', width: '100%' }"
-					/>
+					<div ref="complianceChart" class="chart-content" style="height: 300px; width: 100%;"></div>
 				</div>
 			</el-card>
 			
@@ -105,30 +96,11 @@
 					</div>
 				</template>
 				<div class="chart-wrapper">
-					<Echarts
-						ref="calorificChartRef"
-						:options="calorificValueOptions"
-						:chartStyle="{ height: '300px', width: '100%' }"
-					/>
+					<div ref="coalTypeHeatValueChart" class="chart-content" style="height: 300px; width: 100%;"></div>
 				</div>
 			</el-card>
 			
-			<!-- 閰嶆柟浣跨敤棰戞 -->
-			<el-card class="chart-card">
-				<template #header>
-					<div class="card-header">
-						<span>閰嶆柟浣跨敤棰戞</span>
-					</div>
-				</template>
-				<div class="chart-wrapper">
-					<Echarts
-						ref="recipeChartRef"
-						:options="recipeFrequencyOptions"
-						:chartStyle="{ height: '300px', width: '100%' }"
-					/>
-				</div>
-			</el-card>
-			
+
 			<!-- 鍔犲伐寰楃巼鍒嗘瀽 -->
 			<el-card class="chart-card">
 				<template #header>
@@ -137,27 +109,19 @@
 					</div>
 				</template>
 				<div class="chart-wrapper">
-					<Echarts
-						ref="yieldChartRef"
-						:options="processingYieldOptions"
-						:chartStyle="{ height: '300px', width: '100%' }"
-					/>
+					<div ref="yieldChart" class="chart-content" style="height: 300px; width: 100%;"></div>
 				</div>
 			</el-card>
 			
 			<!-- 鎴愭湰缁撴瀯鍥捐氨 -->
-			<el-card class="chart-card cost-structure">
+			<el-card class="chart-card">
 				<template #header>
 					<div class="card-header">
 						<span>鎴愭湰缁撴瀯鍥捐氨</span>
 					</div>
 				</template>
 				<div class="chart-wrapper">
-					<Echarts
-						ref="costChartRef"
-						:options="costStructureOptions"
-						:chartStyle="{ height: '300px', width: '100%' }"
-					/>
+					<div ref="costStructureChart" class="chart-content" style="height: 300px; width: 100%;"></div>
 				</div>
 			</el-card>
 		</div>
@@ -165,10 +129,31 @@
 </template>
 
 <script setup>
-import { ref, onMounted, computed } from 'vue'
+import { ref, onMounted, computed, nextTick } from 'vue'
 import * as echarts from 'echarts'
 import Echarts from '@/components/Echarts/echarts.vue'
 import { ElMessage } from 'element-plus'
+import { getReportStatistics, getReportTrend } from '@/api/productionScheduling/index.js'
+import { processingRateAnalysis } from '@/api/productionScheduling/index.js'
+import request from '@/utils/request'
+
+// 鎴愭湰缁撴瀯鍥捐氨API鍑芥暟 - 鐩存帴鍦ㄧ粍浠跺唴瀹氫箟
+const costStructure = (query) => {
+  return request({
+    url: '/productHome/costStructure',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鐓ょ鍙戠儹閲忓姣擜PI鍑芥暟 - 鏍规嵁鎺ュ彛鏂囨。瀹氫箟
+const coalTypeHeatValueComparison = (query) => {
+  return request({
+    url: '/productHome/coalTypeHeatValueComparison',
+    method: 'get',
+    params: query
+  })
+}
 
 
 // 鎼滅储鍙傛暟
@@ -207,120 +192,361 @@
 ]
 
 // 缁熻鏁版嵁
-const unitHeatCoalConsumption = ref(32.5)
-const overallComplianceRate = ref(85.7)
-const averageCalorificValue = ref(5260)
-const totalBatches = ref(48)
+const unitHeatValue = ref(0)
+const wholeStandardRate = ref(0)
+const averageFuel = ref(0)
+const frequency = ref(0)
+const totalBatch = ref(0)
 
-// 妯℃嫙鏁版嵁
-const mockComplianceData = [
-	{ date: '2023-06-01', rate: 82 },
-	{ date: '2023-06-02', rate: 85 },
-	{ date: '2023-06-03', rate: 88 },
-	{ date: '2023-06-04', rate: 84 },
-	{ date: '2023-06-05', rate: 87 },
-	{ date: '2023-06-06', rate: 90 },
-	{ date: '2023-06-07', rate: 86 },
-	{ date: '2023-06-08', rate: 89 },
-	{ date: '2023-06-09', rate: 92 },
-	{ date: '2023-06-10', rate: 88 }
-]
+// 杈炬爣鐜囪秼鍔挎暟鎹紩鐢�
+const complianceChart = ref(null)
 
-const mockCalorificData = [
-	{ name: '鐑熺叅', value: 5800 },
-	{ name: '鏃犵儫鐓�', value: 6200 },
-	{ name: '瑜愮叅', value: 4500 },
-	{ name: '璐叅', value: 5300 },
-	{ name: '鐦︾叅', value: 5500 }
-]
+// 鍔犲伐寰楃巼鍥捐〃寮曠敤
+const yieldChart = ref(null)
 
-const mockRecipeData = [
-	{ name: '閰嶆柟A (鐑熺叅60%+鏃犵儫鐓�40%)', value: 18 },
-	{ name: '閰嶆柟B (鐑熺叅70%+瑜愮叅30%)', value: 12 },
-	{ name: '閰嶆柟C (鏃犵儫鐓�50%+璐叅50%)', value: 8 },
-	{ name: '閰嶆柟D (鐑熺叅50%+鐦︾叅50%)', value: 6 },
-	{ name: '鍏朵粬閰嶆柟', value: 4 }
-]
+// 鎴愭湰缁撴瀯鍥捐〃寮曠敤
+const costStructureChart = ref(null)
 
-const mockYieldData = [
-	{ name: '鐑熺叅', yield: 85, efficiency: 92 },
-	{ name: '鏃犵儫鐓�', yield: 88, efficiency: 89 },
-	{ name: '瑜愮叅', yield: 75, efficiency: 78 },
-	{ name: '璐叅', yield: 82, efficiency: 85 },
-	{ name: '鐦︾叅', yield: 80, efficiency: 87 }
-]
+// 鐓ょ鍙戠儹閲忓姣斿浘琛ㄥ紩鐢�
+const coalTypeHeatValueChart = ref(null)
 
-const mockCostData = [
-	{ name: '鑰楁潗', value: 45 },
-	{ name: '鑳借��', value: 30 },
-	{ name: '浜哄姏', value: 25 }
-]
+// Echarts缁勪欢鍥捐〃涓嶉渶瑕侀澶栫殑寮曠敤鍙橀噺锛岀粍浠跺唴閮ㄤ細澶勭悊鍥捐〃鍒濆鍖�
+// 绉婚櫎鏈娇鐢ㄧ殑鍥捐〃寮曠敤鍙橀噺锛岄伩鍏嶅彲鑳界殑鍐茬獊
 
-// 杈炬爣鐜囪秼鍔垮浘閰嶇疆
-const complianceTrendOptions = computed(() => ({
-	tooltip: {
-		trigger: 'axis',
-		formatter: '{b}<br/>杈炬爣鐜�: {c}%'
-	},
-	grid: {
-		left: '3%',
-		right: '4%',
-		bottom: '3%',
-		containLabel: true
-	},
-	xAxis: {
-		type: 'category',
-		data: mockComplianceData.map(item => item.date),
-		axisLabel: {
-			rotate: 45
-		}
-	},
-	yAxis: {
-		type: 'value',
-		name: '杈炬爣鐜� (%)',
-		min: 70,
-		max: 100
-	},
-	series: [
-		{
-			name: '杈炬爣鐜�',
-			type: 'line',
-			smooth: true,
-			data: mockComplianceData.map(item => item.rate),
-			itemStyle: {
-				color: '#409EFF'
+// 杈炬爣鐜囪秼鍔挎暟鎹� - 鍒濆涓虹┖鏁版嵁
+const complianceTrendData = ref({
+	Xkeys: [],
+	Yvalues: []
+})
+
+// 鍔犲伐寰楃巼鍒嗘瀽鏁版嵁 - 鍒濆涓虹┖鏁版嵁
+const processingYieldData = ref({
+	Xkeys: [],
+	Yvalues: []
+})
+
+// 鎴愭湰缁撴瀯鏁版嵁 - 鍒濆涓虹┖鏁版嵁
+const costStructureData = ref([])
+
+// 鐓ょ鍙戠儹閲忓姣旀暟鎹� - 鍒濆涓虹┖鏁版嵁
+const coalTypeHeatValueData = ref([])
+
+// 鎴愭湰缁撴瀯鍥捐氨鍒濆鍖�
+const initCostStructureChart = () => {
+	if (!costStructureChart.value) return
+	
+	console.log('鍒濆鍖栨垚鏈粨鏋勫浘琛紝鏁版嵁:', costStructureData.value);
+	const chart = echarts.init(costStructureChart.value);
+	const option = {
+		title: {
+			show: costStructureData.value.length === 0, // 娌℃暟鎹墠鏄剧ず
+			textStyle: {
+				color: "grey",
+				fontSize: 20,
 			},
-			lineStyle: {
-				width: 3
-			},
-			areaStyle: {
-				color: {
-					type: 'linear',
-					x: 0,
-					y: 0,
-					x2: 0,
-					y2: 1,
-					colorStops: [{
-						offset: 0,
-						color: 'rgba(64, 158, 255, 0.3)'
-					}, {
-						offset: 1,
-						color: 'rgba(64, 158, 255, 0.05)'
-					}]
+			text: "鏆傛棤鏁版嵁",
+			left: "center",
+			top: "center",
+		},
+		tooltip: {
+			trigger: 'item',
+			// 鏍规嵁API杩斿洖鐨勬暟鎹粨鏋勬牸寮忓寲鏄剧ず
+			formatter: '{b}: {c} ({d}%)'
+		},
+		legend: {
+			orient: 'vertical',
+			left: 'right',
+			top: 'center',
+			textStyle: {
+				fontSize: 12
+			}
+		},
+		series: [
+			{
+				name: '鎴愭湰缁撴瀯',
+				type: 'pie',
+				radius: ['30%', '70%'],
+				center: ['40%', '50%'],
+				data: costStructureData.value.length > 0 
+					? costStructureData.value.map(item => ({
+						name: item.name,
+						value: item.value
+					}))
+					: [],
+				emphasis: {
+					itemStyle: {
+						shadowBlur: 10,
+						shadowOffsetX: 0,
+						shadowColor: 'rgba(0, 0, 0, 0.5)'
+					}
+				},
+				itemStyle: {
+					borderRadius: 4,
+					borderColor: '#fff',
+					borderWidth: 2
+				},
+				label: {
+					show: true,
+					formatter: '{b}\n{d}%'
 				}
 			}
-		}
-	]
-}))
+		]
+	};
+	chart.setOption(option);
+	window.addEventListener('resize', () => {
+		chart.resize();
+	});
+}
 
-// 鐓ょ鍙戠儹閲忓姣斿浘閰嶇疆
+// 杈炬爣鐜囪秼鍔垮浘鍒濆鍖�
+const initComplianceChart = () => {
+	if (!complianceChart.value) return
+	
+	const chart = echarts.init(complianceChart.value);
+	const option = {
+		title: {
+			show: complianceTrendData.value.Yvalues.length === 0, // 娌℃暟鎹墠鏄剧ず
+			textStyle: {
+				color: "grey",
+				fontSize: 20,
+			},
+			text: "鏆傛棤鏁版嵁",
+			left: "center",
+			top: "center",
+		},
+		tooltip: {
+			trigger: 'axis',
+			formatter: '{b}<br/>杈炬爣鐜�: {c}%'
+		},
+		grid: {
+			left: '3%',
+			right: '4%',
+			bottom: '3%',
+			containLabel: true
+		},
+		xAxis: {
+			type: 'category',
+			data: complianceTrendData.value.Xkeys || [],
+			axisLabel: {
+				rotate: 45
+			}
+		},
+		yAxis: {
+			type: 'value',
+			name: '杈炬爣鐜� (%)',
+			min: 0, // 鍥哄畾鏈�灏忓�间负0
+			max: 100, // 鍥哄畾鏈�澶у�间负100
+			// 璁剧疆鍧愭爣杞存爣绛炬牸寮忎负鐧惧垎姣�
+			axisLabel: {
+				formatter: '{value}%'
+			}
+		},
+		series: [
+			{
+				name: '杈炬爣鐜�',
+				type: 'line',
+				smooth: true,
+				data: complianceTrendData.value.Yvalues || [],
+				itemStyle: {
+					color: '#409EFF'
+				},
+				// 娣诲姞鏍囪鐐瑰拰鏍囪绾�
+				markPoint: {
+					data: [
+						{ type: 'max', name: '鏈�澶у��' },
+						{ type: 'min', name: '鏈�灏忓��' }
+					]
+				},
+				markLine: {
+					data: [
+						{ type: 'average', name: '骞冲潎鍊�' }
+					]
+				}
+			}
+		]
+	}
+	chart.setOption(option);
+	window.addEventListener('resize', () => {
+		chart.resize();
+	});
+};
+
+// 鐓ょ鍙戠儹閲忓姣斿浘鍒濆鍖�
+const initCoalTypeHeatValueChart = () => {
+	if (!coalTypeHeatValueChart.value) return
+	
+	console.log('鍒濆鍖栫叅绉嶅彂鐑噺瀵规瘮鍥捐〃锛屾暟鎹�:', coalTypeHeatValueData.value);
+	const chart = echarts.init(coalTypeHeatValueChart.value);
+	const option = {
+		title: {
+			show: coalTypeHeatValueData.value.length === 0, // 娌℃暟鎹墠鏄剧ず
+			textStyle: {
+				color: "grey",
+				fontSize: 20,
+			},
+			text: "鏆傛棤鏁版嵁",
+			left: "center",
+			top: "center",
+		},
+		tooltip: {
+			trigger: 'axis',
+			axisPointer: {
+				type: 'shadow'
+			},
+			formatter: function(params) {
+				return params[0].name + '<br/>鍙戠儹閲�: ' + params[0].value + ' 澶у崱';
+			}
+		},
+		grid: {
+			left: '3%',
+			right: '4%',
+			bottom: '10%',
+			containLabel: true
+		},
+		xAxis: {
+			type: 'category',
+			data: coalTypeHeatValueData.value.map(item => item.name) || [],
+			axisLabel: {
+				fontSize: 11,
+				rotate: 45
+			}
+		},
+		yAxis: {
+			type: 'value',
+			axisLabel: {
+				fontSize: 11
+			}
+		},
+		series: [
+			{
+				name: '鍙戠儹閲�',
+				type: 'bar',
+				data: coalTypeHeatValueData.value.map(item => item.value) || [],
+				itemStyle: {
+					color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+						{ offset: 0, color: '#409EFF' },
+						{ offset: 1, color: '#79bbff' }
+					])
+				},
+				barWidth: '60%',
+				label: {
+					show: true,
+					position: 'top',
+					formatter: function(params) {
+						return params.value + '澶у崱';
+					}
+				}
+			}
+		]
+	};
+	chart.setOption(option);
+	window.addEventListener('resize', () => {
+		chart.resize();
+	});
+};
+
+// 鍔犲伐寰楃巼瓒嬪娍鍥惧垵濮嬪寲
+const initProcessingYieldChart = () => {
+	if (!yieldChart.value) return
+	
+	console.log('鍒濆鍖栧姞宸ュ緱鐜囧浘琛紝鏁版嵁:', processingYieldData.value);
+	const chart = echarts.init(yieldChart.value);
+	const option = {
+		title: {
+			show: processingYieldData.value.Yvalues.length === 0, // 娌℃暟鎹墠鏄剧ず
+			textStyle: {
+				color: "grey",
+				fontSize: 20,
+			},
+			text: "鏆傛棤鏁版嵁",
+			left: "center",
+			top: "center",
+		},
+		tooltip: {
+			trigger: 'axis',
+			formatter: '{b}<br/>寰楃巼: {c}%'
+		},
+		grid: {
+			left: '3%',
+			right: '4%',
+			bottom: '3%',
+			containLabel: true
+		},
+		xAxis: {
+			type: 'category',
+			data: processingYieldData.value.Xkeys || [],
+			axisLabel: {
+				rotate: 45
+			}
+		},
+		yAxis: {
+			type: 'value',
+			name: '寰楃巼 (%)',
+			min: 0,
+			// 鏈�澶у�兼敼涓烘暟鎹腑鐨勬渶澶у�硷紝骞跺鍔�5%鐨勪綑閲�
+			max: processingYieldData.value.Yvalues && processingYieldData.value.Yvalues.length > 0 
+				? Math.ceil(Math.max(...processingYieldData.value.Yvalues) * 1.05) 
+				: 100,
+			// 璁剧疆鍧愭爣杞存爣绛炬牸寮忎负鐧惧垎姣�
+			axisLabel: {
+				formatter: '{value}%'
+			}
+		},
+		series: [
+			{
+				name: '鍔犲伐寰楃巼',
+				type: 'line',
+				smooth: true,
+				data: processingYieldData.value.Yvalues || [],
+				itemStyle: {
+					color: '#52C41A'
+				},
+				lineStyle: {
+					width: 3, // 澧炲姞绾挎潯瀹藉害
+					color: '#52C41A'
+				},
+				showSymbol: true, // 鏄剧ず鏍囪鐐�
+				symbol: 'circle',
+				symbolSize: 8, // 澧炲姞鏍囪鐐瑰ぇ灏�
+				// 娣诲姞鏍囪鐐瑰拰鏍囪绾�
+				markPoint: {
+					data: [
+						{ type: 'max', name: '鏈�澶у��' },
+						{ type: 'min', name: '鏈�灏忓��' }
+					]
+				},
+				markLine: {
+					data: [
+						{ type: 'average', name: '骞冲潎鍊�' }
+					]
+				}
+			}
+		]
+	};
+	chart.setOption(option, true); // 寮哄埗閲嶆柊娓叉煋
+	window.addEventListener('resize', () => {
+		chart.resize();
+	});
+};
+
+// 鐓ょ鍙戠儹閲忓姣斿浘閰嶇疆 - 浣跨敤API鑾峰彇鐨勬暟鎹�
 const calorificValueOptions = computed(() => ({
+	title: {
+		show: coalTypeHeatValueData.value.length === 0, // 娌℃暟鎹墠鏄剧ず
+		textStyle: {
+			color: "grey",
+			fontSize: 20,
+		},
+		text: "鏆傛棤鏁版嵁",
+		left: "center",
+		top: "center",
+	},
 	tooltip: {
 		trigger: 'axis',
 		axisPointer: {
 			type: 'shadow'
 		},
-		formatter: '{b}<br/>鍙戠儹閲�: {c} 澶у崱'
+		formatter: '{b}<br/>鍙戠儹閲�: {c} 澶у崱<br/>鍗犳瘮: {d}%'
 	},
 	grid: {
 		left: '3%',
@@ -330,7 +556,10 @@
 	},
 	xAxis: {
 		type: 'category',
-		data: mockCalorificData.map(item => item.name)
+		data: coalTypeHeatValueData.value.map(item => item.name) || [],
+		axisLabel: {
+			rotate: 45
+		}
 	},
 	yAxis: {
 		type: 'value',
@@ -340,7 +569,10 @@
 		{
 			name: '鍙戠儹閲�',
 			type: 'bar',
-			data: mockCalorificData.map(item => item.value),
+			data: coalTypeHeatValueData.value.map(item => ({
+				value: item.value,
+				percent: item.percent
+			})) || [],
 			itemStyle: {
 				color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
 					{ offset: 0, color: '#FF6B81' },
@@ -350,17 +582,34 @@
 			label: {
 				show: true,
 				position: 'top',
-				formatter: '{c}澶у崱'
+				formatter: function(params) {
+					// 浣跨敤鍘熷鏁版嵁涓殑percent鍊�
+					const item = coalTypeHeatValueData.value.find(item => item.name === params.name);
+					return params.value + '澶у崱\n(' + (item && item.percent ? item.percent.toFixed(2) : '0') + '%)';
+				}
 			}
 		}
 	]
 }))
 
-// 閰嶆柟浣跨敤棰戞鍥鹃厤缃�
-const recipeFrequencyOptions = computed(() => ({
+// 鍔犲伐寰楃巼鍒嗘瀽鐩稿叧鐨勯厤缃凡绉婚櫎锛岀幇鍦ㄤ娇鐢ㄦ墜鍔ㄥ垵濮嬪寲鏂瑰紡
+
+// 鎴愭湰缁撴瀯鍥捐氨閰嶇疆 - 浣跨敤API鑾峰彇鐨勬暟鎹�
+const costStructureOptions = computed(() => ({
+	title: {
+		show: costStructureData.value.length === 0, // 娌℃暟鎹墠鏄剧ず
+		textStyle: {
+			color: "grey",
+			fontSize: 20,
+		},
+		text: "鏆傛棤鏁版嵁",
+		left: "center",
+		top: "center",
+	},
 	tooltip: {
 		trigger: 'item',
-		formatter: '{b}: {c}娆� ({d}%)'
+		// 鏍规嵁API杩斿洖鐨勬暟鎹粨鏋勬牸寮忓寲鏄剧ず
+		formatter: '{b}: {c} ({d}%)'
 	},
 	legend: {
 		orient: 'vertical',
@@ -371,95 +620,17 @@
 	},
 	series: [
 		{
-			name: '閰嶆柟浣跨敤棰戞',
-			type: 'pie',
-			radius: '60%',
-			center: ['60%', '50%'],
-			data: mockRecipeData,
-			emphasis: {
-				itemStyle: {
-					shadowBlur: 10,
-					shadowOffsetX: 0,
-					shadowColor: 'rgba(0, 0, 0, 0.5)'
-				}
-			},
-			itemStyle: {
-				borderRadius: 8,
-				borderColor: '#fff',
-				borderWidth: 2
-			},
-			label: {
-				show: true,
-				formatter: '{b}\n{c}娆�'
-			}
-		}
-	]
-}))
-
-// 鍔犲伐寰楃巼鍒嗘瀽鍥鹃厤缃�
-const processingYieldOptions = computed(() => ({
-	tooltip: {
-		trigger: 'axis',
-		axisPointer: {
-			type: 'shadow'
-		}
-	},
-	legend: {
-		data: ['鍑烘礂鐜�', '鍔犲伐鑳芥晥']
-	},
-	grid: {
-		left: '3%',
-		right: '4%',
-		bottom: '3%',
-		containLabel: true
-	},
-	xAxis: {
-		type: 'category',
-		data: mockYieldData.map(item => item.name)
-	},
-	yAxis: {
-		type: 'value',
-		name: '鐧惧垎姣� (%)',
-		min: 60,
-		max: 100
-	},
-	series: [
-		{
-			name: '鍑烘礂鐜�',
-			type: 'bar',
-			data: mockYieldData.map(item => item.yield),
-			itemStyle: {
-				color: '#52C41A'
-			}
-		},
-		{
-			name: '鍔犲伐鑳芥晥',
-			type: 'bar',
-			data: mockYieldData.map(item => item.efficiency),
-			itemStyle: {
-				color: '#1890FF'
-			}
-		}
-	]
-}))
-
-// 鎴愭湰缁撴瀯鍥捐氨閰嶇疆
-const costStructureOptions = computed(() => ({
-	tooltip: {
-		trigger: 'item',
-		formatter: '{b}: {c}%'
-	},
-	legend: {
-		orient: 'vertical',
-		left: 'left'
-	},
-	series: [
-		{
 			name: '鎴愭湰缁撴瀯',
 			type: 'pie',
 			radius: '60%',
 			center: ['60%', '50%'],
-			data: mockCostData,
+			data: costStructureData.value.length > 0 
+				? costStructureData.value.map(item => ({
+					name: item.name,
+					value: item.value,
+					percent: item.percent
+				}))
+				: [],
 			emphasis: {
 				itemStyle: {
 					shadowBlur: 10,
@@ -467,11 +638,15 @@
 					shadowColor: 'rgba(0, 0, 0, 0.5)'
 				}
 			},
-			roseType: 'radius',
 			itemStyle: {
-				borderRadius: 8,
+				borderRadius: 4,
 				borderColor: '#fff',
 				borderWidth: 2
+			},
+			// 璁剧疆鏍囩鏍煎紡鍖栵紝鏄剧ず鍗犳瘮
+			label: {
+				show: true,
+				formatter: '{b}\n{d}%'
 			}
 		}
 	]
@@ -483,30 +658,104 @@
 const handleSearch = async () => {
 	try {
 		loading.value = true
-		// 鍦ㄥ疄闄呭簲鐢ㄤ腑锛岃繖閲屼細璋冪敤API鑾峰彇鐪熷疄鏁版嵁
-		console.log('鎼滅储鍙傛暟:', searchParams.value)
+		// 鏋勫缓璇锋眰鍙傛暟
+		const params = {
+			entryDateStart: searchParams.value.dateRange && searchParams.value.dateRange[0] ?
+				searchParams.value.dateRange[0].toISOString().split('T')[0] : '',
+			entryDateEnd: searchParams.value.dateRange && searchParams.value.dateRange[1] ?
+				searchParams.value.dateRange[1].toISOString().split('T')[0] : ''
+		}
+		console.log('鎼滅储鍙傛暟:', params)
 		
-		// 鑾峰彇閰嶇叅鏁版嵁
-		// const blendingRes = await getCoalBlendingList({
-		//   startTime: searchParams.value.dateRange[0] ? parseTime(searchParams.value.dateRange[0]) : '',
-		//   endTime: searchParams.value.dateRange[1] ? parseTime(searchParams.value.dateRange[1]) : ''
-		// })
+		// 璋冪敤API鑾峰彇鎶ヨ〃缁熻鏁版嵁
+		const res = await getReportStatistics(params)
 		
-		// 妯℃嫙API璇锋眰寤惰繜
-		await new Promise(resolve => setTimeout(resolve, 800))
+		if (res.code === 200 && res.data) {
+			// 鏇存柊缁熻鏁版嵁
+			unitHeatValue.value = res.data.unitHeatValue || 0
+			wholeStandardRate.value = res.data.wholeStandardRate || 0
+			averageFuel.value = res.data.averageFuel || 0
+			frequency.value = res.data.frequency || 0
+			totalBatch.value = res.data.totalBatch || 0
+		} else {
+			throw new Error(res.msg || '鑾峰彇鏁版嵁澶辫触')
+		}
 		
-		// 妯℃嫙鏁版嵁鏇存柊锛堝疄闄呭簲鐢ㄤ腑搴旀牴鎹瓵PI杩斿洖缁撴灉鏇存柊锛�
-		unitHeatCoalConsumption.value = 31.8 + Math.random() * 5
-		overallComplianceRate.value = 80 + Math.random() * 15
-		averageCalorificValue.value = 5000 + Math.random() * 500
-		totalBatches.value = 40 + Math.floor(Math.random() * 20)
+		// 璋冪敤API鑾峰彇杈炬爣鐜囪秼鍔挎暟鎹�
+		const trendRes = await getReportTrend(params)
 		
-		// 闅忔満鏇存柊閮ㄥ垎鍥捐〃鏁版嵁
-		mockComplianceData.forEach(item => {
-			item.rate = 80 + Math.random() * 15
+		if (trendRes.code === 200 && trendRes.data && trendRes.data.length > 0) {
+			// 棰勫鐞嗚揪鏍囩巼瓒嬪娍鏁版嵁锛岀‘淇漹alue瀛楁鏄湁鏁堢殑鏁板瓧
+			const Xkeys = []
+			const Yvalues = []
+			trendRes.data.forEach(item => {
+				Xkeys.push(item.name || '')
+				Yvalues.push(typeof item.value === 'number' ? item.value : parseFloat(item.value) || 0)
+			})
+			// 鏇存柊杈炬爣鐜囪秼鍔挎暟鎹�
+			complianceTrendData.value = {
+				Xkeys,
+				Yvalues
+			}
+		} else {
+			console.warn('鑾峰彇杈炬爣鐜囪秼鍔挎暟鎹け璐�:', trendRes.msg)
+			// 璁剧疆绌烘暟鎹紝鏄剧ず鏆傛棤鏁版嵁鎻愮ず
+			complianceTrendData.value = { Xkeys: [], Yvalues: [] }
+		}
+		
+		// 璋冪敤API鑾峰彇鍔犲伐寰楃巼鍒嗘瀽鏁版嵁
+		const yieldRes = await processingRateAnalysis(params)
+		
+		if (yieldRes.code === 200 && yieldRes.data && yieldRes.data.length > 0) {
+			// 棰勫鐞嗗姞宸ュ緱鐜囨暟鎹�
+			const Xkeys = []
+			const Yvalues = []
+			yieldRes.data.forEach(item => {
+				Xkeys.push(item.name || '')
+				Yvalues.push(typeof item.value === 'number' ? item.value : parseFloat(item.value) || 0)
+			})
+			// 鏇存柊鍔犲伐寰楃巼鏁版嵁
+			processingYieldData.value = {
+				Xkeys,
+				Yvalues
+			}
+		} else {
+			console.warn('鑾峰彇鍔犲伐寰楃巼鏁版嵁澶辫触:', yieldRes.msg)
+			// 璁剧疆绌烘暟鎹紝鏄剧ず鏆傛棤鏁版嵁鎻愮ず
+			processingYieldData.value = { Xkeys: [], Yvalues: [] }
+		}
+		
+		// 璋冪敤API鑾峰彇鎴愭湰缁撴瀯鏁版嵁
+		const costRes = await costStructure(params)
+		
+		if (costRes.code === 200 && costRes.data && costRes.data.length > 0) {
+			// 鏇存柊鎴愭湰缁撴瀯鏁版嵁
+			costStructureData.value = costRes.data
+		} else {
+			console.warn('鑾峰彇鎴愭湰缁撴瀯鏁版嵁澶辫触:', costRes.msg)
+			// 璁剧疆绌烘暟鎹紝鏄剧ず鏆傛棤鏁版嵁鎻愮ず
+			costStructureData.value = []
+		}
+		
+		// 璋冪敤API鑾峰彇鐓ょ鍙戠儹閲忓姣旀暟鎹�
+		const coalValueRes = await coalTypeHeatValueComparison(params)
+		
+		if (coalValueRes.code === 200 && coalValueRes.data && coalValueRes.data.length > 0) {
+			// 鏇存柊鐓ょ鍙戠儹閲忓姣旀暟鎹�
+			coalTypeHeatValueData.value = coalValueRes.data
+		} else {
+			console.warn('鑾峰彇鐓ょ鍙戠儹閲忓姣旀暟鎹け璐�:', coalValueRes.msg)
+			// 璁剧疆绌烘暟鎹紝鏄剧ず鏆傛棤鏁版嵁鎻愮ず
+			coalTypeHeatValueData.value = []
+		}
+		
+		// 鏁版嵁鏇存柊鍚庨噸鏂板垵濮嬪寲鍥捐〃
+		nextTick(() => {
+			initComplianceChart()
+			initProcessingYieldChart()
+			initCostStructureChart()
+			initCoalTypeHeatValueChart()
 		})
-		
-		ElMessage.success('鏌ヨ鎴愬姛')
 	} catch (error) {
 		console.error('鏌ヨ澶辫触:', error)
 		ElMessage.error('鏌ヨ澶辫触锛岃绋嶅悗閲嶈瘯')
@@ -554,6 +803,14 @@
 	
 	// 鍒濆鍔犺浇鏁版嵁
 	handleSearch()
+	
+	// 鍒濆鍖栧浘琛�
+	nextTick(() => {
+		initComplianceChart()
+		initProcessingYieldChart()
+		initCostStructureChart()
+		initCoalTypeHeatValueChart()
+	})
 })
 </script>
 

--
Gitblit v1.9.3