You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
597 lines
20 KiB
597 lines
20 KiB
<script>
|
|
import {
|
|
getBomTreeStructure, searchQuoteBOMAllCost, searchQuoteBOMAlternativeNo,
|
|
searchQuoteBomList,
|
|
searchQuoteBOMVersion,
|
|
updateQuoteBomList
|
|
} from '../../../../../api/quotation/quoteOfBom'
|
|
import {Decimal} from "decimal.js";
|
|
import fi from "element-ui/src/locale/lang/fi";
|
|
export default {
|
|
name:'billOfMateriel',
|
|
props:{
|
|
detail:{
|
|
type:Object,
|
|
request:true,
|
|
},
|
|
height:{
|
|
type:Number,
|
|
default:400,
|
|
},
|
|
updateTree:{
|
|
type:Number,
|
|
default: 0,
|
|
},
|
|
loadingStatus:{
|
|
type:Boolean,
|
|
default:false,
|
|
},
|
|
totalCost:{
|
|
type:Number,
|
|
default:-1,
|
|
},
|
|
allSearchFlag:{
|
|
type:Boolean,
|
|
default:false,
|
|
},
|
|
},
|
|
computed:{
|
|
BOMAllSearchFlag:{
|
|
get(){
|
|
return this.allSearchFlag;
|
|
},
|
|
set(val){
|
|
this.$emit("update:allSearchFlag",val)
|
|
}
|
|
}
|
|
},
|
|
watch:{
|
|
BOMAllSearchFlag(newVal,oldVal){
|
|
if (newVal === true){
|
|
this.$nextTick(()=>{
|
|
this.$refs.tree.setCurrentKey(`${this.selectBom[0]}-${this.selectBom[1]}-${this.selectBom[2]}-${this.selectBom[3]}-${this.selectBom[4]}-${this.selectBom[5]}`)
|
|
})
|
|
}
|
|
this.searchQuoteBomList()
|
|
}
|
|
},
|
|
data(){
|
|
return{
|
|
BomVersion:{},
|
|
BOMVersionList:[],
|
|
handoffVersion:false,
|
|
treeLoading:false,
|
|
bomTreeStructure:[],
|
|
bomProps:{
|
|
label:'label',
|
|
value:'value',
|
|
children:'list'
|
|
},
|
|
dataListLoading:false,
|
|
bomDetailList:[],
|
|
selectBom:[],
|
|
copyBom:[],
|
|
columnDetailList:[
|
|
{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4LineSequence',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'lineSequence',
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: '序号',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 50,
|
|
},{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4PartNo',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'partNo',
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: '产品编码',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 120,
|
|
},{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4ComponentPart',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'componentPart',
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: '零部件编码',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 120,
|
|
},{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4ComponentPartDesc',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'componentPartDesc',
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: '物料名称',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 140,
|
|
},{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4QtyPerAssembly',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'qtyPerAssembly',
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: '单位用量',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 90,
|
|
},{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4ComponentScrap',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'componentScrap',
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: '调机用量',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 90,
|
|
},{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4ShrinkageFactor',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'shrinkageFactor',
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: '损耗率%',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 90,
|
|
},{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4PrintUnitName',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'printUnit',
|
|
headerAlign: "center",
|
|
align: "center",
|
|
columnLabel: '单位',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 90,
|
|
},{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4NoteText',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'noteText',
|
|
headerAlign: "center",
|
|
align: "left",
|
|
columnLabel: '备注',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 90,
|
|
},{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4UnitCost',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'unitCost',
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: '单位成本',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: '',
|
|
columnWidth: 90,
|
|
},{
|
|
userId: this.$store.state.user.name,
|
|
functionId: 102003,
|
|
serialNumber: '102003Table4QuoteUnitCost',
|
|
tableId: "102003Table4",
|
|
tableName: "报价材料信息",
|
|
columnProp: 'quoteUnitCost',
|
|
headerAlign: "center",
|
|
align: "right",
|
|
columnLabel: '单位报价成本',
|
|
columnHidden: false,
|
|
columnImage: false,
|
|
columnSortable: false,
|
|
sortLv: 0,
|
|
status: true,
|
|
fixed: 'right',
|
|
columnWidth: 90,
|
|
},
|
|
],
|
|
versionData:{},
|
|
BOMAlternativeList:[],
|
|
}
|
|
},
|
|
methods:{
|
|
getInventoryPartBom(){
|
|
// 请求后端 获得树结构菜单
|
|
let params = {
|
|
site:this.detail.site,
|
|
partId:0,
|
|
quoteDetailId:this.detail.quotationDetailId
|
|
}
|
|
this.treeLoading = true
|
|
getBomTreeStructure(params).then(({data})=>{
|
|
if (data && data.code === 0){
|
|
this.bomTreeStructure = data.rows;
|
|
this.$nextTick(()=>{
|
|
this.$refs.tree.setCurrentKey(`${this.selectBom[0]}-${this.selectBom[1]}-${this.selectBom[2]}-${this.selectBom[3]}-${this.selectBom[4]}-${this.selectBom[5]}`)
|
|
})
|
|
this.searchQuoteBomList();
|
|
}else {
|
|
this.$message.warning(data.msg)
|
|
}
|
|
this.treeLoading = false;
|
|
// this.$emit("update:loadingStatus",this.treeLoading)
|
|
}).catch((error)=>{
|
|
this.$message.error(error)
|
|
this.treeLoading = false;
|
|
// this.$emit("update:loadingStatus",this.treeLoading)
|
|
})
|
|
},
|
|
changeSelect(val){
|
|
if (this.selectBom.length === 0){
|
|
this.updateQuoteBomList();
|
|
return
|
|
}
|
|
this.$confirm('此操作将更换材料信息, 是否继续?', '提示', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
this.updateQuoteBomList();
|
|
}).catch(() => {
|
|
this.selectBom = JSON.parse(JSON.stringify(this.copyBom))
|
|
this.$nextTick(()=>{
|
|
this.$refs.tree.setCurrentKey(`${this.selectBom[0]}-${this.selectBom[1]}-${this.selectBom[2]}-${this.selectBom[3]}-${this.selectBom[4]}-${this.selectBom[5]}`)
|
|
})
|
|
});
|
|
},
|
|
updateQuoteBomList(){
|
|
let params = {
|
|
site:this.$store.state.user.site,
|
|
testPartNo: this.detail.productNo,
|
|
version:this.selectBom[0],
|
|
bomType:this.selectBom[2],
|
|
alternativeNo:this.selectBom[1],
|
|
quoteDetailId:this.detail.quotationDetailId
|
|
}
|
|
updateQuoteBomList(params).then(({data})=>{
|
|
if (data && data.code === 0){
|
|
this.$message.success(data.msg)
|
|
this.searchQuoteBomList();
|
|
}else {
|
|
this.$message.warning(data.msg)
|
|
}
|
|
}).catch((error)=>{
|
|
this.$message.error(error)
|
|
})
|
|
},
|
|
setSelectBom(val){
|
|
if (val.length === 0){
|
|
this.getInventoryPartBom();
|
|
return
|
|
}
|
|
this.selectBom = val
|
|
this.getInventoryPartBom();
|
|
},
|
|
searchQuoteBomList(){
|
|
let params = {
|
|
site:this.$store.state.user.site,
|
|
partNo: this.selectBom[3],
|
|
version:this.selectBom[0],
|
|
bomType:this.selectBom[2],
|
|
alternativeNo:this.selectBom[1],
|
|
id:this.selectBom[4],
|
|
quoteDetailId:this.detail.quotationDetailId
|
|
}
|
|
this.searchQuoteBomListPost(params)
|
|
},
|
|
searchQuoteBomListPost(params){
|
|
this.dataListLoading = true;
|
|
if (this.BOMAllSearchFlag){
|
|
searchQuoteBomList(params).then(({data})=>{
|
|
if (data && data.code === 0){
|
|
this.bomDetailList = data.rows
|
|
this.computedQuoteBomCost();
|
|
}else {
|
|
this.$message.warning(data.msg)
|
|
}
|
|
this.dataListLoading = false;
|
|
// this.$emit("update:loadingStatus",this.dataListLoading)
|
|
}).catch((error)=>{
|
|
this.dataListLoading = false;
|
|
// this.$emit("update:loadingStatus",this.dataListLoading)
|
|
this.$message.error(error)
|
|
})
|
|
}else {
|
|
// this.dataListLoading = false;
|
|
searchQuoteBOMAllCost(params).then(({data})=>{
|
|
if (data && data.code === 0){
|
|
this.bomDetailList = data.rows
|
|
this.computedQuoteBomCost();
|
|
}else {
|
|
this.$message.warning(data.msg)
|
|
}
|
|
this.dataListLoading = false;
|
|
// this.$emit("update:loadingStatus",this.dataListLoading)
|
|
}).catch((error)=>{
|
|
this.$message.error(error)
|
|
this.dataListLoading = false;
|
|
// this.$emit("update:loadingStatus",this.dataListLoading)
|
|
})
|
|
}
|
|
},
|
|
computedQuoteBomCost(){
|
|
this.$emit("update:loadingStatus",true)
|
|
for (let i = 0; i < this.bomDetailList.length; i++) {
|
|
let bomDetail = this.bomDetailList[i]
|
|
// 单位成本
|
|
let unitCost = new Decimal(bomDetail.unitCost);
|
|
// 调机用量
|
|
let componentScrap = new Decimal(bomDetail.componentScrap)
|
|
// 单位用量
|
|
let qtyPerAssembly = new Decimal(bomDetail.qtyPerAssembly)
|
|
// 损耗率
|
|
let shrinkageFactor = new Decimal(bomDetail.shrinkageFactor)
|
|
// 报价数量
|
|
let num = new Decimal(this.detail.quotationDetailQuantity)
|
|
let needNum = componentScrap.div(num).add(qtyPerAssembly.div(new Decimal(100).sub(shrinkageFactor).div(new Decimal(100))))
|
|
bomDetail.quoteUnitCost = new Decimal(needNum.mul(unitCost).toFixed(4,Decimal.ROUND_HALF_UP)).toSignificantDigits().toNumber()
|
|
}
|
|
this.$emit("update:totalCost",this.getQuoteBomCost())
|
|
// this.$emit("update:loadingStatus",false)
|
|
},
|
|
getQuoteBomCost(){
|
|
// this.searchQuoteBomList();
|
|
return this.bomDetailList.reduce((total, currentValue) => {
|
|
return total + new Decimal(currentValue.quoteUnitCost).toNumber();
|
|
}, 0)
|
|
},
|
|
nodeClick(val){
|
|
this.selectBom = val.value.split("-")
|
|
this.bomDetailList=[];
|
|
this.$nextTick(()=>{
|
|
this.$refs.tree.setCurrentKey(`${this.selectBom[0]}-${this.selectBom[1]}-${this.selectBom[2]}-${this.selectBom[3]}-${this.selectBom[4]}-${this.selectBom[5]}`)
|
|
})
|
|
this.searchQuoteBomList()
|
|
},
|
|
clickVersionCheck(){
|
|
this.handoffVersion = true;
|
|
this.BOMVersionList = [];
|
|
this.versionData = {
|
|
site:this.detail.site,
|
|
partNo:this.selectBom[3],
|
|
version:this.selectBom[0],
|
|
bomType:this.selectBom[2]
|
|
}
|
|
this.searchQuoteBOMVersion();
|
|
},
|
|
searchQuoteBOMVersion(){
|
|
let params = {
|
|
site:this.detail.site,
|
|
quoteDetailId:this.detail.quotationDetailId,
|
|
testPartNo:this.selectBom[3],
|
|
}
|
|
this.BOMVersionList = [];
|
|
searchQuoteBOMVersion(params).then(({data})=>{
|
|
if (data && data.code === 0){
|
|
this.BOMVersionList = data.rows;
|
|
this.selectionVersion();
|
|
// 查询替代
|
|
this.searchBOMAlternative(this.versionData);
|
|
}else {
|
|
this.$message.warning(data.msg)
|
|
}
|
|
}).catch((error)=>{
|
|
this.$message.error(error)
|
|
})
|
|
},
|
|
clickVersion(row){
|
|
this.BomVersion = JSON.parse(JSON.stringify(row));
|
|
},
|
|
searchBOMAlternative(row){
|
|
this.BOMAlternativeList = [];
|
|
searchQuoteBOMAlternativeNo(row).then(({data})=>{
|
|
if (data && data.code === 0){
|
|
this.BOMAlternativeList = data.rows;
|
|
}else {
|
|
this.$message.warning(data.msg)
|
|
}
|
|
}).catch((error)=>{
|
|
this.$message.error(error)
|
|
})
|
|
},
|
|
alternativeRowStyle({row}){
|
|
if (row.version === parseInt(this.selectBom[0]) && row.bomType === this.selectBom[2] && row.alternativeNo === this.selectBom[1]){
|
|
return {'background-color': '#E8F7F6', cursor: 'pointer'}
|
|
}
|
|
},
|
|
versionRowStyle({row}){
|
|
if (row.version === parseInt(this.versionData.version) && row.bomType === this.versionData.bomType){
|
|
return {'background-color': '#E8F7F6', cursor: 'pointer'}
|
|
}
|
|
},
|
|
selectionVersion(){
|
|
for (let i = 0; i < this.BOMVersionList.length; i++) {
|
|
let BOMVersion = this.BOMVersionList[i]
|
|
if (BOMVersion.version === this.versionData.version && BOMVersion.bomType === this.versionData.bomType){
|
|
this.versionData = BOMVersion;
|
|
return
|
|
}
|
|
}
|
|
},
|
|
clickVersionTable(row){
|
|
this.versionData = row;
|
|
this.searchBOMAlternative(row)
|
|
},
|
|
clickAlternative(row){
|
|
let params = {
|
|
site:this.detail.site,
|
|
quoteDetailId:this.detail.quotationDetailId,
|
|
partNo:row.partNo,
|
|
version:row.version,
|
|
bomType:row.bomType,
|
|
id:this.selectBom[4],
|
|
parentId:this.selectBom[5],
|
|
alternativeNo:row.alternativeNo,
|
|
quoteBomDetailList:this.bomDetailList
|
|
}
|
|
updateQuoteBomList(params).then(({data})=>{
|
|
if (data && data.code === 0){
|
|
this.selectBom[0] = row.version;
|
|
this.selectBom[2] = row.bomType;
|
|
this.selectBom[1] = row.alternativeNo;
|
|
this.selectBom[3] = row.partNo;
|
|
this.selectBom[4] = data.row.id;
|
|
this.selectBom[5] = data.row.parentId;
|
|
this.$message.success(data.msg)
|
|
this.getInventoryPartBom();
|
|
this.$emit("update:updateTree",this.updateTree+1)
|
|
this.handoffVersion = false
|
|
}else {
|
|
this.$message.warning(data.msg)
|
|
}
|
|
}).catch((error)=>{
|
|
this.$message.error(error)
|
|
})
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div style="margin-bottom: 5px">
|
|
<el-link style="cursor:pointer;" v-if="this.selectBom.length === 6 && bomTreeStructure.length >= 0" @click="clickVersionCheck">切换版本</el-link>
|
|
<span style="display: inline-block;width: 20px"></span>
|
|
<el-checkbox v-model="BOMAllSearchFlag">全级BOM结构</el-checkbox>
|
|
</div>
|
|
<el-container>
|
|
<el-aside width="24%" style="padding: 0;" :style="{height: height}" v-loading="treeLoading">
|
|
<el-tree :data="bomTreeStructure"
|
|
:props="bomProps"
|
|
@node-click="nodeClick"
|
|
:expand-on-click-node="false"
|
|
node-key="value" style="height: 100%"
|
|
default-expand-all
|
|
:current-node-key="`${selectBom[0]}-${selectBom[1]}-${selectBom[2]}-${selectBom[3]}-${selectBom[4]}-${selectBom[5]}`"
|
|
highlight-current ref="tree"
|
|
></el-tree>
|
|
</el-aside>
|
|
<el-main style="padding: 0">
|
|
<el-table :data="bomDetailList" :height="height"
|
|
stripe border element-loading-text = "数据正在加载中"
|
|
v-loading="dataListLoading">
|
|
<el-table-column
|
|
v-for="(item,index) in columnDetailList" :key="index"
|
|
:sortable="item.columnSortable"
|
|
:prop="item.columnProp"
|
|
:header-align="item.headerAlign"
|
|
:show-overflow-tooltip="item.showOverflowTooltip"
|
|
:align="item.align"
|
|
:fixed="item.fixed===''?false:item.fixed"
|
|
:min-width="item.columnWidth"
|
|
:label="item.columnLabel">
|
|
<template slot-scope="scope">
|
|
<span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
|
|
<span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-main>
|
|
</el-container>
|
|
<el-dialog :visible.sync="handoffVersion" v-drag title="BOM版本切换" @close="()=>{
|
|
this.BOMVersionList = []
|
|
this.BOMAlternativeList = []
|
|
}" append-to-body>
|
|
<el-table :data="BOMVersionList" :row-style="versionRowStyle" ref="BOMVersionTable" style="margin-top: 8px" border :height="240" @row-click="clickVersionTable">
|
|
<el-table-column label="物料编码" prop="partNo" header-align="center" align="center" show-overflow-tooltip min-width="140"/>
|
|
<el-table-column label="物料描述" prop="componentPartDesc" header-align="center" align="left" show-overflow-tooltip min-width="200"/>
|
|
<el-table-column label="版本" prop="version" header-align="center" align="center" show-overflow-tooltip min-width="60"/>
|
|
<el-table-column label="类型" prop="bomType" header-align="center" align="center" show-overflow-tooltip min-width="100"/>
|
|
</el-table>
|
|
|
|
<el-table :data="BOMAlternativeList" :row-style="alternativeRowStyle" border :height="240" style="margin-top: 8px">
|
|
<el-table-column label="物料编码" prop="partNo" header-align="center" align="center" show-overflow-tooltip min-width="140"/>
|
|
<el-table-column label="物料描述" prop="componentPartDesc" header-align="center" align="left" show-overflow-tooltip min-width="200"/>
|
|
<el-table-column label="版本" prop="version" header-align="center" align="center" show-overflow-tooltip min-width="60"/>
|
|
<el-table-column label="替代编码" prop="alternativeNo" header-align="center" align="left" show-overflow-tooltip min-width="60"/>
|
|
<el-table-column label="类型" prop="bomType" header-align="center" align="center" show-overflow-tooltip min-width="100"/>
|
|
<el-table-column label="操作" min-width="80" header-align="center" align="center">
|
|
<template slot-scope="{row,$index}">
|
|
<span style="color: #888;cursor:no-drop;" v-if="row.version === parseInt(selectBom[0]) && row.bomType === selectBom[2] && row.alternativeNo === selectBom[1]">选择</span>
|
|
<el-link style="cursor:pointer;" v-else @click="clickAlternative(row)">选择</el-link>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
|
|
</style>
|