plm前端
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

<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>