refactor(wms): 重构物料信息展示逻辑,移除冗余组件

重构物料信息展示逻辑,统一使用itemName等字段替代原有的product和rawMaterial嵌套结构
删除不再使用的BomInfo、CategoryRenderer等冗余组件
新增report模块配置集中管理
优化代码结构,提升可维护性
This commit is contained in:
砂糖
2026-03-24 13:55:10 +08:00
parent 9738a32d9d
commit ae68b40ee6
65 changed files with 363 additions and 3479 deletions

View File

@@ -1,95 +0,0 @@
<template>
<div>
<el-descriptions :column="1" border v-if="bomInfo.length > 0">
<el-descriptions-item v-for="item in bomInfo" :key="item.attrKey" :label="item.attrKey">
{{ item.attrValue }}
</el-descriptions-item>
</el-descriptions>
<div v-else>
<el-empty description="暂无参数信息" />
</div>
</div>
</template>
<script>
// 如果传递了bomId直接使用bomId, 如果没有传递则根据itemType和itemId获取bomId
import { listBomItem } from '@/api/wms/bomItem';
import { mapState } from 'vuex';
export default {
name: 'BomInfo',
props: {
bomId: {
type: [String, Number],
required: false
},
itemType: {
type: String,
required: false
},
itemId: {
type: [String, Number],
required: false
}
},
data() {
return {
bomInfo: []
}
},
computed: {
...mapState('category', ['bomMap', 'productMap', 'rawMaterialMap']),
},
watch: {
bomId: {
handler: function (newVal) {
this.getBomInfo();
},
immediate: true
},
itemId: {
handler: function (newVal) {
this.getBomInfo();
},
immediate: true
}
},
methods: {
getBomInfo() {
const bomMap = this.$store.getters.bomMap;
if (!this.bomId && !this.itemType && !this.itemId) {
return;
}
let bomId = this.bomId;
if (!bomId) {
if (this.itemType === 'product') {
bomId = this.productMap[this.itemId]?.bomId;
} else if (this.itemType === 'raw_material') {
bomId = this.rawMaterialMap[this.itemId]?.bomId;
}
}
if (!bomId) {
return;
}
if (bomMap[bomId]) {
this.bomInfo = bomMap[bomId];
} else {
listBomItem({ bomId }).then(res => {
this.bomInfo = res.rows;
})
}
}
}
}
</script>
<style scoped>
.bom-info {
cursor: pointer;
/* 溢出隐藏显示省略号 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100px;
}
</style>

View File

@@ -1,96 +0,0 @@
<template>
<div>
<div v-if="bomInfo.length > 0">
<el-tooltip :content="bomInfo.map(item => item.attrKey + ':' + item.attrValue).join(',')" class="bom-info" placement="top">
<span>{{ bomInfo.map(item => item.attrKey).join(',') }}</span>
</el-tooltip>
</div>
<div v-else>
-
</div>
</div>
</template>
<script>
// 如果传递了bomId直接使用bomId, 如果没有传递则根据itemType和itemId获取bomId
import { listBomItem } from '@/api/wms/bomItem';
import { mapState } from 'vuex';
export default {
name: 'BomInfo',
props: {
bomId: {
type: [String, Number],
required: false
},
itemType: {
type: String,
required: false
},
itemId: {
type: [String, Number],
required: false
}
},
data() {
return {
bomInfo: []
}
},
computed: {
...mapState('category', ['bomMap', 'productMap', 'rawMaterialMap']),
},
watch: {
bomId: {
handler: function (newVal) {
this.getBomInfo();
},
immediate: true
},
itemId: {
handler: function (newVal) {
this.getBomInfo();
},
immediate: true
}
},
methods: {
getBomInfo() {
const bomMap = this.$store.getters.bomMap;
if (!this.bomId && !this.itemType && !this.itemId) {
return;
}
let bomId = this.bomId;
if (!bomId) {
if (this.itemType === 'product') {
bomId = this.productMap[this.itemId]?.bomId;
} else if (this.itemType === 'raw_material') {
bomId = this.rawMaterialMap[this.itemId]?.bomId;
}
}
if (!bomId) {
this.bomInfo = [];
return;
}
if (bomMap[bomId]) {
this.bomInfo = bomMap[bomId];
} else {
listBomItem({ bomId }).then(res => {
this.bomInfo = res.rows;
})
}
}
}
}
</script>
<style scoped>
.bom-info {
cursor: pointer;
/* 溢出隐藏显示省略号 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100px;
}
</style>

View File

@@ -1,28 +0,0 @@
<template>
<span v-if="category">
<slot :category="category">
{{ category.categoryName }}
</slot>
</span>
<span v-else>--</span>
</template>
<script>
import { mapState } from 'vuex';
export default {
name: 'CategoryRenderer',
props: {
categoryId: {
type: [String, Number],
required: true
}
},
computed: {
...mapState('category', ['categoryList']),
category() {
return this.categoryList.find(cat => String(cat.categoryId) === String(this.categoryId));
}
}
};
</script>

View File

@@ -80,16 +80,16 @@ export default {
return this.coilNo && this.coilNo.startsWith('G');
},
specification() {
return this.coilInfo.product?.specification || this.coilInfo.rawMaterial?.specification || '-'
return this.coilInfo.specification || '-'
},
itemName() {
return this.coilInfo.product?.productName || this.coilInfo.rawMaterial?.rawMaterialName || '-'
return this.coilInfo.itemName || '-'
},
material() {
return this.coilInfo.product?.material || this.coilInfo.rawMaterial?.material || '-'
return this.coilInfo.material || '-'
},
manufacturer() {
return this.coilInfo.product?.manufacturer || this.coilInfo.rawMaterial?.manufacturer || '-'
return this.coilInfo.manufacturer || '-'
},
currentCoilNo() {
return this.coilNo || this.coilInfo?.currentCoilNo || '-'

View File

@@ -1,26 +0,0 @@
<template>
<el-tag>{{ getCraftInfo() }}</el-tag>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
name: 'CraftInfo',
props: {
craftId: {
type: [String, Number, undefined],
required: true
}
},
computed: {
...mapGetters(['processList'])
},
methods: {
getCraftInfo() {
const craft = this.processList.find(item => item.processId === this.craftId);
return craft.processName;
}
}
}
</script>

View File

@@ -64,9 +64,9 @@ export default {
return {};
}
return {
productId: this.product.productId || '',
productName: this.product.productName || '',
productCode: this.product.productCode || '',
productId: this.product.itemId || '',
productName: this.product.itemName || '',
// productCode: this.product.productCode || '',
specification: this.product.specification || '',
material: this.product.material || '',
surfaceTreatment: this.product.surfaceTreatmentDesc || '',

View File

@@ -1,119 +0,0 @@
<template>
<div v-loading="loading" loading-text="加载中...">
<span class="product-name" @click.stop="clickHandle">
<slot name="default" :product="product">
{{ product && product.productName ? product.productName : '--' }}
</slot>
</span>
<el-dialog
:visible="showDetail"
@close="showDetail = false"
:title="product && product.productName ? product.productName : '--' "
width="500px"
append-to-body
>
<el-descriptions :column="1" border>
<el-descriptions-item label="产品名称">
{{ product.productName || '--' }}
</el-descriptions-item>
<el-descriptions-item label="产品编码">
{{ product.productCode || '--' }}
</el-descriptions-item>
<el-descriptions-item label="规格">
{{ product.specification || '--' }}
</el-descriptions-item>
<el-descriptions-item label="材质">
{{ product.material || '--' }}
</el-descriptions-item>
<el-descriptions-item label="表面处理">
{{ product.surfaceTreatment || '--' }}
</el-descriptions-item>
<!-- 锌层 -->
<el-descriptions-item label="镀层质量">
{{ product.zincLayer || '--' }}
</el-descriptions-item>
<!-- 厂家 -->
<el-descriptions-item label="厂家">
{{ product.manufacturer || '--' }}
</el-descriptions-item>
</el-descriptions>
<!-- <BomInfo :bomId="product.bomId" /> -->
</el-dialog>
</div>
</template>
<script>
import { mapState } from 'vuex';
import BomInfo from './BomInfo.vue';
export default {
name: 'ProductInfo',
components: {
BomInfo
},
props: {
productId: {
type: [String, Number],
required: true
},
},
mounted() {
console.log(this.productId, this.productMap);
},
data() {
return {
showDetail: false,
// product: {},
};
},
computed: {
...mapState({
productMap: state => state.category.productMap
}),
product() {
// 检查 productMap 是否已加载
if (!this.productMap || Object.keys(this.productMap).length === 0) {
return {};
}
if (!this.productId) {
return {};
}
return this.productMap[this.productId.toString()] || {};
},
loading() {
return !this.productMap || Object.keys(this.productMap).length === 0
}
},
methods: {
clickHandle() {
this.showDetail = true;
}
},
// watch: {
// productId: {
// handler(newVal) {
// if (!newVal) {
// this.product = {};
// }
// const res = this.productMap[newVal.toString()] ? this.productMap[newVal.toString()] : {};
// this.product = res;
// },
// immediate: true
// }
// }
};
</script>
<style scoped>
.product-name {
color: #1890ff;
cursor: pointer;
text-decoration: underline;
}
/* 可选:调整描述列表的外边距 */
:deep(.el-descriptions) {
margin-top: -10px;
}
</style>

View File

@@ -31,13 +31,8 @@
</template>
<script>
import BomInfo from './BomInfo.vue'; // 保留导入(如需使用可解除注释)
export default {
name: 'RawMaterialInfo',
components: {
BomInfo
},
props: {
material: {
type: Object,
@@ -56,9 +51,9 @@ export default {
return {};
}
return {
rawMaterialId: this.material.rawMaterialId || '',
rawMaterialName: this.material.rawMaterialName || '',
rawMaterialCode: this.material.rawMaterialCode || '',
rawMaterialId: this.material.itemId || '',
rawMaterialName: this.material.itemName || '',
// rawMaterialCode: this.material.rawMaterialCode || '',
specification: this.material.specification || '',
material: this.material.material || '',
surfaceTreatment: this.material.surfaceTreatmentDesc || '',

View File

@@ -1,84 +0,0 @@
<template>
<div v-loading="loading" loading-text="加载中...">
<!-- 作用域插槽 -->
<span class="material-name" @click.stop="showDetail = true">
<slot name="default" :material="material">
{{ material.rawMaterialName ? material.rawMaterialName : '-' }}
</slot>
</span>
<el-dialog :visible="showDetail" @close="showDetail = false" :title="material.rawMaterialName" width="600px"
append-to-body>
<el-descriptions :column="1" border>
<!-- <el-descriptions-item label="原材料ID">{{ material.rawMaterialId }}</el-descriptions-item> -->
<el-descriptions-item label="原材料名称">{{ material.rawMaterialName }}</el-descriptions-item>
<el-descriptions-item label="原材料编码">{{ material.rawMaterialCode }}</el-descriptions-item>
<el-descriptions-item label="规格">{{ material.specification }}</el-descriptions-item>
<el-descriptions-item label="材质">
{{ material.material || '--' }}
</el-descriptions-item>
<el-descriptions-item label="表面处理">
{{ material.surfaceTreatment || '--' }}
</el-descriptions-item>
<!-- 锌层 -->
<el-descriptions-item label="镀层质量">
{{ material.zincLayer || '--' }}
</el-descriptions-item>
<!-- 厂家 -->
<el-descriptions-item label="厂家">
{{ material.manufacturer || '--' }}
</el-descriptions-item>
</el-descriptions>
<!-- <BomInfo :bomId="material.bomId" /> -->
</el-dialog>
</div>
</template>
<script>
import { mapState } from 'vuex';
import BomInfo from './BomInfo.vue';
export default {
name: 'RawMaterialInfo',
components: {
BomInfo
},
props: {
materialId: {
type: [String, Number],
required: true
}
},
data() {
return {
showDetail: false,
// material: {},
};
},
computed: {
...mapState({
materialMap: state => state.category.rawMaterialMap // 假设vuex中为material模块
}),
material() {
// 检查 materialMap 是否已加载
if (!this.materialMap || Object.keys(this.materialMap).length === 0) {
return {};
}
if (!this.materialId) {
return {};
}
return this.materialMap[this.materialId.toString()] || {};
},
loading() {
return !this.materialMap || Object.keys(this.materialMap).length === 0
}
},
}
</script>
<style scoped>
.material-name {
color: #1890ff;
cursor: pointer;
text-decoration: underline;
}
</style>

View File

@@ -1,10 +1,8 @@
export { default as CheckItemSelect } from './CheckItemSelect/index.vue';
export { default as ProductSelect } from './ProductSelect/index.vue';
export { default as RawMaterialSelect } from './RawMaterialSelect/index.vue';
export { default as CategoryRenderer } from './Renderer/CategoryRenderer.vue';
export { default as UserSelect } from './UserSelect/index.vue';
export { default as WarehouseSelect } from './WarehouseSelect/index.vue';
export { default as ProductInfo } from './Renderer/ProductInfo.vue';
export { default as RawMaterialInfo } from './Renderer/RawMaterialInfo.vue';
export { default as BomInfoMini } from './Renderer/BomInfoMini.vue';
export { default as WarehouseTree } from './WarehouseTree/index.vue';