From 237ea80f25f97d0a63969cc844a86a05c127a582 Mon Sep 17 00:00:00 2001 From: huangjinysf Date: Wed, 24 Dec 2025 15:51:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E9=94=80=E9=87=8F?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=9B=B8=E5=85=B3=E7=8A=B6=E6=80=81=E5=8F=98?= =?UTF-8?q?=E9=87=8F=EF=BC=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit salesDataLoading : 销量数据加载状态 salesData : 存储销量数据 hasSalesData : 是否有销量数据 添加了销量图表引用和实例: salesChartRef : 销量图表的DOM引用 salesChart : 销量图表的echarts实例 创建了获取销量数据的函数: fetchSalesData : 从API获取销量数据 使用 /api/records 接口,传递型号、规格和时间范围参数 更新了图表选项卡: 添加了"销量变化"选项卡 在选项卡切换时处理销量图表的初始化和调整 更新了图表初始化和更新逻辑: 在 initCharts 函数中添加销量图表的初始化 在 handleClose 函数中添加销量图表的销毁 在 updateCharts 函数中添加销量图表的更新逻辑 修改了数据获取流程: 在 showAxleDetails 和 onTimeRangeChange 中调用 fetchSalesData 更新了加载状态的判断条件 销量图表特点: 使用柱状图显示箱数,使用折线图显示重量 双Y轴设计,左侧显示箱数,右侧显示重量 添加了图例区分两种数据类型 --- src/views/plan/EquipmentStatus.vue | 223 ++++++++++++++++++++++++++--- 1 file changed, 203 insertions(+), 20 deletions(-) diff --git a/src/views/plan/EquipmentStatus.vue b/src/views/plan/EquipmentStatus.vue index 28f4f45..27d04a5 100644 --- a/src/views/plan/EquipmentStatus.vue +++ b/src/views/plan/EquipmentStatus.vue @@ -163,10 +163,10 @@ -
+
-
- 暂无历史数据 +
+ 暂无数据
@@ -181,6 +181,9 @@
+ +
+
@@ -497,6 +500,11 @@ const selectedTimeRange = ref('近1月'); // 默认时间范围 const activeChartTab = ref('totalNumber'); const hasHistoryData = ref(false); +// 销量数据相关状态 +const salesDataLoading = ref(false); +const salesData = ref([]); +const hasSalesData = ref(false); + // 排产信息相关状态 const productionScheduleData = ref(null); const productionScheduleLoading = ref(false); @@ -508,11 +516,13 @@ const editableTotalQuantity = ref(0); const totalNumberChartRef = ref(null); const totalNetWeightChartRef = ref(null); const totalGrossWeightChartRef = ref(null); +const salesChartRef = ref(null); // 图表实例 let totalNumberChart = null; let totalNetWeightChart = null; let totalGrossWeightChart = null; +let salesChart = null; // 显示轴详情对话框 const showAxleDetails = (record, equipmentCode) => { @@ -527,6 +537,7 @@ const showAxleDetails = (record, equipmentCode) => { if (record.update_time && record.model && record.specification && record.wire_disc) { fetchHistoryData(record.model, record.specification, record.wire_disc); fetchProductionScheduleData(record.model, record.specification, record.wire_disc, equipmentCode, record.axle_number); + fetchSalesData(record.model, record.specification); } else { hasHistoryData.value = false; } @@ -553,6 +564,10 @@ const handleClose = () => { totalGrossWeightChart.dispose(); totalGrossWeightChart = null; } + if (salesChart) { + salesChart.dispose(); + salesChart = null; + } }; // 监听对话框打开状态 @@ -569,6 +584,14 @@ watch(dialogVisible, (newValue) => { updateCharts(); }, 300); } + + // 如果已有销量数据,则更新图表 + if (hasSalesData.value && salesData.value.length > 0) { + // 再次延迟以确保图表容器完全初始化 + setTimeout(() => { + updateCharts(); + }, 300); + } }, 300); } }); @@ -582,6 +605,10 @@ const onTimeRangeChange = () => { selectedAxle.value.specification, selectedAxle.value.wire_disc ); + fetchSalesData( + selectedAxle.value.model, + selectedAxle.value.specification + ); } }; @@ -598,6 +625,9 @@ const handleTabClick = (tab) => { } else if (tab.props.name === 'totalGrossWeight' && !totalGrossWeightChart && totalGrossWeightChartRef.value) { totalGrossWeightChart = echarts.init(totalGrossWeightChartRef.value); updateCharts(); + } else if (tab.props.name === 'salesData' && !salesChart && salesChartRef.value) { + salesChart = echarts.init(salesChartRef.value); + updateCharts(); } // 强制图表重新渲染 @@ -607,6 +637,8 @@ const handleTabClick = (tab) => { totalNetWeightChart.resize(); } else if (tab.props.name === 'totalGrossWeight' && totalGrossWeightChart) { totalGrossWeightChart.resize(); + } else if (tab.props.name === 'salesData' && salesChart) { + salesChart.resize(); } }, 100); }; @@ -654,6 +686,49 @@ const fetchHistoryData = (model, specification, wireDisc) => { }); }; +// 获取销量数据 +const fetchSalesData = (model, specification) => { + salesDataLoading.value = true; + + // 获取日期范围 + const dateRange = getDateRangeByTimeRange(selectedTimeRange.value); + + // 构建API URL + let apiUrl = `${API_CONFIG.BASE_URL}/api/sale/records?model=${model}&specification=${specification}&start_date=${dateRange.start_date}&end_date=${dateRange.end_date}`; + + fetch(apiUrl) + .then(response => response.json()) + .then(data => { + if (data.code === 200 && data.data) { + salesData.value = data.data; + hasSalesData.value = salesData.value.length > 0; + + if (hasSalesData.value) { + // 使用setTimeout确保DOM完全渲染后再初始化图表 + setTimeout(() => { + initCharts(); + + // 再次延迟以确保图表容器完全初始化 + setTimeout(() => { + updateCharts(); + }, 300); + }, 300); + } + } else { + salesData.value = []; + hasSalesData.value = false; + } + }) + .catch(error => { + console.error('销量数据API调用失败:', error); + salesData.value = []; + hasSalesData.value = false; + }) + .finally(() => { + salesDataLoading.value = false; + }); +}; + // 获取排产信息数据 const fetchProductionScheduleData = (model, specification, wireDisc, equipmentCode, axleNumber) => { productionScheduleLoading.value = true; @@ -777,6 +852,10 @@ const initCharts = () => { totalGrossWeightChart.dispose(); totalGrossWeightChart = null; } + if (salesChart) { + salesChart.dispose(); + salesChart = null; + } // 初始化新图表实例 if (totalNumberChartRef.value) { @@ -790,24 +869,14 @@ const initCharts = () => { if (totalGrossWeightChartRef.value) { totalGrossWeightChart = echarts.init(totalGrossWeightChartRef.value); } + + if (salesChartRef.value) { + salesChart = echarts.init(salesChartRef.value); + } }; // 更新图表数据 const updateCharts = () => { - if (!historyData.value || historyData.value.length === 0) { - return; - } - - // 准备数据 - const timeData = historyData.value.map(item => { - const date = new Date(item.create_time); - return `${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`; - }); - - const totalNumberData = historyData.value.map(item => item.total_number); - const totalNetWeightData = historyData.value.map(item => item.total_net_weight); - const totalGrossWeightData = historyData.value.map(item => item.total_gross_weight); - // 确保图表容器已经渲染完成 nextTick(() => { // 初始化或重新初始化图表实例 @@ -820,9 +889,19 @@ const updateCharts = () => { if (!totalGrossWeightChart && totalGrossWeightChartRef.value) { totalGrossWeightChart = echarts.init(totalGrossWeightChartRef.value); } + if (!salesChart && salesChartRef.value) { + salesChart = echarts.init(salesChartRef.value); + } // 更新总箱数图表 - if (totalNumberChart) { + if (totalNumberChart && historyData.value && historyData.value.length > 0) { + const timeData = historyData.value.map(item => { + const date = new Date(item.create_time); + return `${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`; + }); + + const totalNumberData = historyData.value.map(item => item.total_number); + const totalNumberOption = { title: { text: '总箱数变化趋势', @@ -867,7 +946,14 @@ const updateCharts = () => { } // 更新总净重图表 - if (totalNetWeightChart) { + if (totalNetWeightChart && historyData.value && historyData.value.length > 0) { + const timeData = historyData.value.map(item => { + const date = new Date(item.create_time); + return `${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`; + }); + + const totalNetWeightData = historyData.value.map(item => item.total_net_weight); + const totalNetWeightOption = { title: { text: '总净重变化趋势', @@ -917,7 +1003,14 @@ const updateCharts = () => { } // 更新总毛重图表 - if (totalGrossWeightChart) { + if (totalGrossWeightChart && historyData.value && historyData.value.length > 0) { + const timeData = historyData.value.map(item => { + const date = new Date(item.create_time); + return `${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`; + }); + + const totalGrossWeightData = historyData.value.map(item => item.total_gross_weight); + const totalGrossWeightOption = { title: { text: '总毛重变化趋势', @@ -965,6 +1058,96 @@ const updateCharts = () => { }; totalGrossWeightChart.setOption(totalGrossWeightOption, true); // true表示不合并选项 } + + // 更新销量图表 + if (salesChart && salesData.value && salesData.value.length > 0) { + // 准备销量数据 + const salesTimeData = salesData.value.map(item => { + const date = new Date(item.date); + return `${date.getMonth() + 1}/${date.getDate()}`; + }); + + const boxCountData = salesData.value.map(item => item.box_count); + const weightData = salesData.value.map(item => item.weight); + + const salesOption = { + title: { + text: '销量变化趋势', + left: 'center', + textStyle: { + fontSize: 16 + } + }, + tooltip: { + trigger: 'axis', + formatter: function(params) { + let result = params[0].name + '
'; + params.forEach(param => { + if (param.seriesName === '箱数') { + result += `${param.seriesName}: ${param.value} 箱
`; + } else if (param.seriesName === '重量') { + result += `${param.seriesName}: ${param.value} kg
`; + } + }); + return result; + } + }, + legend: { + data: ['箱数', '重量'], + top: 30 + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + top: 60, + containLabel: true + }, + xAxis: { + type: 'category', + data: salesTimeData, + axisLabel: { + rotate: 45 + } + }, + yAxis: [ + { + type: 'value', + name: '箱数', + position: 'left' + }, + { + type: 'value', + name: '重量(kg)', + position: 'right' + } + ], + series: [ + { + name: '箱数', + type: 'bar', + data: boxCountData, + itemStyle: { + color: '#409EFF' + } + }, + { + name: '重量', + type: 'line', + yAxisIndex: 1, + data: weightData, + smooth: true, + itemStyle: { + color: '#67C23A' + }, + areaStyle: { + opacity: 0.3 + } + } + ] + }; + salesChart.setOption(salesOption, true); // true表示不合并选项 + } }); };