|
|
<script>import { selectTestSoBom, saveTestSoBom, removeTestSoBom, updateTestSoBom, removeBatchTestSoBom} from "../../../../api/test/testSoBom";import {updateMaterialTotalAmount} from "../../../../api/test/testInformation";import {searchPart, searchPartList} from '@/api/part/partInformation.js';import numberInput from "../../common/numberInput.vue";import {searchAllUmInformationList} from "../../../../api/part/umInformation";import {Decimal} from "decimal.js";import {queryPart, queryPartUnitCostList} from "../../../../api/part/partInformation";export default { name: "testTable", components:{ numberInput, }, props:{ dataList:{ type: Array, default: ()=>[], }, testNo:{ type:String, }, testNumber:{ type:[String,Number], }, columnList:{ type: Array, default: ()=>[], }, height:{ type:[Number,String], default:300 }, disabled:{ type:Boolean, default:false }, }, model:{ prop:"dataList", event:"change" }, data(){ return{ partList:[], partData:{ partNo:undefined, partDesc:undefined, ifsPartNo:undefined, site:this.$store.state.user.site }, partDialogFlag:false, testSoBomLabel:{ componentPartNo: "物料编码", partDesc:"物料名称", requiredQty:"需求数量", assemblyQty:"单位用量", fixedScrapQty:"固定损耗", scrapFactor:"报废率" }, testSoBomRule:{ componentPartNo: [{required: true,message: ' ',trigger: ['change','blur']}], partDesc: [{required: true,message: ' ',trigger: ['change','blur']}], requiredQty: [{required: true,message: ' ',trigger: ['change','blur']}], assemblyQty: [{required: true,message: ' ',trigger: ['change','blur']}], fixedScrapQty: [{required: true,message: ' ',trigger: ['change','blur']}], scrapFactor: [{required: true,message: ' ',trigger: ['change','blur']}], unitCost: [{required: true,message: ' ',trigger: ['change','blur']}], totalCost: [{required: true,message: ' ',trigger: ['change','blur']}], }, testSoBom:{ site:this.$store.state.user.site, testNo:undefined, itemNo:undefined, componentPartNo:undefined, partDesc:undefined, umId:undefined, assemblyQty:0, fixedScrapQty:0, scrapFactor:0, requiredQty:0, issuedQty:undefined, issuedDate:undefined, reserveQty:0, mateGroup:undefined, notifiedQty:undefined, rmTypeDb:0, issuedType:undefined, remark:undefined, unitCost:0, totalCost:0, status:"N", }, selectionTestSoBomList:[], testSoBomColumnList:[{ userId: this.$store.state.user.name, functionId: 102001, serialNumber: '102001Table3ItemNo', tableId: '102001Table3', tableName: '测试物料结构', columnProp: 'itemNo', 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: 102001, serialNumber: '102001Table3ComponentPartNo', tableId: '102001Table3', tableName: '测试物料结构', columnProp: 'plmPartNo', headerAlign: 'center', align: 'left', columnLabel: 'PLM物料编码', columnHidden: false, columnImage: false, columnSortable: false, sortLv: 0, status: true, fixed: '', columnWidth: 100 }, { userId: this.$store.state.user.name, functionId: 102001, serialNumber: '102001Table3ComponentPartNo', tableId: '102001Table3', tableName: '测试物料结构', columnProp: 'ifsPartNo', headerAlign: 'center', align: 'left', columnLabel: 'IFS物料编码', columnHidden: false, columnImage: false, columnSortable: false, sortLv: 0, status: true, fixed: '', columnWidth: 100 }, { userId: this.$store.state.user.name, functionId: 102001, serialNumber: '102001Table3PartDesc', tableId: '102001Table3', tableName: '测试物料结构', columnProp: 'partDesc', headerAlign: 'center', align: 'left', columnLabel: '物料名称', columnHidden: false, columnImage: false, columnSortable: false, sortLv: 0, status: true, fixed: '', columnWidth: 200 },{ userId: this.$store.state.user.name, functionId: 102001, serialNumber: '102001Table3Spec', tableId: '102001Table3', tableName: '测试物料结构', columnProp: 'spec', headerAlign: 'center', align: 'left', columnLabel: '规格型号', columnHidden: false, columnImage: false, columnSortable: false, sortLv: 0, status: true, fixed: '', columnWidth: 100 }, // {
// userId: this.$store.state.user.name,
// functionId: 102001,
// serialNumber: '102001Table3AssemblyQty',
// tableId: '102001Table3',
// tableName: '测试物料结构',
// columnProp: 'assemblyQty',
// headerAlign: 'center',
// align: 'left',
// columnLabel: '单位用量',
// columnHidden: false,
// columnImage: false,
// columnSortable: false,
// sortLv: 0,
// status: true,
// fixed: '',
// columnWidth: 100
// },
// {
// userId: this.$store.state.user.name,
// functionId: 102001,
// serialNumber: '102001Table3FixedScrapQty',
// tableId: '102001Table3',
// tableName: '测试物料结构',
// columnProp: 'fixedScrapQty',
// headerAlign: 'center',
// align: 'left',
// columnLabel: '固定损耗',
// columnHidden: false,
// columnImage: false,
// columnSortable: false,
// sortLv: 0,
// status: true,
// fixed: '',
// columnWidth: 100
// },
{ userId: this.$store.state.user.name, functionId: 102001, serialNumber: '102001Table3UmName', tableId: '102001Table3', tableName: '测试物料结构', columnProp: 'umId', headerAlign: 'center', align: 'left', columnLabel: '计量单位', columnHidden: false, columnImage: false, columnSortable: false, sortLv: 0, status: true, fixed: '', columnWidth: 100 }, // {
// userId: this.$store.state.user.name,
// functionId: 102001,
// serialNumber: '102001Table3ScrapFactor',
// tableId: '102001Table3',
// tableName: '测试物料结构',
// columnProp: 'scrapFactor',
// headerAlign: 'center',
// align: 'left',
// columnLabel: '报废率%',
// columnHidden: false,
// columnImage: false,
// columnSortable: false,
// sortLv: 0,
// status: true,
// fixed: '',
// columnWidth: 100
// },
{ userId: this.$store.state.user.name, functionId: 102001, serialNumber: '102001Table3RequiredQty', tableId: '102001Table3', tableName: '测试物料结构', columnProp: 'requiredQty', headerAlign: 'center', align: 'right', columnLabel: '需求数量', columnHidden: false, columnImage: false, columnSortable: false, sortLv: 0, status: true, fixed: '', columnWidth: 100 }, // {
// userId: this.$store.state.user.name,
// functionId: 102001,
// serialNumber: '102001Table3ReserveQty',
// tableId: '102001Table3',
// tableName: '测试物料结构',
// columnProp: 'reserveQty',
// headerAlign: 'center',
// align: 'left',
// columnLabel: '预留数量',
// columnHidden: false,
// columnImage: false,
// columnSortable: false,
// sortLv: 0,
// status: true,
// fixed: '',
// columnWidth: 100
// },
// {
// userId: this.$store.state.user.name,
// functionId: 102001,
// serialNumber: '102001Table3IssuedDate',
// tableId: '102001Table3',
// tableName: '测试物料结构',
// columnProp: 'issuedDate',
// headerAlign: 'center',
// align: 'left',
// columnLabel: '发料日期',
// columnHidden: false,
// columnImage: false,
// columnSortable: false,
// sortLv: 0,
// status: true,
// fixed: '',
// columnWidth: 100
// },
{ userId: this.$store.state.user.name, functionId: 102001, serialNumber: '102001Table3UnitCost', tableId: '102001Table3', tableName: '测试物料结构', columnProp: 'unitCost', headerAlign: 'center', align: 'right', columnLabel: '单价', columnHidden: false, columnImage: false, columnSortable: false, sortLv: 0, status: true, fixed: '', columnWidth: 100 }, { userId: this.$store.state.user.name, functionId: 102001, serialNumber: '102001Table3TotalCost', tableId: '102001Table3', tableName: '测试物料结构', columnProp: 'totalCost', headerAlign: 'center', align: 'right', columnLabel: '总价', columnHidden: false, columnImage: false, columnSortable: false, sortLv: 0, status: true, fixed: '', columnWidth: 100 }, { userId: this.$store.state.user.name, functionId: 102001, serialNumber: '102001Table3Remark', tableId: '102001Table3', tableName: '测试物料结构', columnProp: 'remark', 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: 102001,
// serialNumber: '102001Table3rmTypeDb',
// tableId: '102001Table3',
// tableName: '测试物料结构',
// columnProp: 'rmTypeDb',
// headerAlign: 'center',
// align: 'left',
// columnLabel: '是否主物料',
// columnHidden: false,
// columnImage: false,
// columnSortable: false,
// sortLv: 0,
// status: true,
// fixed: '',
// columnWidth: 100
// },
], saveOrUpdateFlag:false, umList:[],
no:1, size:20, total:0, queryLoading:false } }, created() { if (this.columnList.length !== 0){ this.testSoBomColumnList = [...this.columnList] } }, methods:{ closePartDialog(){ this.partData = { partNo: undefined, partDesc: undefined, ifsPartNo:'', site:this.$store.state.user.site } this.partList = []; }, openPartDialog(){ this.partDialogFlag = true; this.partData.partNo = this.testSoBom.componentPartNo this.initPartList(); }, initPartList(){ let params = { ...this.partData, no:this.no, size:this.size, } this.queryLoading = true searchPartList(params).then(({data})=>{ if (data && data.code === 0) { this.partList = data.data; this.total = data.total } this.queryLoading = false }).catch(()=>{ this.queryLoading = false }) }, dblClickPartTable(row){ if (row.status === 'Y'){ let params = { site:row.site, partNo:row.partNo, configurationId:row.configurationId, userName: this.$store.state.user.name } this.queryLoading = true queryPartUnitCostList(params).then(({data}) => { if (data && data.code === 0) { this.testSoBom.componentPartNo = row.partNo; this.testSoBom.partDesc = row.partDesc; this.testSoBom.umId = row.umId; this.testSoBom.unitCost = (data.rows && data.rows.length === 1)?data.rows[0].inventoryValue:0; this.testSoBom.status = row.status; this.partDialogFlag = false; this.queryLoading = false }else { this.$message.warning(data.msg); this.queryLoading = false } }).catch((error)=>{ this.$message.error(error) this.queryLoading = false }) }else { this.testSoBom.componentPartNo = row.partNo; this.testSoBom.partDesc = row.partDesc; this.testSoBom.umId = row.umId; this.testSoBom.status = row.status; this.testSoBom.unitCost = row.standardCost; this.partDialogFlag = false; } }, testSoBomClickRow(row,column){ if (column.label !== '操作'){ this.$refs.testSoBomTable.toggleRowSelection(row,true) } }, selectionTestSoBom(rows){ this.selectionTestSoBomList = rows; }, saveTestSoBom(row){ if (row){ this.testSoBom = JSON.parse(JSON.stringify(row)) } this.getAllUm() this.saveOrUpdateFlag = true }, removeBatchTestSoBom(){ if (this.selectionTestSoBomList.length === 0){ this.$message.warning("请勾选需要删除的信息") return } this.$confirm('此操作将删除材料信息, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { removeBatchTestSoBom(this.selectionTestSoBomList).then(({data})=>{ if (data && data.code === 0){ this.$message.success(data.msg) this.selectTestSoBom(); this.$refs.testSoBomTable.clearSelection() }else { this.$alert(data.msg, '错误', { confirmButtonText: '确定' }) } }).catch((error)=>{ this.$alert(error, '错误', { confirmButtonText: '确定' }) }) }).catch(() => {}); }, closeTestSoBom(){ this.$refs.saveForm.resetFields(); this.testSoBom = { site:this.$store.state.user.site, testNo:undefined, itemNo:undefined, componentPartNo:undefined, partDesc:undefined, umId:undefined, assemblyQty:0, fixedScrapQty:0, scrapFactor:0, requiredQty:0, issuedQty:undefined, issuedDate:undefined, reserveQty:0, mateGroup:undefined, notifiedQty:undefined, rmTypeDb:0, issuedType:undefined, remark:undefined, unitCost:0, totalCost:0, } }, clearTable(){ this.$emit("change",[]) this.$refs.testSoBomTable.clearSelection(); }, selectTestSoBom(){ let params = { testNo:this.testNo, site:this.$store.state.user.site } this.$emit("change",[]) this.$refs.testSoBomTable.clearSelection(); selectTestSoBom(params).then(({data})=>{ if (data && data.code === 0 ){ this.$emit("change",data.rows) this.restSoBom(); // 数据加载完成后,更新材料总金额
this.$nextTick(() => { this.updateTestMaterialTotalAmount() }) }else { this.$message.error(data.msg) } }).catch((error)=>{ this.$message.error(error) }) }, saveTestSoBomBtn(isClose){ this.$refs.saveForm.validate((validate,objects)=>{ if (validate){ if (this.testSoBom.itemNo !== undefined && this.testSoBom.itemNo !== null && this.testSoBom.itemNo !== ''){ updateTestSoBom(this.testSoBom).then(({data})=>{ if (data && data.code === 0){ this.$message.success(data.msg) this.selectTestSoBom() this.saveOrUpdateFlag = false }else { this.$message.error(data.msg) } }).catch((error)=>{ this.$message.error(error) }) }else { this.testSoBom.testNo = this.testNo saveTestSoBom(this.testSoBom).then(({data})=>{ if (data && data.code === 0){ this.$message.success(data.msg) this.selectTestSoBom() if (!isClose){ this.saveOrUpdateFlag = false } }else { this.$message.error(data.msg) } }).catch((error)=>{ this.$message.error(error) }) } }else { for (let key in objects) { this.$message.error(this.testSoBomLabel[key]+"不能为空") } } }) }, restSoBom(){ this.$nextTick(()=>{ this.testSoBom= { site:this.$store.state.user.site, testNo:this.testNo, itemNo:undefined, componentPartNo:undefined, partDesc:undefined, umId:undefined, assemblyQty:0, fixedScrapQty:0, scrapFactor:0, requiredQty:0, issuedQty:undefined, issuedDate:undefined, reserveQty:0, mateGroup:undefined, notifiedQty:undefined, rmTypeDb:0, issuedType:undefined, remark:undefined, } }) }, getAllUm(){ let params = { site:this.$store.state.user.site } searchAllUmInformationList(params).then(({data})=>{ if (data && data.code === 0){ this.umList = data.rows }else { this.$message.warning(data.msg) } }).catch((error)=>{ this.$message.error(error) }) }, computeQuantityRequired(){ let total = new Decimal(this.testNumber).mul(new Decimal(this.testSoBom.assemblyQty)).div((new Decimal(100).sub(new Decimal(this.testSoBom.scrapFactor))).div(new Decimal(100))) this.testSoBom.requiredQty = new Decimal(total.toFixed(3,Decimal.ROUND_FLOOR)).toSignificantDigits().toNumber(); }, computeTotalCost(val){ this.testSoBom.assemblyQty = new Decimal(this.testSoBom.requiredQty).div(new Decimal(this.testNumber)).toNumber() this.testSoBom.totalCost = new Decimal(this.testSoBom.requiredQty).mul(new Decimal(this.testSoBom.unitCost)).toNumber() }, handleQueryPart(){ let params = { site:this.$store.state.user.site, partNo:this.testSoBom.componentPartNo } queryPart(params).then(({data})=>{ if (data && data.code === 0){ if (data.rows && data.rows.length === 1){ this.dblClickPartTable(data.rows[0]) }else { this.dblClickPartTable({ site:this.$store.state.user.site, partNo:this.testSoBom.componentPartNo, }) } }else { this.$message.warning(data.msg) } }).catch((error)=>{ this.$message.error(error) }) }, handleSizeChange(val){ this.size = val this.initPartList() }, handleCurrentChange(val){ this.no = val this.initPartList() }, // 更新测试主信息的材料总金额
updateTestMaterialTotalAmount(){ if (!this.testNo) { return } // 计算当前所有材料的总金额
const totalAmount = this.dataList.reduce((sum, item) => { return sum + (Number(item.totalCost) || 0) }, 0) const params = { testNo: this.testNo, materialTotalAmount: totalAmount } updateMaterialTotalAmount(params).then(({data}) => { if (data && data.code === 0) { // 更新成功,通知父组件刷新主信息
console.log('材料总金额更新成功:', totalAmount) this.$emit('refresh-test-info') } }).catch((error) => { console.error('更新材料总金额失败', error) }) } },
watch:{ partDialogFlag(newVal,oldVal){ if (newVal === false){ this.no = 1; this.size = 20; this.total = 0; this.closePartDialog(); } }, // queryLoading(newVal,oldVal){
// if (newVal){
// setTimeout(()=>{
// this.queryLoading = false
// },5000)
// }
// }
}
}</script>
<template> <div class="testTable"> <div style="margin-bottom: 5px"> <template v-if="isAuth('107001:tab3:save')"> <el-button type="primary" v-if="!disabled" @click="saveTestSoBom(null)">新增</el-button> </template> <template v-if="isAuth('107001:tab3:remove')"> <el-button type="primary" v-if="!disabled" @click="removeBatchTestSoBom">删除</el-button> </template> </div> <el-table :height="height" border :data="dataList" ref="testSoBomTable" @row-click="testSoBomClickRow" @selection-change="selectionTestSoBom"> <el-table-column type="selection" header-align="center" align="center" width="50"> </el-table-column> <el-table-column v-for="(item,index) in testSoBomColumnList" :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-column label="操作" align="center" fixed="right"> <template slot-scope="{row,$index}"> <template v-if="isAuth('107001:tab3:update')"> <a type="text" style="cursor:pointer;" v-if="!disabled" @click="saveTestSoBom(row)">编辑</a> </template> </template> </el-table-column> </el-table>
<el-dialog :title="(testSoBom.itemNo?'编辑':'新增')+'-物料结构'" :close-on-click-modal="false" v-drag width="600px" append-to-body :visible.sync="saveOrUpdateFlag" @close="closeTestSoBom"> <el-form ref="saveForm" label-position="top" :model="testSoBom" :rules="testSoBomRule"> <el-row :gutter="15"> <el-col :span="24"> <el-row :gutter="15"> <el-col :span="8"> <el-form-item label="物料编码" prop="componentPartNo"> <span slot="label" @click="openPartDialog"><a>物料编码</a></span> <el-input @blur="handleQueryPart" v-model="testSoBom.componentPartNo"></el-input> </el-form-item> </el-col> <el-col :span="11"> <el-form-item label="物料名称" prop="partDesc"> <el-input disabled v-model="testSoBom.partDesc"></el-input> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="单位" prop="umId"> <el-select disabled v-model="testSoBom.umId" placeholder=" "> <el-option v-for="v in umList" :value="v.umId" :label="v.umId" :key="v.umId"></el-option> </el-select> </el-form-item> </el-col> </el-row> </el-col> <el-col :span="8"> <el-form-item label="需求数量" prop="requiredQty"> <el-input-number @input="computeTotalCost" style="width: 100%;margin-top: -5px;" :min="0" v-model="testSoBom.requiredQty" :controls="false"></el-input-number> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="单价" prop="unitCost"> <el-input-number @input="computeTotalCost" :disabled="testSoBom.status === 'N'" style="width: 100%;margin-top: -5px;" :min="0" v-model="testSoBom.unitCost" :controls="false"></el-input-number> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="总价" prop="totalCost"> <el-input-number disabled style="width: 100%;margin-top: -5px;" :min="0" v-model="testSoBom.totalCost" :controls="false"></el-input-number> </el-form-item> </el-col> <el-col :span="24"> <el-form-item label="备注" prop="remark" style="height: 90px"> <el-input type="textarea" resize='none' :autosize="{ minRows: 3, maxRows: 3 }" v-model="testSoBom.remark"></el-input> </el-form-item> </el-col> </el-row> </el-form> <span slot="footer" class="dialog-footer"> <el-button type="primary" v-if="!testSoBom.itemNo" @click="saveTestSoBomBtn(true)">保 存</el-button> <el-button type="primary" @click="saveTestSoBomBtn(false)">保存并关闭</el-button> <el-button @click="saveOrUpdateFlag = false">取 消</el-button> </span> </el-dialog>
<el-dialog title="物料信息" width="800px" append-to-body :close-on-click-modal="false" v-drag :visible.sync="partDialogFlag"> <!--搜索条件--> <el-form :model="partData" ref="partDataForm" style="width: 600px;" label-position="top"> <el-row :gutter="10"> <el-col :span="6"> <el-form-item label="物料编号" prop="partNo"> <el-input v-model="partData.partNo" clearable/> </el-form-item> </el-col> <el-col :span="6" > <el-form-item label="物料名称" prop="partDesc"> <el-input v-model="partData.partDesc" clearable/> </el-form-item> </el-col> <el-col :span="6" > <el-form-item label="IFS物料编码" prop="ifsPartNo"> <el-input v-model="partData.ifsPartNo" clearable/> </el-form-item> </el-col> <el-col :span="6" > <el-form-item label=" "> <el-button type="primary" @click="initPartList">查 询</el-button> </el-form-item> </el-col> </el-row> </el-form> <!--筛选的数据--> <el-table :data="partList" v-loading="queryLoading" ref="partDataTable" :style="{marginTop:'5px'}" height="200px" width="100%" stripe border @row-dblclick="dblClickPartTable"> <el-table-column label="物料编号" prop="partNo" header-align="center" align="left" min-width="100"/> <el-table-column label="物料名称" prop="partDesc" header-align="center" align="left" min-width="160"/> <el-table-column label="单位" prop="umId" header-align="center" align="center" min-width="60"/> <el-table-column label="IFS物料编码" prop="ifsPartNo" header-align="center" align="left" min-width="100"/> </el-table>
<!--分页--> <div style="margin-top: 10px;text-align: right;"> <el-pagination style="margin-top: 0;" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="no" :page-sizes="[20, 50, 100, 200, 500]" :page-size="size" :total="total" layout="total, sizes, prev, pager, next, jumper"> </el-pagination> </div> </el-dialog> </div></template>
<style scoped> .el-input-number /deep/ .el-input__inner{ text-align: right; padding-right: 5px !important; }</style>
|