|
|
|
|
@ -0,0 +1,257 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div class="inventory-table-container">
|
|
|
|
|
<div class="table-header">
|
|
|
|
|
<h3>实时库存表</h3>
|
|
|
|
|
<div class="table-actions">
|
|
|
|
|
<el-button @click="refreshData" type="primary" size="small">刷新数据</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 调试信息 -->
|
|
|
|
|
<div v-if="!loading" style="margin-bottom: 10px; font-size: 12px; color: #666;">
|
|
|
|
|
调试信息: 获取到 {{ records.length }} 条记录,表格共 {{ tableData.length }} 行
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-loading="loading" class="table-wrapper">
|
|
|
|
|
<el-table
|
|
|
|
|
:data="tableData"
|
|
|
|
|
style="width: 100%; min-width: max-content;"
|
|
|
|
|
border
|
|
|
|
|
:header-cell-style="{ backgroundColor: '#f5f7fa', color: '#606266' }"
|
|
|
|
|
empty-text="暂无数据"
|
|
|
|
|
:scrollbar-always-on="true"
|
|
|
|
|
>
|
|
|
|
|
<!-- 规格列 -->
|
|
|
|
|
<el-table-column
|
|
|
|
|
prop="specification"
|
|
|
|
|
label="规格"
|
|
|
|
|
width="120"
|
|
|
|
|
fixed="left"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<!-- 动态列:model-wire_disc 组合 -->
|
|
|
|
|
<el-table-column
|
|
|
|
|
v-for="column in dynamicColumns"
|
|
|
|
|
:key="column.key"
|
|
|
|
|
:label="column.label"
|
|
|
|
|
:prop="column.prop"
|
|
|
|
|
min-width="150"
|
|
|
|
|
>
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
{{ scope.row[column.prop] || '-' }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
|
|
|
|
<!-- 总计列 -->
|
|
|
|
|
<el-table-column
|
|
|
|
|
label="总计"
|
|
|
|
|
width="100"
|
|
|
|
|
fixed="right"
|
|
|
|
|
>
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
{{ scope.row.total }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { ref, onMounted, computed } from 'vue'
|
|
|
|
|
import { API_CONFIG } from "@/config/api"
|
|
|
|
|
|
|
|
|
|
// 响应式数据
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
const records = ref([])
|
|
|
|
|
|
|
|
|
|
// 计算属性:动态列
|
|
|
|
|
const dynamicColumns = computed(() => {
|
|
|
|
|
if (!records.value.length) return [];
|
|
|
|
|
|
|
|
|
|
// 使用 '::' 作为分隔符
|
|
|
|
|
const combinations = [...new Set(records.value.map(item => {
|
|
|
|
|
if (item.wire_disc && item.wire_disc.trim() !== '') {
|
|
|
|
|
return `${item.model}::${item.wire_disc}`;
|
|
|
|
|
} else {
|
|
|
|
|
return item.model;
|
|
|
|
|
}
|
|
|
|
|
}))].sort(); // 可选:若需自定义排序,调整这里
|
|
|
|
|
|
|
|
|
|
return combinations.map(comb => {
|
|
|
|
|
return {
|
|
|
|
|
key: comb,
|
|
|
|
|
prop: comb,
|
|
|
|
|
label: comb.replace('::', '-') // 显示时可替换回 '-' 以保持原样
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 计算属性:表格数据
|
|
|
|
|
const tableData = computed(() => {
|
|
|
|
|
console.log('计算表格数据, records.value:', records.value);
|
|
|
|
|
|
|
|
|
|
if (!records.value.length) {
|
|
|
|
|
console.log('records为空,返回空数组');
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取所有唯一的规格并从小到大排序(可选数值排序)
|
|
|
|
|
const specifications = [...new Set(records.value.map(item => item.specification))]
|
|
|
|
|
.sort((a, b) => parseFloat(a) - parseFloat(b)); // 改为数值排序,避免 "0.800" 在前
|
|
|
|
|
|
|
|
|
|
console.log('获取到的规格列表:', specifications);
|
|
|
|
|
|
|
|
|
|
// 获取所有唯一的 model::wire_disc 组合
|
|
|
|
|
const combinations = [...new Set(records.value.map(item => {
|
|
|
|
|
if (item.wire_disc && item.wire_disc.trim() !== '') {
|
|
|
|
|
return `${item.model}::${item.wire_disc}`;
|
|
|
|
|
} else {
|
|
|
|
|
return item.model;
|
|
|
|
|
}
|
|
|
|
|
}))];
|
|
|
|
|
console.log('获取到的model::wire_disc组合:', combinations);
|
|
|
|
|
|
|
|
|
|
// 构建表格数据
|
|
|
|
|
const tableDataResult = specifications.map(specification => {
|
|
|
|
|
const row = { specification };
|
|
|
|
|
let total = 0;
|
|
|
|
|
|
|
|
|
|
combinations.forEach(comb => {
|
|
|
|
|
// 判断是否包含 wire_disc(检查 '::')
|
|
|
|
|
const hasWireDisc = comb.includes('::');
|
|
|
|
|
let model, wire_disc;
|
|
|
|
|
|
|
|
|
|
if (hasWireDisc) {
|
|
|
|
|
[model, wire_disc] = comb.split('::'); // 使用 '::' 分割
|
|
|
|
|
} else {
|
|
|
|
|
model = comb;
|
|
|
|
|
wire_disc = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查找对应的记录
|
|
|
|
|
const record = records.value.find(r => {
|
|
|
|
|
const specMatch = r.specification === specification;
|
|
|
|
|
const modelMatch = r.model === model;
|
|
|
|
|
const wireDiscMatch = hasWireDisc
|
|
|
|
|
? (r.wire_disc === wire_disc)
|
|
|
|
|
: (!r.wire_disc || r.wire_disc.trim() === '');
|
|
|
|
|
return specMatch && modelMatch && wireDiscMatch;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
row[comb] = record ? record.total_number : null;
|
|
|
|
|
if (record) total += record.total_number;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
row.total = total;
|
|
|
|
|
return row;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
console.log('生成的表格数据:', tableDataResult);
|
|
|
|
|
return tableDataResult;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 方法:获取数据
|
|
|
|
|
const fetchData = async () => {
|
|
|
|
|
loading.value = true;
|
|
|
|
|
try {
|
|
|
|
|
console.log('正在请求API:', `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.WMS_TYPE_1_RECORDS}`);
|
|
|
|
|
const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.WMS_TYPE_1_RECORDS}`);
|
|
|
|
|
const result = await response.json();
|
|
|
|
|
|
|
|
|
|
console.log('API返回结果:', result);
|
|
|
|
|
|
|
|
|
|
if (result.code === 200 && result.data && result.data.records) {
|
|
|
|
|
records.value = result.data.records;
|
|
|
|
|
console.log('设置records值:', records.value);
|
|
|
|
|
} else {
|
|
|
|
|
console.error('获取实时库存数据失败:', result.message);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('API调用失败:', error);
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 方法:刷新数据
|
|
|
|
|
const refreshData = () => {
|
|
|
|
|
fetchData();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 组件挂载时获取数据
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
fetchData();
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.inventory-table-container {
|
|
|
|
|
padding: 20px;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.table-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.table-header h3 {
|
|
|
|
|
margin: 0;
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
color: #303133;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.table-actions {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.table-wrapper {
|
|
|
|
|
width: 100%;
|
|
|
|
|
overflow-x: auto;
|
|
|
|
|
/* 确保滚动条始终可见 */
|
|
|
|
|
scrollbar-width: thin; /* Firefox */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.el-table) {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
/* 确保表格最小宽度正确计算 */
|
|
|
|
|
width: max-content !important;
|
|
|
|
|
min-width: 100% !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.el-table th) {
|
|
|
|
|
background-color: #f5f7fa !important;
|
|
|
|
|
color: #606266;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.el-table td) {
|
|
|
|
|
padding: 8px 0;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Webkit 浏览器的滚动条样式 */
|
|
|
|
|
.table-wrapper::-webkit-scrollbar {
|
|
|
|
|
height: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.table-wrapper::-webkit-scrollbar-track {
|
|
|
|
|
background: #f1f1f1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.table-wrapper::-webkit-scrollbar-thumb {
|
|
|
|
|
background: #c1c1c1;
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.table-wrapper::-webkit-scrollbar-thumb:hover {
|
|
|
|
|
background: #a8a8a8;
|
|
|
|
|
}
|
|
|
|
|
</style>
|