You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

328 lines
8.7 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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"
@cell-dblclick="handleCellDblClick"
>
<!-- 规格列 -->
<el-table-column
prop="specification"
label="规格"
width="80"
fixed="left"
/>
<!-- 动态列model-wire_disc 组合 -->
<el-table-column
v-for="column in dynamicColumns"
:key="column.key"
:label="column.label"
:prop="column.prop"
min-width="100"
>
<template #default="scope">
{{ scope.row[column.prop] || '-' }}
</template>
<template #header>
<div v-html="column.label"></div> <!-- 使用 v-html 渲染 HTML 标签,确保 <br> 生效 -->
</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>
<!-- WmsTable 详情对话框 -->
<el-dialog
v-model="wmsDialogVisible"
title="库存详情"
width="80%"
destroy-on-close
>
<WmsTable
v-if="wmsDialogVisible"
ref="wmsTableRef"
:model="currentWmsModel"
:specification="currentWmsSpecification"
:loading-height="200"
:show-action="true"
/>
</el-dialog>
</div>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue'
import { API_CONFIG } from "@/config/api"
import { ElMessage } from 'element-plus'
import WmsTable from '@/components/WmsTable/index.vue'
// 响应式数据
const loading = ref(false)
const records = ref([])
// WMS对话框相关状态
const wmsDialogVisible = ref(false)
const currentWmsModel = ref('')
const currentWmsSpecification = ref('')
const wmsTableRef = ref(null)
// 计算属性:动态列
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 => {
// 将组合拆分为 model 和 wire_disc
const hasWireDisc = comb.includes('::');
const [model, wire_disc] = hasWireDisc ? comb.split('::') : [comb, ''];
return {
key: comb,
prop: comb,
label: `${model}<br>${wire_disc}` // 使用HTML换行符实现两行显示
};
});
});
// 计算属性:表格数据
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();
};
// 方法:处理单元格双击事件
const handleCellDblClick = (row, column, cell, event) => {
const cellValue = row[column.property];
// 检查单元格是否有值
if (!cellValue || cellValue === '-' || cellValue === null || cellValue === undefined) {
ElMessage.warning('该单元格暂无数据');
return;
}
// 检查是否是规格列或总计列这些列不需要显示WMS详情
if (column.property === 'specification' || column.property === 'total') {
ElMessage.info('该列不支持查看详情');
return;
}
// 从列属性中提取model和wire_disc
const columnKey = column.property;
const hasWireDisc = columnKey.includes('::');
let model, wire_disc;
if (hasWireDisc) {
[model, wire_disc] = columnKey.split('::');
} else {
model = columnKey;
wire_disc = null;
}
// 设置当前WMS数据的参数
currentWmsModel.value = model;
currentWmsSpecification.value = row.specification;
// 显示WMS详情对话框
wmsDialogVisible.value = true;
};
// 组件挂载时获取数据
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;
text-align: center; /* 可选:居中对齐列头 */
padding: 8px 0; /* 调整列头内间距,以适应两行显示 */
}
: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>