|
|
|
@ -56,57 +56,94 @@
|
|
|
|
<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="detail-row">
|
|
|
|
<!-- 左侧:轴基本信息 -->
|
|
|
|
<span class="detail-label">设备编号:</span>
|
|
|
|
<div class="axle-info-panel">
|
|
|
|
<span class="detail-value">{{ selectedEquipmentCode }}</span>
|
|
|
|
<div class="detail-title">基本信息</div>
|
|
|
|
</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">{{ selectedAxle.axle_number }}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">运行状态:</span>
|
|
|
|
|
|
|
|
<span class="detail-value" :class="{ 'status-running': selectedAxle.update_time, 'status-stopped': !selectedAxle.update_time }">
|
|
|
|
|
|
|
|
{{ selectedAxle.update_time ? '运行中' : '不在运行' }}
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">规格:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.specification || '无' }}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">型号:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.model || '无' }}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">线盘:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.raw_wire_disc || '无' }}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">完成度:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ (selectedAxle.degree_of_completion * 100).toFixed(1) }}%</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time && (selectedAxle.total_number || selectedAxle.total_net_weight || selectedAxle.total_gross_weight)" class="stock-details">
|
|
|
|
|
|
|
|
<div class="detail-title">库存信息</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.total_number" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">总箱数:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.total_number }}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div v-if="selectedAxle.total_net_weight" class="detail-row">
|
|
|
|
<div class="detail-row">
|
|
|
|
<span class="detail-label">总净重:</span>
|
|
|
|
<span class="detail-label">轴号:</span>
|
|
|
|
<span class="detail-value">{{ selectedAxle.total_net_weight }}kg</span>
|
|
|
|
<span class="detail-value">{{ selectedAxle.axle_number }}</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div v-if="selectedAxle.total_gross_weight" class="detail-row">
|
|
|
|
<div class="detail-row">
|
|
|
|
<span class="detail-label">总毛重:</span>
|
|
|
|
<span class="detail-label">运行状态:</span>
|
|
|
|
<span class="detail-value">{{ selectedAxle.total_gross_weight }}kg</span>
|
|
|
|
<span class="detail-value" :class="{ 'status-running': selectedAxle.update_time, 'status-stopped': !selectedAxle.update_time }">
|
|
|
|
|
|
|
|
{{ selectedAxle.update_time ? '运行中' : '不在运行' }}
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">规格:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.specification || '无' }}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">型号:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.model || '无' }}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">线盘:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.raw_wire_disc || '无' }}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">完成度:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ (selectedAxle.degree_of_completion * 100).toFixed(1) }}%</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time && (selectedAxle.total_number || selectedAxle.total_net_weight || selectedAxle.total_gross_weight)" class="stock-details">
|
|
|
|
|
|
|
|
<div class="detail-title">库存信息</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.total_number" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">总箱数:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.total_number }}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.total_net_weight" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">总净重:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.total_net_weight }}kg</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.total_gross_weight" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">总毛重:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.total_gross_weight }}kg</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="selectedAxle.update_time" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">最后更新:</span>
|
|
|
|
|
|
|
|
<span class="detail-value">{{ selectedAxle.update_time }}</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div v-if="selectedAxle.update_time" class="detail-row">
|
|
|
|
|
|
|
|
<span class="detail-label">最后更新:</span>
|
|
|
|
<!-- 右侧:历史数据图表 -->
|
|
|
|
<span class="detail-value">{{ selectedAxle.update_time }}</span>
|
|
|
|
<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>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<template #footer>
|
|
|
|
<template #footer>
|
|
|
|
@ -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);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 使用setTimeout确保DOM完全渲染后再操作图表
|
|
|
|
|
|
|
|
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('准备更新图表');
|
|
|
|
|
|
|
|
// 使用setTimeout确保DOM完全渲染后再初始化图表
|
|
|
|
|
|
|
|
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;
|
|
|
|
|