feat(调拨单): 新增调拨单管理功能

- 新增调拨单主表和明细表相关API接口
- 新增调拨单主表和明细表前端页面
- 新增钢卷选择器组件和调拨明细表格组件
- 修改产品信息和原料信息渲染组件支持更多字段
- 修改产品选择和原料选择组件支持数值类型值
- 修改钢卷号渲染组件支持更多字段和外部数据
- 新增调拨单匹配物料接口
This commit is contained in:
砂糖
2026-03-28 14:08:27 +08:00
parent 00939dae2f
commit 499654907b
13 changed files with 2520 additions and 33 deletions

View File

@@ -0,0 +1,227 @@
<template>
<el-table :data="tableData" style="width: 100%" border>
<el-table-column prop="coilId" label="钢卷号">
<template slot-scope="scope">
<CoilNo :coil-no="scope.row.coil.enterCoilNo" :coil="scope.row.coil" />
</template>
</el-table-column>
<el-table-column prop="coilId" label="当前钢卷号">
<template slot-scope="scope">
<current-coil-no :current-coil-no="scope.row.coil.currentCoilNo" />
</template>
</el-table-column>
<el-table-column prop="materialTypeBefore" label="调拨前类型" width="100">
<template slot-scope="scope">
{{ scope.row.materialTypeBefore == '1' ? '原料' : '产品' }}
</template>
</el-table-column>
<el-table-column prop="itemIdBefore" label="调拨前物料" width="260">
<template slot-scope="scope">
<ProductInfo v-if="scope.row.materialTypeBefore == '2'" :product="scope.row.oBefore" />
<RawMaterialInfo v-else-if="scope.row.materialTypeBefore == '1'" :material="scope.row.oBefore" />
</template>
</el-table-column>
<el-table-column prop="warehouseNameBefore" label="调拨前库区" width="180" />
<el-table-column prop="materialTypeAfter" label="调拨后类型" width="100">
<template slot-scope="scope">
<el-select v-if="!scope.row.isConfirmed" v-model="scope.row.materialTypeAfter"
@change="handleMaterialChange(scope.row)" placeholder="请选择">
<el-option label="原料" :value="1" />
<el-option label="产品" :value="2" />
</el-select>
<div v-else slot-scope="scope">
{{ scope.row.materialTypeAfter == '1' ? '原料' : '产品' }}
</div>
</template>
</el-table-column>
<el-table-column prop="itemIdAfter" v-loading="materialLoading" label="调拨后物料" width="260">
<template slot-scope="scope">
<div v-loading="materialLoading" v-if="!scope.row.isConfirmed">
<RawMaterialSelect v-model="scope.row.itemIdAfter" v-if="scope.row.materialTypeAfter == '1'" />
<ProductSelect v-model="scope.row.itemIdAfter" v-else-if="scope.row.materialTypeAfter == '2'" />
</div>
<div v-else>
<ProductInfo v-if="scope.row.materialTypeAfter == '2'" :product="scope.row.oAfter" />
<RawMaterialInfo v-else-if="scope.row.materialTypeAfter == '1'" :material="scope.row.oAfter" />
</div>
</template>
</el-table-column>
<el-table-column prop="warehouseIdAfter" label="调拨后库区" width="200">
<template slot-scope="scope">
<el-select v-if="!scope.row.isConfirmed" v-model="scope.row.warehouseIdAfter" placeholder="请选择">
<el-option v-for="item in warehouseList" :disabled="!item.isEnabled" :key="item.warehouseId"
:label="item.warehouseName" :value="item.warehouseId" />
</el-select>
<div v-else>
{{ scope.row.warehouseNameAfter }}
</div>
</template>
</el-table-column>
<el-table-column type="action" label="操作" width="180">
<template slot-scope="scope">
<el-button icon="el-icon-check" size="mini" v-if="!scope.row.isConfirmed" @click="handleConfirm(scope.row)"
:loading="buttonLoading">确认</el-button>
<el-button icon="el-icon-close" size="mini" @click="handleCancel(scope.row)"
:loading="buttonLoading">取消</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script>
import { matchOrCreateMaterial, confirmTransferOrderItem, cancelTransferOrderItem } from '@/api/wms/transferOrderItem'
import ProductSelect from "@/components/KLPService/ProductSelect";
import RawMaterialSelect from "@/components/KLPService/RawMaterialSelect";
import { listWarehouse } from '@/api/wms/warehouse';
import CoilNo from "@/components/KLPService/Renderer/CoilNo";
import ProductInfo from "@/components/KLPService/Renderer/ProductInfo";
import RawMaterialInfo from "@/components/KLPService/Renderer/RawMaterialInfo";
export default {
props: {
data: {
type: Array,
default: () => []
}
},
components: {
// WarehouseSelect,
ProductSelect,
RawMaterialSelect,
CoilNo,
ProductInfo,
RawMaterialInfo
},
data() {
return {
tableData: [],
materialLoading: false,
warehouseList: [],
buttonLoading: false
}
},
mounted() {
this.getWarehouseList()
},
watch: {
data: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
// 预处理数据
this.tableData = newVal.map(item => {
const isConfirmed = this.isConfirmed(item);
if (isConfirmed) {
return {
...item,
oBefore: {
manufacturer: item.manufacturerBefore,
specification: item.specificationBefore,
material: item.materialBefore,
itemName: item.materialNameBefore,
surfaceTreatmentDesc: item.surfaceTreatmentBefore,
zincLayer: item.zincLayerBefore
},
oAfter: {
manufacturer: item.manufacturerAfter,
specification: item.specificationAfter,
material: item.materialAfter,
itemName: item.materialNameAfter,
surfaceTreatmentDesc: item.surfaceTreatmentAfter,
zincLayer: item.zincLayerAfter
},
isConfirmed: true
}
} else {
return {
...item,
oBefore: {
manufacturer: item.manufacturerBefore,
specification: item.specificationBefore,
material: item.materialBefore,
itemName: item.materialNameBefore,
surfaceTreatmentDesc: item.surfaceTreatmentBefore,
zincLayer: item.zincLayerBefore
},
// 将三个after字段设置为与before相同
itemIdAfter: item.itemIdBefore,
warehouseIdAfter: item.warehouseIdBefore,
materialTypeAfter: item.materialTypeBefore,
isConfirmed: false
}
}
});
}
},
immediate: true
}
},
methods: {
// 获取库区列表
getWarehouseList() {
listWarehouse().then(res => {
this.warehouseList = res.data
})
},
// 是否是已调拨状态
isConfirmed(item) {
// 只有三个after字段有值才认为是已调拨状态
return item && item.itemIdAfter && item.warehouseIdAfter && item.materialTypeAfter
},
// 确认调拨
handleConfirm(item) {
this.buttonLoading = true
confirmTransferOrderItem(item).then(res => {
if (res.code === 200) {
this.$message({
message: '确认调拨成功',
type: 'success'
})
// 刷新数据
this.$emit('refreshData')
}
}).finally(() => {
this.buttonLoading = false
})
},
// 取消调拨
handleCancel(item) {
this.$confirm('确认取消调拨吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.buttonLoading = true
cancelTransferOrderItem(item.orderItemId).then(res => {
if (res.code === 200) {
this.$message({
message: '取消调拨成功',
type: 'success'
})
// 刷新数据
this.$emit('refreshData')
}
}).finally(() => {
this.buttonLoading = false
})
})
},
handleMaterialChange(row) {
// 如果修改后是产品,说明切换前是原料
const itemType = row.materialTypeAfter == '1' ? 'product' : 'raw_material'
this.materialLoading = true
matchOrCreateMaterial({
itemType,
itemId: row.itemIdAfter
}).then(res => {
row.itemIdAfter = res.data
this.materialLoading = false
}).catch(() => {
this.materialLoading = false
})
}
}
}
</script>