feat(EnamellingMachineStatus): 添加库存数据显示和单位切换功能

- 新增库存数据获取和显示功能,与销售数据一起展示
- 添加箱数和重量单位切换功能
- 优化图表显示逻辑,合并销售和库存数据
- 改进图表初始化处理,增加重试机制
- 移除调试用的console.log语句
master
huangjinysf 2 months ago
parent 3d4fd8243b
commit 520d8e0d36

@ -191,12 +191,17 @@
<el-option label="近1周" value="近1周" /> <el-option label="近1周" value="近1周" />
<el-option label="近1月" value="近1月" /> <el-option label="近1月" value="近1月" />
</el-select> </el-select>
<span class="filter-label" style="margin-left: 20px;">显示单位:</span>
<el-radio-group v-model="chartUnit" @change="onChartUnitChange" size="small">
<el-radio-button label="box">箱数</el-radio-button>
<el-radio-button label="weight">重量</el-radio-button>
</el-radio-group>
</div> </div>
<div v-if="salesChartLoading" v-loading="true" class="chart-loading"></div> <div v-if="salesChartLoading || historyChartLoading" v-loading="true" class="chart-loading"></div>
<div v-else-if="!hasSalesData" class="no-data-message"> <div v-else-if="!hasSalesData && !hasHistoryData" class="no-data-message">
暂无销售数据 暂无销售和库存数据
</div> </div>
<div v-else ref="salesChartRef" class="chart"></div> <div v-show="!salesChartLoading && (hasSalesData || hasHistoryData)" ref="salesChartRef" class="chart"></div>
</div> </div>
</div> </div>
</template> </template>
@ -228,9 +233,13 @@ const selectedCompletionLevel = ref('all') // 默认显示全部
// //
const showChart = ref(false) const showChart = ref(false)
const salesChartLoading = ref(false) const salesChartLoading = ref(false)
const historyChartLoading = ref(false)
const salesData = ref([]) const salesData = ref([])
const historyData = ref([])
const hasSalesData = ref(false) const hasSalesData = ref(false)
const hasHistoryData = ref(false)
const selectedTimeRange = ref('近1周') const selectedTimeRange = ref('近1周')
const chartUnit = ref('box')
const salesChartTitle = ref('') const salesChartTitle = ref('')
const currentSalesAxle = ref(null) const currentSalesAxle = ref(null)
const salesChartRef = ref(null) const salesChartRef = ref(null)
@ -418,7 +427,14 @@ const showSalesHistory = (row) => {
currentSalesAxle.value = { ...row }; currentSalesAxle.value = { ...row };
salesChartTitle.value = `${row.equipment_code} - ${row.axle_number} - ${row.specification} - ${row.model}`; salesChartTitle.value = `${row.equipment_code} - ${row.axle_number} - ${row.specification} - ${row.model}`;
showChart.value = true; showChart.value = true;
salesData.value = [];
historyData.value = [];
hasSalesData.value = false;
hasHistoryData.value = false;
fetchSalesData(row.model, row.specification); fetchSalesData(row.model, row.specification);
fetchHistoryData(row.model, row.specification, row.wire_disc);
}; };
// //
@ -434,6 +450,18 @@ const closeChart = () => {
const onChartTimeRangeChange = () => { const onChartTimeRangeChange = () => {
if (currentSalesAxle.value) { if (currentSalesAxle.value) {
fetchSalesData(currentSalesAxle.value.model, currentSalesAxle.value.specification); fetchSalesData(currentSalesAxle.value.model, currentSalesAxle.value.specification);
fetchHistoryData(currentSalesAxle.value.model, currentSalesAxle.value.specification, currentSalesAxle.value.wire_disc);
}
};
//
const onChartUnitChange = () => {
if (hasSalesData.value || hasHistoryData.value) {
nextTick(() => {
setTimeout(() => {
initSalesChart();
}, 100);
});
} }
}; };
@ -445,25 +473,18 @@ const fetchSalesData = (model, specification) => {
let apiUrl = `${API_CONFIG.BASE_URL}/api/sale/records?model=${model}&specification=${specification}&start_date=${dateRange.start_date}&end_date=${dateRange.end_date}`; let apiUrl = `${API_CONFIG.BASE_URL}/api/sale/records?model=${model}&specification=${specification}&start_date=${dateRange.start_date}&end_date=${dateRange.end_date}`;
console.log('获取销量数据 URL:', apiUrl);
fetch(apiUrl) fetch(apiUrl)
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
console.log('销量数据响应:', data);
if (data.code === 200 && data.data) { if (data.code === 200 && data.data) {
salesData.value = data.data; salesData.value = data.data;
hasSalesData.value = salesData.value.length > 0; hasSalesData.value = salesData.value.length > 0;
console.log('销量数据:', salesData.value, 'hasSalesData:', hasSalesData.value);
if (hasSalesData.value) { nextTick(() => {
nextTick(() => { setTimeout(() => {
setTimeout(() => { initSalesChart();
console.log('初始化图表salesChartRef:', salesChartRef.value); }, 100);
initSalesChart(); });
}, 100);
});
}
} else { } else {
salesData.value = []; salesData.value = [];
hasSalesData.value = false; hasSalesData.value = false;
@ -479,41 +500,135 @@ const fetchSalesData = (model, specification) => {
}); });
}; };
// //
const initSalesChart = () => { const fetchHistoryData = (model, specification, wireDisc) => {
console.log('initSalesChart called, hasSalesData:', hasSalesData.value, 'data length:', salesData.value.length); historyChartLoading.value = true;
console.log('salesChartRef.value:', salesChartRef.value);
if (!hasSalesData.value || !salesData.value.length) { const dateRange = getDateRangeByTimeRange(selectedTimeRange.value);
console.log('没有销量数据,跳过图表初始化');
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}`;
fetch(apiUrl)
.then(response => response.json())
.then(data => {
if (data.code === 200 && data.data && data.data.records) {
historyData.value = data.data.records;
hasHistoryData.value = historyData.value.length > 0;
nextTick(() => {
setTimeout(() => {
initSalesChart();
}, 100);
});
} else {
historyData.value = [];
hasHistoryData.value = false;
}
})
.catch(error => {
console.error('库存历史数据API调用失败:', error);
historyData.value = [];
hasHistoryData.value = false;
})
.finally(() => {
historyChartLoading.value = false;
});
};
//
const initSalesChart = (retryCount = 0) => {
if (!hasSalesData.value && !hasHistoryData.value) {
return; return;
} }
if (!salesChartRef.value) { if (!salesChartRef.value) {
console.warn('图表容器未渲染,尝试重新初始化'); if (retryCount >= 20) {
return;
}
setTimeout(() => { setTimeout(() => {
initSalesChart(); initSalesChart(retryCount + 1);
}, 200); }, 50);
return; return;
} }
console.log('开始初始化图表');
if (salesChart) { if (salesChart) {
salesChart.dispose(); salesChart.dispose();
} }
salesChart = echarts.init(salesChartRef.value); salesChart = echarts.init(salesChartRef.value);
const dates = salesData.value.map(item => { const salesDateMap = new Map();
const date = new Date(item.date); const historyDateMap = new Map();
return `${date.getMonth() + 1}/${date.getDate()}`;
if (hasSalesData.value && salesData.value.length > 0) {
salesData.value.forEach((item, index) => {
const dateStr = item.date;
const date = new Date(dateStr);
if (!isNaN(date.getTime())) {
const dateKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}-${index}`;
const existing = salesDateMap.get(dateKey);
if (existing) {
existing.boxCount += item.box_count || 0;
existing.weight += item.weight || 0;
} else {
salesDateMap.set(dateKey, {
displayDate: `${date.getMonth() + 1}/${date.getDate()}`,
boxCount: item.box_count || 0,
weight: item.weight || 0
});
}
}
});
}
if (hasHistoryData.value && historyData.value.length > 0) {
historyData.value.forEach((item, index) => {
const dateStr = item.create_time;
const date = new Date(dateStr);
if (!isNaN(date.getTime())) {
const dateKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}-${index}`;
historyDateMap.set(dateKey, {
displayDate: `${date.getMonth() + 1}/${date.getDate()} ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`,
totalNumber: item.total_number ?? null,
totalNetWeight: item.total_net_weight ?? null
});
}
});
}
const allDates = new Set([...salesDateMap.keys(), ...historyDateMap.keys()]);
const sortedDates = Array.from(allDates).sort((a, b) => {
const timeA = a.split('-').slice(0, 3).join('-');
const timeB = b.split('-').slice(0, 3).join('-');
return new Date(timeA) - new Date(timeB);
}); });
const boxCountData = salesData.value.map(item => item.box_count); const dates = [];
const weightData = salesData.value.map(item => item.weight); const salesBoxData = [];
const salesWeightData = [];
const historyBoxData = [];
const historyWeightData = [];
console.log('图表数据:', { dates, boxCountData, weightData }); sortedDates.forEach(dateKey => {
const salesItem = salesDateMap.get(dateKey);
const historyItem = historyDateMap.get(dateKey);
if (salesItem || historyItem) {
dates.push(salesItem?.displayDate || historyItem?.displayDate);
salesBoxData.push(salesItem?.boxCount ?? null);
salesWeightData.push(salesItem?.weight ?? null);
historyBoxData.push(historyItem?.totalNumber ?? null);
historyWeightData.push(historyItem?.totalNetWeight ?? null);
}
});
const isBoxUnit = chartUnit.value === 'box';
const chartSalesData = isBoxUnit ? salesBoxData : salesWeightData;
const chartHistoryData = isBoxUnit ? historyBoxData : historyWeightData;
const yAxisName = isBoxUnit ? '箱数' : '重量(kg)';
const historyName = isBoxUnit ? '库存箱数' : '库存重量(kg)';
const salesName = isBoxUnit ? '销售箱数' : '销售重量(kg)';
const option = { const option = {
tooltip: { tooltip: {
@ -523,7 +638,7 @@ const initSalesChart = () => {
} }
}, },
legend: { legend: {
data: ['箱数', '重量(kg)'], data: [salesName, historyName],
top: 10 top: 10
}, },
grid: { grid: {
@ -536,57 +651,49 @@ const initSalesChart = () => {
type: 'category', type: 'category',
data: dates, data: dates,
axisLabel: { axisLabel: {
interval: 0, interval: Math.floor(dates.length / 10),
rotate: 30 rotate: 30
} }
}, },
yAxis: [ yAxis: {
{ type: 'value',
type: 'value', name: yAxisName,
name: '箱数', position: 'left',
position: 'left', axisLine: {
axisLine: { show: true,
show: true, lineStyle: {
lineStyle: { color: '#5470C6'
color: '#5470C6'
}
}
},
{
type: 'value',
name: '重量(kg)',
position: 'right',
axisLine: {
show: true,
lineStyle: {
color: '#91CC75'
}
} }
} }
], },
series: [ series: [
{ {
name: '箱数', name: salesName,
type: 'bar', type: 'bar',
data: boxCountData, data: chartSalesData,
itemStyle: { itemStyle: {
color: '#5470C6' color: '#5470C6'
} },
barGap: '10%',
connectNulls: true
}, },
{ {
name: '重量(kg)', name: historyName,
type: 'line', type: 'line',
yAxisIndex: 1, data: chartHistoryData,
data: weightData,
itemStyle: { itemStyle: {
color: '#91CC75' color: '#91CC75'
} },
lineStyle: {
width: 3
},
symbol: 'none',
connectNulls: true
} }
] ]
}; };
salesChart.setOption(option); salesChart.setOption(option);
console.log('图表已渲染');
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
if (salesChart) { if (salesChart) {

Loading…
Cancel
Save