|
|
@@ -0,0 +1,596 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <ele-modal
|
|
|
+ width="80vw"
|
|
|
+ :visible.sync="visible"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ row-key="code"
|
|
|
+ custom-class="ele-dialog-form"
|
|
|
+ :title="'齐套性检查'"
|
|
|
+ :maxable="true"
|
|
|
+ >
|
|
|
+ <div v-loading="loading">
|
|
|
+ <el-form label-width="80px" :model="dataObj" class="order_form">
|
|
|
+ <el-row :gutter="20" type="flex" style="flex-wrap: wrap">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="单据编号:">
|
|
|
+ <el-input readonly v-model="dataObj.code"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="编号:">
|
|
|
+ <el-input readonly v-model="dataObj.productCode"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="名称:">
|
|
|
+ <el-input readonly v-model="dataObj.productName"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="规格:">
|
|
|
+ <el-input readonly v-model="dataObj.specification"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="型号:">
|
|
|
+ <el-input readonly v-model="dataObj.model"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="数量:">
|
|
|
+ <el-input readonly v-model="dataObj.totalCount"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ <div class="form-wrapper">
|
|
|
+ <div
|
|
|
+ class="left_tree"
|
|
|
+ v-show="leftShow"
|
|
|
+ :style="{ width: leftWidth }"
|
|
|
+ >
|
|
|
+ <el-tree
|
|
|
+ ref="treeRef"
|
|
|
+ :expand-on-click-node="false"
|
|
|
+ :data="cardList"
|
|
|
+ :props="treeProps"
|
|
|
+ node-key="id"
|
|
|
+ highlight-current
|
|
|
+ @node-click="handleNodeClick"
|
|
|
+ ></el-tree>
|
|
|
+ </div>
|
|
|
+ <div :style="{ width: rightWidth }">
|
|
|
+ <div>
|
|
|
+ <ele-pro-table
|
|
|
+ ref="table"
|
|
|
+ :needPage="false"
|
|
|
+ :columns="columns"
|
|
|
+ key="checkTable"
|
|
|
+ :init-load="false"
|
|
|
+ :datasource="datasourceList"
|
|
|
+ >
|
|
|
+ <template v-slot:toolkit>
|
|
|
+ <el-form
|
|
|
+ :inline="true"
|
|
|
+ :model="formInline"
|
|
|
+ class="demo-form-inline"
|
|
|
+ >
|
|
|
+ <el-form-item label="BOM类型">
|
|
|
+ <el-select
|
|
|
+ size="mini"
|
|
|
+ v-model="formInline.bomType"
|
|
|
+ placeholder="BOM类型"
|
|
|
+ class="select-type"
|
|
|
+ @change="bomTypeChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in bomListType"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.bomName"
|
|
|
+ :value="item.id"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="BOM版本">
|
|
|
+ <el-select
|
|
|
+ class="select-type"
|
|
|
+ size="mini"
|
|
|
+ v-model="formInline.bomId"
|
|
|
+ placeholder="BOM版本"
|
|
|
+ @change="bomVChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in bomListV"
|
|
|
+ :key="item.bomId"
|
|
|
+ :label="item.versions"
|
|
|
+ :value="item.bomId"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="最终状态">
|
|
|
+ <el-select
|
|
|
+ class="select-type"
|
|
|
+ size="mini"
|
|
|
+ v-model="formInline.finalState"
|
|
|
+ placeholder="最终状态"
|
|
|
+ @change="finalChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in finalStateList"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </template>
|
|
|
+ <template v-slot:inventoryQuantity="{ row }">
|
|
|
+ <el-link
|
|
|
+ type="primary"
|
|
|
+ :underline="false"
|
|
|
+ @click="stockDetail(row)"
|
|
|
+ >
|
|
|
+ {{ row.inventoryQuantity }}
|
|
|
+ </el-link>
|
|
|
+ </template>
|
|
|
+ <template v-slot:inTransitNum="{ row }">
|
|
|
+ <el-link
|
|
|
+ type="primary"
|
|
|
+ :underline="false"
|
|
|
+ @click="currentDetail(row)"
|
|
|
+ >
|
|
|
+ {{ row.inTransitNum }}
|
|
|
+ </el-link>
|
|
|
+ </template>
|
|
|
+ <template v-slot:inventoryStatusText="{ row }">
|
|
|
+ <div
|
|
|
+ :class="
|
|
|
+ row.inventoryStatusText == '缺料'
|
|
|
+ ? 'statusRed'
|
|
|
+ : 'statusGreen'
|
|
|
+ "
|
|
|
+ >
|
|
|
+ {{ row.inventoryStatusText }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-slot:inTransitStatusText="{ row }">
|
|
|
+ <div
|
|
|
+ :class="
|
|
|
+ row.inTransitStatusText == '缺料'
|
|
|
+ ? 'statusRed'
|
|
|
+ : 'statusGreen'
|
|
|
+ "
|
|
|
+ >
|
|
|
+ {{ row.inTransitStatusText }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-slot:finalStateText="{ row }">
|
|
|
+ <div
|
|
|
+ :class="
|
|
|
+ row.finalStateText == '缺料' ? 'statusRed' : 'statusGreen'
|
|
|
+ "
|
|
|
+ >
|
|
|
+ {{ row.finalStateText }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <!-- <template v-slot:stockColor="{ row }">
|
|
|
+ <div :class="{ statusRed: row.stockStatus == '缺料' }">
|
|
|
+ {{ row.stockStatus }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-slot:currentColor="{ row }">
|
|
|
+ <div :class="{ statusRed: row.currentStatus == '缺料' }">
|
|
|
+ {{ row.currentStatus }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-slot:finishColor="{ row }">
|
|
|
+ <div :class="{ statusRed: row.finishStatus == '缺料' }">
|
|
|
+ {{ row.finishStatus }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-slot:finishCount="{ row }">
|
|
|
+ <div>
|
|
|
+ <div v-if="row.finishCount > 0">{{ row.finishCount }}</div>
|
|
|
+ <div v-else>-</div>
|
|
|
+ </div>
|
|
|
+ </template> -->
|
|
|
+ </ele-pro-table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button plain @click="cancel">取消</el-button>
|
|
|
+ <!-- <el-button type="primary" @click="confirm">确定</el-button> -->
|
|
|
+ </div>
|
|
|
+ </ele-modal>
|
|
|
+
|
|
|
+ <stockDetailDialog ref="stockDetailDialog" />
|
|
|
+
|
|
|
+ <currentDetailDialog ref="currentDetailDialog" />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import {
|
|
|
+ findBomSalesorderCategoryId,
|
|
|
+ getMaterialInfo
|
|
|
+ } from '@/api/aps/index.js';
|
|
|
+ import stockDetailDialog from './stockDetailDialog.vue';
|
|
|
+ import currentDetailDialog from './currentDetailDialog.vue';
|
|
|
+
|
|
|
+ export default {
|
|
|
+ components: {
|
|
|
+ stockDetailDialog,
|
|
|
+ currentDetailDialog
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ visible: false,
|
|
|
+ formInline: {
|
|
|
+ finalState: 0
|
|
|
+ },
|
|
|
+ finalStateList: [
|
|
|
+ {
|
|
|
+ label: '全部',
|
|
|
+ value: 0
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '齐套',
|
|
|
+ value: 1
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '缺料',
|
|
|
+ value: 2
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ loading: false,
|
|
|
+ datasourceAllList: [], // 表格物料全部数据
|
|
|
+ datasourceList: [], // 表格物料数据
|
|
|
+ bomListV: [], // BOM版本
|
|
|
+ bomListType: [], // BOM 类型
|
|
|
+ form: {
|
|
|
+ homogeneityInspect: []
|
|
|
+ },
|
|
|
+
|
|
|
+ columns: [
|
|
|
+ {
|
|
|
+ columnKey: 'index',
|
|
|
+ label: '序号',
|
|
|
+ type: 'index',
|
|
|
+ width: 55,
|
|
|
+ align: 'center',
|
|
|
+ fixed: 'left'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ width: 45,
|
|
|
+ type: 'selection',
|
|
|
+ columnKey: 'selection',
|
|
|
+ align: 'center',
|
|
|
+ slot: 'selection',
|
|
|
+ fixed: 'left'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'batchNo',
|
|
|
+ label: '批次号',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 100,
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'productCode',
|
|
|
+ label: '编码',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 100,
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'code',
|
|
|
+ label: '物料编码',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 100,
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'name',
|
|
|
+ label: '物料名称',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 100,
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'demandQuantity',
|
|
|
+ label: '定额数量',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'inventoryQuantity',
|
|
|
+ slot: 'inventoryQuantity',
|
|
|
+ label: '库存数量',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'secureInventory',
|
|
|
+ label: '安全库存',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'lockQuantity',
|
|
|
+ label: '锁库数量',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ slot: 'inventoryStatusText',
|
|
|
+ prop: 'inventoryStatusText',
|
|
|
+ label: '库存状态',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 80
|
|
|
+ },
|
|
|
+ {
|
|
|
+ slot: 'inTransitNum',
|
|
|
+ prop: 'inTransitNum',
|
|
|
+ label: '在途数量',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 80
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'inTransitOrdersNum',
|
|
|
+ label: '在途已关联数量 ',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ slot: 'inTransitStatusText',
|
|
|
+ prop: 'inTransitStatusText',
|
|
|
+ label: '在途状态',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 80
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '最终可用数量',
|
|
|
+ prop: 'finalAvailableQuantity',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 110
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '最终缺料数量',
|
|
|
+ prop: 'finalShortageQuantity',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ slot: 'finalStateText',
|
|
|
+ prop: 'finalStateText',
|
|
|
+ label: '最终状态',
|
|
|
+ align: 'center',
|
|
|
+ minWidth: 80
|
|
|
+ }
|
|
|
+ // {
|
|
|
+ // columnKey: 'action',
|
|
|
+ // label: '操作',
|
|
|
+ // width: 120,
|
|
|
+ // align: 'center',
|
|
|
+ // resizable: false,
|
|
|
+ // fixed: 'right',
|
|
|
+ // slot: 'action'
|
|
|
+ // }
|
|
|
+ ],
|
|
|
+ ids: [],
|
|
|
+ leftShow: false,
|
|
|
+ leftWidth: '0%',
|
|
|
+ rightWidth: '100%',
|
|
|
+ cardList: [],
|
|
|
+ treeProps: {
|
|
|
+ label: 'productName',
|
|
|
+ children: 'children'
|
|
|
+ },
|
|
|
+ dataObj: {
|
|
|
+ code: '',
|
|
|
+ productCode: '',
|
|
|
+ productName: '',
|
|
|
+ totalCount: '',
|
|
|
+ specification: '',
|
|
|
+ model: ''
|
|
|
+ },
|
|
|
+ };
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ leftShow(newVal, oldVal) {
|
|
|
+ if (newVal) {
|
|
|
+ this.leftWidth = '250px';
|
|
|
+ this.rightWidth = 'calc(100% - 260px)';
|
|
|
+ } else {
|
|
|
+ this.leftWidth = '0';
|
|
|
+ this.rightWidth = '100%';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ reload(where) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.table.reload({ page: 1, where });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 定额数量
|
|
|
+ stockDetail(row) {
|
|
|
+ this.$refs.stockDetailDialog.open({ bomCode: row.code });
|
|
|
+ },
|
|
|
+ // 在途
|
|
|
+ currentDetail(row) {
|
|
|
+ this.$refs.currentDetailDialog.open({ bomCode: row.code });
|
|
|
+ },
|
|
|
+ open(dataList) {
|
|
|
+ this.visible = true;
|
|
|
+ this.cardList = dataList;
|
|
|
+
|
|
|
+ if (dataList.length === 1) {
|
|
|
+ this.leftShow = false;
|
|
|
+ } else {
|
|
|
+ this.leftShow = true;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.treeRef.setCurrentKey(dataList[0].id);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ this.handleNodeClick(this.cardList[0]);
|
|
|
+ },
|
|
|
+ cancel() {
|
|
|
+ this.clearData();
|
|
|
+ this.visible = false;
|
|
|
+ },
|
|
|
+
|
|
|
+ confirm() {
|
|
|
+ this.visible = false;
|
|
|
+ },
|
|
|
+
|
|
|
+ handleNodeClick(data) {
|
|
|
+ this.clearData();
|
|
|
+ this.dataObj = data;
|
|
|
+ this.getBomData();
|
|
|
+ },
|
|
|
+ // 获取bom 数据
|
|
|
+ async getBomData() {
|
|
|
+ this.loading = true;
|
|
|
+ try {
|
|
|
+ const res = await findBomSalesorderCategoryId( this.dataObj.productId);
|
|
|
+ if (!res || res.length == 0) {
|
|
|
+ this.loading = false;
|
|
|
+ this.datasourceList = [];
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let obj = {};
|
|
|
+ let bomMap = {
|
|
|
+ 1: 'PBOM',
|
|
|
+ 2: 'MBOM',
|
|
|
+ 3: 'ABOM',
|
|
|
+ 4: 'EBOM'
|
|
|
+ };
|
|
|
+ res.map((el) => {
|
|
|
+ el.bomName = bomMap[el.bomType];
|
|
|
+ let OBMINFO = {
|
|
|
+ bomId: el.bomId,
|
|
|
+ bomType: el.type,
|
|
|
+ versions: `V${el.versions}.0`,
|
|
|
+ code: el.code
|
|
|
+ };
|
|
|
+ if (obj[el.bomType]) {
|
|
|
+ obj[el.bomType].bomList.unshift(OBMINFO);
|
|
|
+ } else {
|
|
|
+ obj[el.bomType] = { ...el, bomList: [OBMINFO] };
|
|
|
+ }
|
|
|
+ });
|
|
|
+ let list = Object.values(obj);
|
|
|
+ this.bomListType = list;
|
|
|
+ await this.bomTypeChange(list[0].id);
|
|
|
+ this.loading = false;
|
|
|
+ } catch (err) {
|
|
|
+ this.$message.error(err.message);
|
|
|
+ this.loading = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 选择BOM类型
|
|
|
+ async bomTypeChange(e) {
|
|
|
+ this.formInline.bomType = e;
|
|
|
+ let data = this.bomListType.find((el) => el.id === e);
|
|
|
+ if (!data) return;
|
|
|
+ this.bomListV = data.bomList;
|
|
|
+ await this.bomVChange(data.bomList[0].bomId);
|
|
|
+ },
|
|
|
+ // 选择BOM版本
|
|
|
+ async bomVChange(e) {
|
|
|
+ this.formInline.bomId = e;
|
|
|
+ let data = this.bomListV.find((el) => el.bomId === e);
|
|
|
+ if (!data) return;
|
|
|
+ await this.getMaterialData(data);
|
|
|
+ },
|
|
|
+ // 获取物料数据信息
|
|
|
+ async getMaterialData(data) {
|
|
|
+ const result = await getMaterialInfo({
|
|
|
+ categoryId: this.dataObj.productId,
|
|
|
+ bomVersionId: data.bomId,
|
|
|
+ requiredFormingNum: this.dataObj.totalCount
|
|
|
+ });
|
|
|
+ result.map((item) => {
|
|
|
+ item.batchNo = this.dataObj.batchNo;
|
|
|
+ item.productCode = this.dataObj.productCode;
|
|
|
+ item.finalState =
|
|
|
+ item.finalStateText == '齐套'
|
|
|
+ ? 1
|
|
|
+ : item.finalStateText == '缺料'
|
|
|
+ ? 2
|
|
|
+ : '';
|
|
|
+ });
|
|
|
+ this.datasourceAllList = result;
|
|
|
+ this.finalChange(0);
|
|
|
+ },
|
|
|
+ // 选择状态
|
|
|
+ finalChange(e) {
|
|
|
+ if (e === 0 || !e) {
|
|
|
+ this.datasourceList = this.datasourceAllList;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.datasourceList = this.datasourceAllList.filter(
|
|
|
+ (item) => item.finalState === e
|
|
|
+ );
|
|
|
+ },
|
|
|
+ clearData() {
|
|
|
+ this.formInline = {
|
|
|
+ finalState: 0
|
|
|
+ };
|
|
|
+ this.bomListV = [];
|
|
|
+ this.bomListType = [];
|
|
|
+ this.datasourceList = [];
|
|
|
+ this.datasourceAllList = [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .mt20 {
|
|
|
+ margin-top: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-form-item {
|
|
|
+ margin-bottom: 0 !important;
|
|
|
+ }
|
|
|
+ .planInfo {
|
|
|
+ display: flex;
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-wrapper {
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
+
|
|
|
+ .order_form {
|
|
|
+ .el-col {
|
|
|
+ margin-bottom: 16px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .statusRed {
|
|
|
+ color: red;
|
|
|
+ }
|
|
|
+
|
|
|
+ .statusGreen {
|
|
|
+ color: green;
|
|
|
+ }
|
|
|
+
|
|
|
+ .left_tree {
|
|
|
+ width: 250px;
|
|
|
+ max-height: 600px;
|
|
|
+ min-height: 300px;
|
|
|
+ overflow: auto;
|
|
|
+ border: 1px solid #ccc;
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+</style>
|