feat(wms): 新增热轧原料库存透视功能及相关组件

添加热轧原料库存透视表API接口
创建透视表展示组件HotZhaRaw.vue和Perspective.vue
实现数据持久化功能及左右布局管理界面
优化锌卷标签显示样式及字段名称
This commit is contained in:
砂糖
2026-03-09 13:06:30 +08:00
parent d3da84f65e
commit 693edbb543
7 changed files with 844 additions and 6 deletions

View File

@@ -37,11 +37,11 @@
<!-- 第四行包装要求切边要求 -->
<div class="grid-cell label-cell">包装要求</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.packagingRequirements || '' }}</div>
<div class="nob" contenteditable>{{ content.packagingRequirement || '' }}</div>
</div>
<div class="grid-cell label-cell">切边要求</div>
<div class="grid-cell value-cell">
<div class="nob" contenteditable>{{ content.trimmingRequirements || '' }}</div>
<div class="nob" contenteditable>{{ content.trimmingRequirement || '' }}</div>
</div>
<!-- 第五行班组代码二维码 -->
@@ -192,7 +192,7 @@ export default {
.grid-cell {
border: 1px solid #333;
padding: 4px;
font-size: 14px;
font-size: 20px;
box-sizing: border-box;
text-align: center;
word-break: break-all;
@@ -205,14 +205,14 @@ export default {
/* 公司名称单元格 */
.company-cell {
grid-column: span 4; /* 跨4列 */
font-size: 18px;
font-size: 24px;
font-weight: bold;
background-color: #f5f5f5;
/* background-color: #f5f5f5; */
}
/* 标签单元格(左) */
.label-cell {
background-color: #f5f5f5;
/* background-color: #f5f5f5; */
font-weight: bold;
}

View File

@@ -0,0 +1,175 @@
<template>
<div class="hot-zha-raw">
<div v-if="!data || data.length === 0" class="empty-data">
暂无数据
</div>
<div v-else class="data-container">
<!-- 表头 -->
<div class="header-row">
<div class="header-cell manufacturer-header">厂家</div>
<div class="header-cell material-header">材质</div>
<div class="header-cell spec-header">规格</div>
<div class="header-cell count-header">求和项:件数</div>
<div class="header-cell weight-header">求和项:重量</div>
</div>
<!-- 数据行 -->
<div v-for="(manufacturer, mIndex) in processedData" :key="'manufacturer-' + mIndex" class="manufacturer-section">
<!-- 厂家行 -->
<div class="row manufacturer-row">
<div class="cell manufacturer-cell" :colspan="2">{{ manufacturer.manufacturer }}</div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell">{{ manufacturer.totalCoilCount }}</div>
<div class="cell">{{ manufacturer.totalWeight }}</div>
</div>
<!-- 材质行 -->
<div v-for="(material, matIndex) in manufacturer.materials" :key="'material-' + mIndex + '-' + matIndex" class="material-section">
<div class="row material-row">
<div class="cell"></div>
<div class="cell material-cell">{{ material.material }}</div>
<div class="cell"></div>
<div class="cell">{{ material.totalCoilCount }}</div>
<div class="cell">{{ material.totalWeight }}</div>
</div>
<!-- 规格行 -->
<div v-for="(spec, sIndex) in material.specifications" :key="'spec-' + mIndex + '-' + matIndex + '-' + sIndex" class="row spec-row">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell spec-cell">{{ spec.specification }}</div>
<div class="cell">{{ spec.coilCount }}</div>
<div class="cell">{{ spec.totalWeight }}</div>
</div>
</div>
</div>
<div v-if="processedData.length === 0" class="no-data">
过滤后暂无数据
</div>
</div>
</div>
</template>
<script>
export default {
name: 'HotZhaRaw',
props: {
data: {
type: Array,
default: () => ([])
},
},
computed: {
processedData() {
if (!this.data || !Array.isArray(this.data)) {
return [];
}
return this.data;
}
},
methods: {
handleSave() {
this.$emit('save', this.processedData);
}
}
}
</script>
<style scoped>
.hot-zha-raw {
width: 100%;
min-height: 200px;
}
.empty-data,
.no-data {
text-align: center;
padding: 40px;
color: #999;
font-size: 14px;
}
.data-container {
width: 100%;
border: 1px solid #ddd;
border-radius: 4px;
overflow: hidden;
}
.header-row {
display: flex;
background-color: #f2f2f2;
font-weight: bold;
position: sticky;
top: 0;
z-index: 10;
}
.header-cell {
padding: 8px;
border-right: 1px solid #ddd;
word-break: break-all;
}
.header-cell:last-child {
border-right: none;
}
.manufacturer-header {
width: 200px;
}
.material-header {
width: 100px;
}
.spec-header {
width: 150px;
}
.count-header,
.weight-header {
width: 120px;
text-align: right;
}
.row {
display: flex;
border-top: 1px solid #ddd;
}
.row:first-child {
border-top: none;
}
.cell {
padding: 8px;
border-right: 1px solid #ddd;
word-break: break-all;
}
.cell:last-child {
border-right: none;
}
/* 确保表头和数据行的列宽一致 */
.row .cell:nth-child(1) {
width: 200px;
}
.row .cell:nth-child(2) {
width: 100px;
}
.row .cell:nth-child(3) {
width: 150px;
}
.row .cell:nth-child(4),
.row .cell:nth-child(5) {
width: 120px;
text-align: right;
}
.spec-cell {
padding-left: 20px;
}
.manufacturer-row {
background-color: #e6f7ff;
}
.material-row {
background-color: #f0f5ff;
}
.spec-row {
background-color: #f9f9f9;
}
.manufacturer-cell {
font-weight: bold;
}
.material-cell {
font-weight: bold;
}
.spec-cell {
padding-left: 20px;
}
</style>

View File

@@ -0,0 +1,48 @@
<template>
<div class="perspective">
<hot-zha-raw :data="data" />
</div>
</template>
<script>
import HotZhaRaw from "@/views/wms/coil/panels/Perspective/HotZhaRaw.vue";
export default {
name: 'Perspective',
props: {
data: {
type: Array,
default: () => ([])
},
type: {
type: String,
default: ''
},
},
data() {
return {
title: ''
}
},
components: {
HotZhaRaw,
},
methods: {
handleSave(data) {
const dataText = JSON.stringify(data, null, 2);
this.$emit('save', {
title: this.title,
data: dataText,
type: this.type,
});
}
}
}
</script>
<style scoped>
.perspective {
width: 100%;
min-height: 200px;
font-size: 14px;
}
</style>