添加轴详情历史数据图表功能,支持近1天/3天/1周时间范围选择

master
huangjinysf 3 months ago
parent 0073d3581d
commit ce0c6f0588

@ -1,8 +1,8 @@
// API配置文件 // API配置文件
export const API_CONFIG = { export const API_CONFIG = {
// API服务器基础地址 // API服务器基础地址
// BASE_URL: 'http://192.168.110.38:8100', BASE_URL: 'http://192.168.110.38:8100',
BASE_URL: 'http://localhost:8100', // BASE_URL: 'http://localhost:8100',
// API端点 // API端点
ENDPOINTS: { ENDPOINTS: {

@ -36,7 +36,7 @@ export function formatDateTime(date) {
} }
/** /**
* 根据时间范围文字"近1"计算开始和结束日期 * 根据时间范围文字"近1"计算开始和结束日期
* @param {string} timeRange - 时间范围文字 * @param {string} timeRange - 时间范围文字
* @returns {Object} 包含开始和结束日期的对象 * @returns {Object} 包含开始和结束日期的对象
*/ */
@ -44,7 +44,15 @@ export function getDateRangeByTimeRange(timeRange) {
const endDate = new Date(); const endDate = new Date();
const startDate = new Date(); const startDate = new Date();
if (timeRange === '近1年') { if (timeRange === '近1天') {
startDate.setDate(endDate.getDate() - 1);
} else if (timeRange === '近3天') {
startDate.setDate(endDate.getDate() - 3);
} else if (timeRange === '近1周') {
startDate.setDate(endDate.getDate() - 7);
} else if (timeRange === '近1月') {
startDate.setMonth(endDate.getMonth() - 1);
} else if (timeRange === '近1年') {
startDate.setFullYear(endDate.getFullYear() - 1); startDate.setFullYear(endDate.getFullYear() - 1);
} else if (timeRange === '近2年') { } else if (timeRange === '近2年') {
startDate.setFullYear(endDate.getFullYear() - 2); startDate.setFullYear(endDate.getFullYear() - 2);

@ -56,9 +56,12 @@
<el-dialog <el-dialog
v-model="dialogVisible" v-model="dialogVisible"
title="轴详细信息" title="轴详细信息"
width="50%" width="80%"
:before-close="handleClose"> :before-close="handleClose">
<div v-if="selectedAxle" class="axle-details"> <div v-if="selectedAxle" class="axle-details-container">
<!-- 左侧轴基本信息 -->
<div class="axle-info-panel">
<div class="detail-title">基本信息</div>
<div class="detail-row"> <div class="detail-row">
<span class="detail-label">设备编号:</span> <span class="detail-label">设备编号:</span>
<span class="detail-value">{{ selectedEquipmentCode }}</span> <span class="detail-value">{{ selectedEquipmentCode }}</span>
@ -109,6 +112,40 @@
<span class="detail-value">{{ selectedAxle.update_time }}</span> <span class="detail-value">{{ selectedAxle.update_time }}</span>
</div> </div>
</div> </div>
<!-- 右侧历史数据图表 -->
<div class="history-chart-panel">
<div class="chart-controls">
<div class="detail-title">历史数据分析</div>
<el-select v-model="selectedTimeRange" @change="onTimeRangeChange" style="width: 120px">
<el-option label="近1天" value="近1天" />
<el-option label="近3天" value="近3天" />
<el-option label="近1周" value="近1周" />
</el-select>
</div>
<div v-if="historyDataLoading" v-loading="true" class="chart-loading"></div>
<div v-else-if="!hasHistoryData" class="no-history-data">
暂无历史数据
</div>
<div v-else class="charts-container">
<!-- 图表选项卡 -->
<el-tabs v-model="activeChartTab" type="border-card" @tab-click="handleTabClick">
<el-tab-pane label="总箱数变化" name="totalNumber">
<div ref="totalNumberChartRef" class="chart"></div>
</el-tab-pane>
<el-tab-pane label="总净重变化" name="totalNetWeight">
<div ref="totalNetWeightChartRef" class="chart"></div>
</el-tab-pane>
<el-tab-pane label="总毛重变化" name="totalGrossWeight">
<div ref="totalGrossWeightChartRef" class="chart"></div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="dialogVisible = false">关闭</el-button> <el-button @click="dialogVisible = false">关闭</el-button>
@ -119,8 +156,11 @@
</template> </template>
<script setup> <script setup>
import { defineProps, computed, ref } from 'vue'; import { defineProps, computed, ref, onMounted, nextTick, watch } from 'vue';
import { ElDialog, ElButton } from 'element-plus'; import { ElDialog, ElButton, ElSelect, ElOption, ElTabs, ElTabPane } from 'element-plus';
import { getDateRangeByTimeRange } from '@/utils/dateFormat';
import * as echarts from 'echarts';
import { API_CONFIG } from "@/config/api";
const props = defineProps({ const props = defineProps({
equipmentData: { equipmentData: {
@ -365,16 +405,436 @@ const dialogVisible = ref(false);
const selectedAxle = ref(null); const selectedAxle = ref(null);
const selectedEquipmentCode = ref(''); const selectedEquipmentCode = ref('');
//
const historyDataLoading = ref(false);
const historyData = ref([]);
const selectedTimeRange = ref('近1天');
const activeChartTab = ref('totalNumber');
const hasHistoryData = ref(false);
//
const totalNumberChartRef = ref(null);
const totalNetWeightChartRef = ref(null);
const totalGrossWeightChartRef = ref(null);
//
let totalNumberChart = null;
let totalNetWeightChart = null;
let totalGrossWeightChart = null;
// //
const showAxleDetails = (record, equipmentCode) => { const showAxleDetails = (record, equipmentCode) => {
console.log('显示轴详情对话框, record:', record);
selectedAxle.value = { ...record }; selectedAxle.value = { ...record };
selectedEquipmentCode.value = equipmentCode; selectedEquipmentCode.value = equipmentCode;
dialogVisible.value = true; dialogVisible.value = true;
// 线
if (record.update_time && record.specification && record.wire_disc) {
console.log('获取历史数据, model:', record.model, 'specification:', record.specification, 'wire_disc:', record.wire_disc);
fetchHistoryData(record.model, record.specification, record.wire_disc);
} else {
console.log('不获取历史数据, update_time:', record.update_time, 'specification:', record.specification, 'wire_disc:', record.wire_disc);
hasHistoryData.value = false;
}
//
nextTick(() => {
console.log('初始化图表');
initCharts();
});
}; };
// //
const handleClose = () => { const handleClose = () => {
console.log('关闭对话框');
dialogVisible.value = false; dialogVisible.value = false;
//
if (totalNumberChart) {
totalNumberChart.dispose();
totalNumberChart = null;
}
if (totalNetWeightChart) {
totalNetWeightChart.dispose();
totalNetWeightChart = null;
}
if (totalGrossWeightChart) {
totalGrossWeightChart.dispose();
totalGrossWeightChart = null;
}
};
//
watch(dialogVisible, (newValue) => {
console.log('对话框状态变化:', newValue);
if (newValue) {
//
setTimeout(() => {
console.log('对话框打开,延迟初始化图表');
initCharts();
//
if (hasHistoryData.value && historyData.value.length > 0) {
//
setTimeout(() => {
console.log('对话框打开,延迟更新图表');
updateCharts();
}, 300);
}
}, 300);
}
});
//
const onTimeRangeChange = () => {
console.log('时间范围改变, 新范围:', selectedTimeRange.value);
if (selectedAxle.value && selectedAxle.value.update_time &&
selectedAxle.value.specification && selectedAxle.value.wire_disc) {
fetchHistoryData(
selectedAxle.value.model,
selectedAxle.value.specification,
selectedAxle.value.wire_disc
);
}
};
//
const handleTabClick = (tab) => {
console.log('选项卡切换, 当前选项卡:', tab.props.name);
// 使setTimeoutDOM
setTimeout(() => {
if (tab.props.name === 'totalNumber' && !totalNumberChart && totalNumberChartRef.value) {
console.log('选项卡切换时初始化总箱数图表');
totalNumberChart = echarts.init(totalNumberChartRef.value);
updateCharts();
} else if (tab.props.name === 'totalNetWeight' && !totalNetWeightChart && totalNetWeightChartRef.value) {
console.log('选项卡切换时初始化总净重图表');
totalNetWeightChart = echarts.init(totalNetWeightChartRef.value);
updateCharts();
} else if (tab.props.name === 'totalGrossWeight' && !totalGrossWeightChart && totalGrossWeightChartRef.value) {
console.log('选项卡切换时初始化总毛重图表');
totalGrossWeightChart = echarts.init(totalGrossWeightChartRef.value);
updateCharts();
}
//
if (tab.props.name === 'totalNumber' && totalNumberChart) {
console.log('重新渲染总箱数图表');
totalNumberChart.resize();
} else if (tab.props.name === 'totalNetWeight' && totalNetWeightChart) {
console.log('重新渲染总净重图表');
totalNetWeightChart.resize();
} else if (tab.props.name === 'totalGrossWeight' && totalGrossWeightChart) {
console.log('重新渲染总毛重图表');
totalGrossWeightChart.resize();
}
}, 100);
};
//
const fetchHistoryData = (model, specification, wireDisc) => {
console.log('开始获取历史数据, model:', model, 'specification:', specification, 'wireDisc:', wireDisc);
historyDataLoading.value = true;
//
const dateRange = getDateRangeByTimeRange(selectedTimeRange.value);
console.log('日期范围:', dateRange);
// API URL
let apiUrl = `${API_CONFIG.BASE_URL}/api/plan/wms/history?model=${model}&specification=${specification}&wire_disc=${wireDisc}&start_date=${dateRange.start_date}&end_date=${dateRange.end_date}`;
console.log('API URL:', apiUrl);
fetch(apiUrl)
.then(response => {
console.log('API响应状态:', response.status);
return response.json();
})
.then(data => {
console.log('API响应数据:', data);
if (data.code === 200 && data.data && data.data.records) {
historyData.value = data.data.records;
hasHistoryData.value = historyData.value.length > 0;
console.log('历史数据获取成功, 记录数:', historyData.value.length);
if (hasHistoryData.value) {
console.log('准备更新图表');
// 使setTimeoutDOM
setTimeout(() => {
console.log('延迟初始化图表');
initCharts();
//
setTimeout(() => {
console.log('延迟更新图表');
updateCharts();
}, 300);
}, 300);
}
} else {
console.log('历史数据格式不正确或无记录');
historyData.value = [];
hasHistoryData.value = false;
}
})
.catch(error => {
console.error('历史数据API调用失败:', error);
historyData.value = [];
hasHistoryData.value = false;
})
.finally(() => {
historyDataLoading.value = false;
});
};
//
const initCharts = () => {
console.log('初始化图表开始');
console.log('totalNumberChartRef.value:', totalNumberChartRef.value);
console.log('totalNetWeightChartRef.value:', totalNetWeightChartRef.value);
console.log('totalGrossWeightChartRef.value:', totalGrossWeightChartRef.value);
//
if (totalNumberChart) {
totalNumberChart.dispose();
totalNumberChart = null;
}
if (totalNetWeightChart) {
totalNetWeightChart.dispose();
totalNetWeightChart = null;
}
if (totalGrossWeightChart) {
totalGrossWeightChart.dispose();
totalGrossWeightChart = null;
}
//
if (totalNumberChartRef.value) {
console.log('初始化总箱数图表');
totalNumberChart = echarts.init(totalNumberChartRef.value);
} else {
console.error('totalNumberChartRef.value不存在');
}
if (totalNetWeightChartRef.value) {
console.log('初始化总净重图表');
totalNetWeightChart = echarts.init(totalNetWeightChartRef.value);
} else {
console.error('totalNetWeightChartRef.value不存在');
}
if (totalGrossWeightChartRef.value) {
console.log('初始化总毛重图表');
totalGrossWeightChart = echarts.init(totalGrossWeightChartRef.value);
} else {
console.error('totalGrossWeightChartRef.value不存在');
}
console.log('初始化图表结束, totalNumberChart:', totalNumberChart, 'totalNetWeightChart:', totalNetWeightChart, 'totalGrossWeightChart:', totalGrossWeightChart);
};
//
const updateCharts = () => {
console.log('更新图表开始, historyData.value:', historyData.value);
if (!historyData.value || historyData.value.length === 0) {
console.log('无历史数据,不更新图表');
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);
console.log('准备好的数据:', {
timeData,
totalNumberData,
totalNetWeightData,
totalGrossWeightData
});
//
nextTick(() => {
console.log('在nextTick中更新图表');
//
if (!totalNumberChart && totalNumberChartRef.value) {
console.log('重新初始化总箱数图表');
totalNumberChart = echarts.init(totalNumberChartRef.value);
}
if (!totalNetWeightChart && totalNetWeightChartRef.value) {
console.log('重新初始化总净重图表');
totalNetWeightChart = echarts.init(totalNetWeightChartRef.value);
}
if (!totalGrossWeightChart && totalGrossWeightChartRef.value) {
console.log('重新初始化总毛重图表');
totalGrossWeightChart = echarts.init(totalGrossWeightChartRef.value);
}
//
if (totalNumberChart) {
console.log('更新总箱数图表');
const totalNumberOption = {
title: {
text: '总箱数变化趋势',
left: 'center',
textStyle: {
fontSize: 16
}
},
tooltip: {
trigger: 'axis'
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: timeData,
axisLabel: {
rotate: 45
}
},
yAxis: {
type: 'value',
name: '箱数'
},
series: [{
data: totalNumberData,
type: 'line',
smooth: true,
itemStyle: {
color: '#409EFF'
},
areaStyle: {
opacity: 0.3
}
}]
};
console.log('设置总箱数图表选项');
totalNumberChart.setOption(totalNumberOption, true); // true
} else {
console.error('总箱数图表实例不存在');
}
//
if (totalNetWeightChart) {
console.log('更新总净重图表');
const totalNetWeightOption = {
title: {
text: '总净重变化趋势',
left: 'center',
textStyle: {
fontSize: 16
}
},
tooltip: {
trigger: 'axis',
formatter: function(params) {
return params[0].name + '<br/>' +
params[0].seriesName + ': ' + params[0].value + 'kg';
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: timeData,
axisLabel: {
rotate: 45
}
},
yAxis: {
type: 'value',
name: '重量(kg)'
},
series: [{
name: '总净重',
data: totalNetWeightData,
type: 'line',
smooth: true,
itemStyle: {
color: '#67C23A'
},
areaStyle: {
opacity: 0.3
}
}]
};
console.log('设置总净重图表选项');
totalNetWeightChart.setOption(totalNetWeightOption, true); // true
} else {
console.error('总净重图表实例不存在');
}
//
if (totalGrossWeightChart) {
console.log('更新总毛重图表');
const totalGrossWeightOption = {
title: {
text: '总毛重变化趋势',
left: 'center',
textStyle: {
fontSize: 16
}
},
tooltip: {
trigger: 'axis',
formatter: function(params) {
return params[0].name + '<br/>' +
params[0].seriesName + ': ' + params[0].value + 'kg';
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: timeData,
axisLabel: {
rotate: 45
}
},
yAxis: {
type: 'value',
name: '重量(kg)'
},
series: [{
name: '总毛重',
data: totalGrossWeightData,
type: 'line',
smooth: true,
itemStyle: {
color: '#E6A23C'
},
areaStyle: {
opacity: 0.3
}
}]
};
console.log('设置总毛重图表选项');
totalGrossWeightChart.setOption(totalGrossWeightOption, true); // true
} else {
console.error('总毛重图表实例不存在');
}
console.log('图表更新完成');
});
}; };
</script> </script>
@ -569,8 +1029,26 @@ const handleClose = () => {
} }
/* 对话框样式 */ /* 对话框样式 */
.axle-details { .axle-details-container {
padding: 10px 0; display: flex;
min-height: 500px;
}
/* 左侧面板样式 */
.axle-info-panel {
flex: 1;
padding: 10px 20px 10px 10px;
border-right: 1px solid #EBEEF5;
max-height: 500px;
overflow-y: auto;
}
/* 右侧面板样式 */
.history-chart-panel {
flex: 1;
padding: 10px;
display: flex;
flex-direction: column;
} }
.detail-row { .detail-row {
@ -606,6 +1084,44 @@ const handleClose = () => {
color: #f56c6c; color: #f56c6c;
} }
/* 图表控制区域 */
.chart-controls {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
/* 图表容器样式 */
.charts-container {
flex: 1;
display: flex;
flex-direction: column;
}
.chart {
height: 400px;
width: 100%;
}
/* 加载状态 */
.chart-loading {
height: 400px;
display: flex;
align-items: center;
justify-content: center;
}
/* 无数据状态 */
.no-history-data {
height: 400px;
display: flex;
align-items: center;
justify-content: center;
color: #909399;
font-size: 16px;
}
/* 添加悬停效果,提示用户可以双击 */ /* 添加悬停效果,提示用户可以双击 */
.axle-item { .axle-item {
cursor: pointer; cursor: pointer;

Loading…
Cancel
Save